opensteer 0.8.18 → 0.9.1
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 +5 -5
- package/dist/chunk-4LP7QP2O.js +4336 -0
- package/dist/chunk-4LP7QP2O.js.map +1 -0
- package/dist/{chunk-GQ3PGLYQ.js → chunk-6PGXWW3X.js} +5142 -9634
- package/dist/chunk-6PGXWW3X.js.map +1 -0
- package/dist/chunk-BMPUL66S.js +1170 -0
- package/dist/chunk-BMPUL66S.js.map +1 -0
- package/dist/{chunk-T6TG4WO2.js → chunk-L4FWHBQJ.js} +4 -3
- package/dist/chunk-L4FWHBQJ.js.map +1 -0
- package/dist/chunk-Z53HNZ7Z.js +1800 -0
- package/dist/chunk-Z53HNZ7Z.js.map +1 -0
- package/dist/cli/bin.cjs +3533 -499
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +130 -11
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +1382 -487
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -27
- package/dist/index.d.ts +20 -27
- package/dist/index.js +4 -2
- package/dist/local-view/public/assets/app.css +770 -0
- package/dist/local-view/public/assets/app.js +2053 -0
- package/dist/local-view/public/index.html +235 -0
- package/dist/local-view/serve-entry.cjs +7436 -0
- package/dist/local-view/serve-entry.cjs.map +1 -0
- package/dist/local-view/serve-entry.d.cts +1 -0
- package/dist/local-view/serve-entry.d.ts +1 -0
- package/dist/local-view/serve-entry.js +23 -0
- package/dist/local-view/serve-entry.js.map +1 -0
- package/dist/opensteer-KZCRP425.js +6 -0
- package/dist/{opensteer-XMCWYUH3.js.map → opensteer-KZCRP425.js.map} +1 -1
- package/dist/session-control-VGBFOH3Y.js +39 -0
- package/dist/session-control-VGBFOH3Y.js.map +1 -0
- package/package.json +8 -8
- package/skills/README.md +12 -6
- package/skills/opensteer/SKILL.md +275 -217
- package/skills/recorder/SKILL.md +1 -1
- package/dist/chunk-GQ3PGLYQ.js.map +0 -1
- package/dist/chunk-T6TG4WO2.js.map +0 -1
- package/dist/opensteer-XMCWYUH3.js +0 -4
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var path10 = 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 module$1 = require('module');
|
|
13
14
|
var zlib = require('zlib');
|
|
14
15
|
var async_hooks = require('async_hooks');
|
|
15
16
|
var sharp = require('sharp');
|
|
@@ -18,6 +19,7 @@ var prettier = require('prettier');
|
|
|
18
19
|
var vm = require('vm');
|
|
19
20
|
var WebSocket2 = require('ws');
|
|
20
21
|
|
|
22
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
21
23
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
22
24
|
|
|
23
25
|
function _interopNamespace(e) {
|
|
@@ -38,7 +40,7 @@ function _interopNamespace(e) {
|
|
|
38
40
|
return Object.freeze(n);
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
var
|
|
43
|
+
var path10__default = /*#__PURE__*/_interopDefault(path10);
|
|
42
44
|
var sharp__default = /*#__PURE__*/_interopDefault(sharp);
|
|
43
45
|
var cheerio__namespace = /*#__PURE__*/_interopNamespace(cheerio);
|
|
44
46
|
var prettier__namespace = /*#__PURE__*/_interopNamespace(prettier);
|
|
@@ -60,30 +62,30 @@ function isPlainObject(value) {
|
|
|
60
62
|
const prototype = Object.getPrototypeOf(value);
|
|
61
63
|
return prototype === Object.prototype || prototype === null;
|
|
62
64
|
}
|
|
63
|
-
function canonicalizeJsonValue(value,
|
|
65
|
+
function canonicalizeJsonValue(value, path18) {
|
|
64
66
|
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
65
67
|
return value;
|
|
66
68
|
}
|
|
67
69
|
if (typeof value === "number") {
|
|
68
70
|
if (!Number.isFinite(value)) {
|
|
69
|
-
throw new TypeError(`${
|
|
71
|
+
throw new TypeError(`${path18} must be a finite JSON number`);
|
|
70
72
|
}
|
|
71
73
|
return value;
|
|
72
74
|
}
|
|
73
75
|
if (Array.isArray(value)) {
|
|
74
|
-
return value.map((entry, index) => canonicalizeJsonValue(entry, `${
|
|
76
|
+
return value.map((entry, index) => canonicalizeJsonValue(entry, `${path18}[${index}]`));
|
|
75
77
|
}
|
|
76
78
|
if (!isPlainObject(value)) {
|
|
77
|
-
throw new TypeError(`${
|
|
79
|
+
throw new TypeError(`${path18} must be a plain JSON object`);
|
|
78
80
|
}
|
|
79
81
|
const sorted = Object.keys(value).sort((left, right) => left.localeCompare(right));
|
|
80
82
|
const result = {};
|
|
81
83
|
for (const key of sorted) {
|
|
82
84
|
const entry = value[key];
|
|
83
85
|
if (entry === void 0) {
|
|
84
|
-
throw new TypeError(`${
|
|
86
|
+
throw new TypeError(`${path18}.${key} must not be undefined`);
|
|
85
87
|
}
|
|
86
|
-
result[key] = canonicalizeJsonValue(entry, `${
|
|
88
|
+
result[key] = canonicalizeJsonValue(entry, `${path18}.${key}`);
|
|
87
89
|
}
|
|
88
90
|
return result;
|
|
89
91
|
}
|
|
@@ -120,7 +122,7 @@ function joinStoragePath(...segments) {
|
|
|
120
122
|
return segments.join("/");
|
|
121
123
|
}
|
|
122
124
|
function resolveStoragePath(rootPath, relativePath) {
|
|
123
|
-
if (
|
|
125
|
+
if (path10__default.default.isAbsolute(relativePath)) {
|
|
124
126
|
throw new TypeError(`storage path ${relativePath} must be relative`);
|
|
125
127
|
}
|
|
126
128
|
const segments = relativePath.split("/");
|
|
@@ -132,7 +134,7 @@ function resolveStoragePath(rootPath, relativePath) {
|
|
|
132
134
|
throw new TypeError(`storage path ${relativePath} must not contain path traversal`);
|
|
133
135
|
}
|
|
134
136
|
}
|
|
135
|
-
return
|
|
137
|
+
return path10__default.default.join(rootPath, ...segments);
|
|
136
138
|
}
|
|
137
139
|
async function ensureDirectory(directoryPath) {
|
|
138
140
|
await promises.mkdir(directoryPath, { recursive: true });
|
|
@@ -152,7 +154,7 @@ async function writeJsonFileAtomic(filePath, value) {
|
|
|
152
154
|
await writeTextFileAtomic(filePath, stableJsonString(value));
|
|
153
155
|
}
|
|
154
156
|
async function writeTextFileAtomic(filePath, value) {
|
|
155
|
-
await ensureDirectory(
|
|
157
|
+
await ensureDirectory(path10__default.default.dirname(filePath));
|
|
156
158
|
const temporaryPath = `${filePath}.${crypto.randomUUID()}.tmp`;
|
|
157
159
|
await promises.writeFile(temporaryPath, value, "utf8");
|
|
158
160
|
await promises.rename(temporaryPath, filePath);
|
|
@@ -161,7 +163,7 @@ async function writeJsonFileExclusive(filePath, value) {
|
|
|
161
163
|
await writeTextFileExclusive(filePath, stableJsonString(value));
|
|
162
164
|
}
|
|
163
165
|
async function writeTextFileExclusive(filePath, value) {
|
|
164
|
-
await ensureDirectory(
|
|
166
|
+
await ensureDirectory(path10__default.default.dirname(filePath));
|
|
165
167
|
const handle = await promises.open(filePath, "wx");
|
|
166
168
|
try {
|
|
167
169
|
await handle.writeFile(value, "utf8");
|
|
@@ -170,7 +172,7 @@ async function writeTextFileExclusive(filePath, value) {
|
|
|
170
172
|
}
|
|
171
173
|
}
|
|
172
174
|
async function writeBufferIfMissing(filePath, value) {
|
|
173
|
-
await ensureDirectory(
|
|
175
|
+
await ensureDirectory(path10__default.default.dirname(filePath));
|
|
174
176
|
try {
|
|
175
177
|
const handle = await promises.open(filePath, "wx");
|
|
176
178
|
try {
|
|
@@ -204,7 +206,7 @@ function isAlreadyExistsError(error) {
|
|
|
204
206
|
return error?.code === "EEXIST";
|
|
205
207
|
}
|
|
206
208
|
async function withFilesystemLock(lockPath, task) {
|
|
207
|
-
await ensureDirectory(
|
|
209
|
+
await ensureDirectory(path10__default.default.dirname(lockPath));
|
|
208
210
|
let attempt = 0;
|
|
209
211
|
while (true) {
|
|
210
212
|
try {
|
|
@@ -259,8 +261,8 @@ async function readStructuredPayload(objectPath) {
|
|
|
259
261
|
var FilesystemArtifactStore = class {
|
|
260
262
|
constructor(rootPath) {
|
|
261
263
|
this.rootPath = rootPath;
|
|
262
|
-
this.manifestsDirectory =
|
|
263
|
-
this.objectsDirectory =
|
|
264
|
+
this.manifestsDirectory = path10__default.default.join(this.rootPath, "artifacts", "manifests");
|
|
265
|
+
this.objectsDirectory = path10__default.default.join(this.rootPath, "artifacts", "objects", "sha256");
|
|
264
266
|
}
|
|
265
267
|
manifestsDirectory;
|
|
266
268
|
objectsDirectory;
|
|
@@ -485,7 +487,7 @@ var FilesystemArtifactStore = class {
|
|
|
485
487
|
}
|
|
486
488
|
}
|
|
487
489
|
manifestPath(artifactId) {
|
|
488
|
-
return
|
|
490
|
+
return path10__default.default.join(this.manifestsDirectory, `${encodePathSegment(artifactId)}.json`);
|
|
489
491
|
}
|
|
490
492
|
};
|
|
491
493
|
function createArtifactStore(rootPath) {
|
|
@@ -580,31 +582,31 @@ function oneOfSchema(members, options = {}) {
|
|
|
580
582
|
}
|
|
581
583
|
|
|
582
584
|
// ../protocol/src/validation.ts
|
|
583
|
-
function validateJsonSchema(schema, value,
|
|
584
|
-
return validateSchemaNode(schema, value,
|
|
585
|
+
function validateJsonSchema(schema, value, path18 = "$") {
|
|
586
|
+
return validateSchemaNode(schema, value, path18);
|
|
585
587
|
}
|
|
586
|
-
function validateSchemaNode(schema, value,
|
|
588
|
+
function validateSchemaNode(schema, value, path18) {
|
|
587
589
|
const issues = [];
|
|
588
590
|
if ("const" in schema && !isJsonValueEqual(schema.const, value)) {
|
|
589
591
|
issues.push({
|
|
590
|
-
path:
|
|
592
|
+
path: path18,
|
|
591
593
|
message: `must equal ${JSON.stringify(schema.const)}`
|
|
592
594
|
});
|
|
593
595
|
return issues;
|
|
594
596
|
}
|
|
595
597
|
if (schema.enum !== void 0 && !schema.enum.some((candidate) => isJsonValueEqual(candidate, value))) {
|
|
596
598
|
issues.push({
|
|
597
|
-
path:
|
|
599
|
+
path: path18,
|
|
598
600
|
message: `must be one of ${schema.enum.map((candidate) => JSON.stringify(candidate)).join(", ")}`
|
|
599
601
|
});
|
|
600
602
|
return issues;
|
|
601
603
|
}
|
|
602
604
|
if (schema.oneOf !== void 0) {
|
|
603
|
-
const branchIssues = schema.oneOf.map((member) => validateSchemaNode(member, value,
|
|
605
|
+
const branchIssues = schema.oneOf.map((member) => validateSchemaNode(member, value, path18));
|
|
604
606
|
const validBranches = branchIssues.filter((current) => current.length === 0).length;
|
|
605
607
|
if (validBranches !== 1) {
|
|
606
608
|
issues.push({
|
|
607
|
-
path:
|
|
609
|
+
path: path18,
|
|
608
610
|
message: validBranches === 0 ? "must match exactly one supported shape" : "matches multiple supported shapes"
|
|
609
611
|
});
|
|
610
612
|
return issues;
|
|
@@ -612,11 +614,11 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
612
614
|
}
|
|
613
615
|
if (schema.anyOf !== void 0) {
|
|
614
616
|
const hasMatch = schema.anyOf.some(
|
|
615
|
-
(member) => validateSchemaNode(member, value,
|
|
617
|
+
(member) => validateSchemaNode(member, value, path18).length === 0
|
|
616
618
|
);
|
|
617
619
|
if (!hasMatch) {
|
|
618
620
|
issues.push({
|
|
619
|
-
path:
|
|
621
|
+
path: path18,
|
|
620
622
|
message: "must match at least one supported shape"
|
|
621
623
|
});
|
|
622
624
|
return issues;
|
|
@@ -624,7 +626,7 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
624
626
|
}
|
|
625
627
|
if (schema.allOf !== void 0) {
|
|
626
628
|
for (const member of schema.allOf) {
|
|
627
|
-
issues.push(...validateSchemaNode(member, value,
|
|
629
|
+
issues.push(...validateSchemaNode(member, value, path18));
|
|
628
630
|
}
|
|
629
631
|
if (issues.length > 0) {
|
|
630
632
|
return issues;
|
|
@@ -632,7 +634,7 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
632
634
|
}
|
|
633
635
|
if (schema.type !== void 0 && !matchesSchemaType(schema.type, value)) {
|
|
634
636
|
issues.push({
|
|
635
|
-
path:
|
|
637
|
+
path: path18,
|
|
636
638
|
message: `must be ${describeSchemaType(schema.type)}`
|
|
637
639
|
});
|
|
638
640
|
return issues;
|
|
@@ -640,19 +642,19 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
640
642
|
if (typeof value === "string") {
|
|
641
643
|
if (schema.minLength !== void 0 && value.length < schema.minLength) {
|
|
642
644
|
issues.push({
|
|
643
|
-
path:
|
|
645
|
+
path: path18,
|
|
644
646
|
message: `must have length >= ${String(schema.minLength)}`
|
|
645
647
|
});
|
|
646
648
|
}
|
|
647
649
|
if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
|
|
648
650
|
issues.push({
|
|
649
|
-
path:
|
|
651
|
+
path: path18,
|
|
650
652
|
message: `must have length <= ${String(schema.maxLength)}`
|
|
651
653
|
});
|
|
652
654
|
}
|
|
653
655
|
if (schema.pattern !== void 0 && !new RegExp(schema.pattern).test(value)) {
|
|
654
656
|
issues.push({
|
|
655
|
-
path:
|
|
657
|
+
path: path18,
|
|
656
658
|
message: `must match pattern ${schema.pattern}`
|
|
657
659
|
});
|
|
658
660
|
}
|
|
@@ -661,25 +663,25 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
661
663
|
if (typeof value === "number") {
|
|
662
664
|
if (schema.minimum !== void 0 && value < schema.minimum) {
|
|
663
665
|
issues.push({
|
|
664
|
-
path:
|
|
666
|
+
path: path18,
|
|
665
667
|
message: `must be >= ${String(schema.minimum)}`
|
|
666
668
|
});
|
|
667
669
|
}
|
|
668
670
|
if (schema.maximum !== void 0 && value > schema.maximum) {
|
|
669
671
|
issues.push({
|
|
670
|
-
path:
|
|
672
|
+
path: path18,
|
|
671
673
|
message: `must be <= ${String(schema.maximum)}`
|
|
672
674
|
});
|
|
673
675
|
}
|
|
674
676
|
if (schema.exclusiveMinimum !== void 0 && value <= schema.exclusiveMinimum) {
|
|
675
677
|
issues.push({
|
|
676
|
-
path:
|
|
678
|
+
path: path18,
|
|
677
679
|
message: `must be > ${String(schema.exclusiveMinimum)}`
|
|
678
680
|
});
|
|
679
681
|
}
|
|
680
682
|
if (schema.exclusiveMaximum !== void 0 && value >= schema.exclusiveMaximum) {
|
|
681
683
|
issues.push({
|
|
682
|
-
path:
|
|
684
|
+
path: path18,
|
|
683
685
|
message: `must be < ${String(schema.exclusiveMaximum)}`
|
|
684
686
|
});
|
|
685
687
|
}
|
|
@@ -688,13 +690,13 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
688
690
|
if (Array.isArray(value)) {
|
|
689
691
|
if (schema.minItems !== void 0 && value.length < schema.minItems) {
|
|
690
692
|
issues.push({
|
|
691
|
-
path:
|
|
693
|
+
path: path18,
|
|
692
694
|
message: `must have at least ${String(schema.minItems)} items`
|
|
693
695
|
});
|
|
694
696
|
}
|
|
695
697
|
if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
|
|
696
698
|
issues.push({
|
|
697
|
-
path:
|
|
699
|
+
path: path18,
|
|
698
700
|
message: `must have at most ${String(schema.maxItems)} items`
|
|
699
701
|
});
|
|
700
702
|
}
|
|
@@ -704,7 +706,7 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
704
706
|
const key = JSON.stringify(item);
|
|
705
707
|
if (seen.has(key)) {
|
|
706
708
|
issues.push({
|
|
707
|
-
path:
|
|
709
|
+
path: path18,
|
|
708
710
|
message: "must not contain duplicate items"
|
|
709
711
|
});
|
|
710
712
|
break;
|
|
@@ -714,7 +716,7 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
714
716
|
}
|
|
715
717
|
if (schema.items !== void 0) {
|
|
716
718
|
for (let index = 0; index < value.length; index += 1) {
|
|
717
|
-
issues.push(...validateSchemaNode(schema.items, value[index], `${
|
|
719
|
+
issues.push(...validateSchemaNode(schema.items, value[index], `${path18}[${String(index)}]`));
|
|
718
720
|
}
|
|
719
721
|
}
|
|
720
722
|
return issues;
|
|
@@ -724,7 +726,7 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
724
726
|
for (const requiredKey of schema.required ?? []) {
|
|
725
727
|
if (!(requiredKey in value)) {
|
|
726
728
|
issues.push({
|
|
727
|
-
path: joinObjectPath(
|
|
729
|
+
path: joinObjectPath(path18, requiredKey),
|
|
728
730
|
message: "is required"
|
|
729
731
|
});
|
|
730
732
|
}
|
|
@@ -733,13 +735,13 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
733
735
|
const propertySchema = properties[key];
|
|
734
736
|
if (propertySchema !== void 0) {
|
|
735
737
|
issues.push(
|
|
736
|
-
...validateSchemaNode(propertySchema, propertyValue, joinObjectPath(
|
|
738
|
+
...validateSchemaNode(propertySchema, propertyValue, joinObjectPath(path18, key))
|
|
737
739
|
);
|
|
738
740
|
continue;
|
|
739
741
|
}
|
|
740
742
|
if (schema.additionalProperties === false) {
|
|
741
743
|
issues.push({
|
|
742
|
-
path: joinObjectPath(
|
|
744
|
+
path: joinObjectPath(path18, key),
|
|
743
745
|
message: "is not allowed"
|
|
744
746
|
});
|
|
745
747
|
continue;
|
|
@@ -749,7 +751,7 @@ function validateSchemaNode(schema, value, path15) {
|
|
|
749
751
|
...validateSchemaNode(
|
|
750
752
|
schema.additionalProperties,
|
|
751
753
|
propertyValue,
|
|
752
|
-
joinObjectPath(
|
|
754
|
+
joinObjectPath(path18, key)
|
|
753
755
|
)
|
|
754
756
|
);
|
|
755
757
|
}
|
|
@@ -993,8 +995,8 @@ function matchesNetworkRecordFilters(record, filters) {
|
|
|
993
995
|
}
|
|
994
996
|
}
|
|
995
997
|
if (filters.path !== void 0) {
|
|
996
|
-
const
|
|
997
|
-
if (!includesCaseInsensitive(
|
|
998
|
+
const path18 = getParsedUrl().pathname;
|
|
999
|
+
if (!includesCaseInsensitive(path18, filters.path)) {
|
|
998
1000
|
return false;
|
|
999
1001
|
}
|
|
1000
1002
|
}
|
|
@@ -2507,7 +2509,7 @@ objectSchema(
|
|
|
2507
2509
|
}
|
|
2508
2510
|
);
|
|
2509
2511
|
var opensteerSessionFetchTransportSchema = enumSchema(
|
|
2510
|
-
["auto", "direct", "matched-tls", "page"],
|
|
2512
|
+
["auto", "direct", "matched-tls", "context", "page"],
|
|
2511
2513
|
{
|
|
2512
2514
|
title: "OpensteerSessionFetchTransport"
|
|
2513
2515
|
}
|
|
@@ -6860,6 +6862,7 @@ var opensteerSemanticOperationSpecificationsBase = [
|
|
|
6860
6862
|
case "direct":
|
|
6861
6863
|
return [];
|
|
6862
6864
|
case "matched-tls":
|
|
6865
|
+
case "context":
|
|
6863
6866
|
return ["inspect.cookies"];
|
|
6864
6867
|
case "page":
|
|
6865
6868
|
return ["pages.manage"];
|
|
@@ -6991,9 +6994,9 @@ function compareByCreatedAtAndId(left, right) {
|
|
|
6991
6994
|
var FilesystemRegistryStore = class {
|
|
6992
6995
|
constructor(rootPath, registryRelativePath) {
|
|
6993
6996
|
this.registryRelativePath = registryRelativePath;
|
|
6994
|
-
const basePath =
|
|
6995
|
-
this.recordsDirectory =
|
|
6996
|
-
this.indexesDirectory =
|
|
6997
|
+
const basePath = path10__default.default.join(rootPath, ...registryRelativePath);
|
|
6998
|
+
this.recordsDirectory = path10__default.default.join(basePath, "records");
|
|
6999
|
+
this.indexesDirectory = path10__default.default.join(basePath, "indexes", "by-key");
|
|
6997
7000
|
}
|
|
6998
7001
|
recordsDirectory;
|
|
6999
7002
|
indexesDirectory;
|
|
@@ -7062,7 +7065,7 @@ var FilesystemRegistryStore = class {
|
|
|
7062
7065
|
async readRecordsFromDirectory() {
|
|
7063
7066
|
const files = await listJsonFiles(this.recordsDirectory);
|
|
7064
7067
|
const records = await Promise.all(
|
|
7065
|
-
files.map((fileName) => readJsonFile(
|
|
7068
|
+
files.map((fileName) => readJsonFile(path10__default.default.join(this.recordsDirectory, fileName)))
|
|
7066
7069
|
);
|
|
7067
7070
|
records.sort(compareByCreatedAtAndId);
|
|
7068
7071
|
return records;
|
|
@@ -7094,17 +7097,17 @@ var FilesystemRegistryStore = class {
|
|
|
7094
7097
|
return record;
|
|
7095
7098
|
}
|
|
7096
7099
|
recordPath(id) {
|
|
7097
|
-
return
|
|
7100
|
+
return path10__default.default.join(this.recordsDirectory, `${encodePathSegment(id)}.json`);
|
|
7098
7101
|
}
|
|
7099
7102
|
indexPath(key, version) {
|
|
7100
|
-
return
|
|
7103
|
+
return path10__default.default.join(
|
|
7101
7104
|
this.indexesDirectory,
|
|
7102
7105
|
encodePathSegment(key),
|
|
7103
7106
|
`${encodePathSegment(version)}.json`
|
|
7104
7107
|
);
|
|
7105
7108
|
}
|
|
7106
7109
|
writeLockPath() {
|
|
7107
|
-
return
|
|
7110
|
+
return path10__default.default.join(path10__default.default.dirname(this.recordsDirectory), ".write.lock");
|
|
7108
7111
|
}
|
|
7109
7112
|
};
|
|
7110
7113
|
var FilesystemDescriptorRegistry = class extends FilesystemRegistryStore {
|
|
@@ -7474,20 +7477,13 @@ var SqliteSavedNetworkStore = class {
|
|
|
7474
7477
|
directoryInitialization;
|
|
7475
7478
|
databaseInitialization;
|
|
7476
7479
|
constructor(rootPath) {
|
|
7477
|
-
this.databasePath =
|
|
7480
|
+
this.databasePath = path10__default.default.join(rootPath, "registry", "saved-network.sqlite");
|
|
7478
7481
|
}
|
|
7479
7482
|
async initialize() {
|
|
7480
7483
|
await this.ensureDatabaseDirectory();
|
|
7481
7484
|
}
|
|
7482
7485
|
async save(records, options) {
|
|
7483
7486
|
const database = await this.requireDatabase();
|
|
7484
|
-
const readExisting = database.prepare(`
|
|
7485
|
-
SELECT record_id
|
|
7486
|
-
FROM saved_network_records
|
|
7487
|
-
WHERE session_ref = @session_ref
|
|
7488
|
-
AND page_ref_key = @page_ref_key
|
|
7489
|
-
AND request_id = @request_id
|
|
7490
|
-
`);
|
|
7491
7487
|
const upsertRecord = database.prepare(buildSavedNetworkUpsertSql(options.bodyWriteMode));
|
|
7492
7488
|
const insertTag = database.prepare(`
|
|
7493
7489
|
INSERT OR IGNORE INTO saved_network_tags (record_id, tag)
|
|
@@ -7498,14 +7494,8 @@ var SqliteSavedNetworkStore = class {
|
|
|
7498
7494
|
for (const entry of records) {
|
|
7499
7495
|
const url = new URL(entry.record.url);
|
|
7500
7496
|
const pageRefKey = entry.record.pageRef ?? "";
|
|
7501
|
-
const existing = readExisting.get({
|
|
7502
|
-
session_ref: entry.record.sessionRef,
|
|
7503
|
-
page_ref_key: pageRefKey,
|
|
7504
|
-
request_id: entry.record.requestId
|
|
7505
|
-
}) ?? void 0;
|
|
7506
|
-
const recordId = existing?.record_id ?? entry.recordId;
|
|
7507
7497
|
upsertRecord.run({
|
|
7508
|
-
record_id: recordId,
|
|
7498
|
+
record_id: entry.recordId,
|
|
7509
7499
|
request_id: entry.record.requestId,
|
|
7510
7500
|
session_ref: entry.record.sessionRef,
|
|
7511
7501
|
page_ref: entry.record.pageRef ?? null,
|
|
@@ -7550,7 +7540,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7550
7540
|
}
|
|
7551
7541
|
for (const currentTag of tags) {
|
|
7552
7542
|
const result = insertTag.run({
|
|
7553
|
-
record_id: recordId,
|
|
7543
|
+
record_id: entry.recordId,
|
|
7554
7544
|
tag: currentTag
|
|
7555
7545
|
});
|
|
7556
7546
|
savedCount += result.changes ?? 0;
|
|
@@ -7653,6 +7643,49 @@ var SqliteSavedNetworkStore = class {
|
|
|
7653
7643
|
return cleared;
|
|
7654
7644
|
});
|
|
7655
7645
|
}
|
|
7646
|
+
async *iterateBatches(options = {}) {
|
|
7647
|
+
const database = await this.requireDatabase();
|
|
7648
|
+
const batchSize = Math.max(1, Math.min(options.batchSize ?? 500, 1e3));
|
|
7649
|
+
let cursor;
|
|
7650
|
+
while (true) {
|
|
7651
|
+
const rows = database.prepare(
|
|
7652
|
+
`
|
|
7653
|
+
SELECT
|
|
7654
|
+
r.*,
|
|
7655
|
+
GROUP_CONCAT(t.tag, '${TAG_DELIMITER}') AS tags
|
|
7656
|
+
FROM saved_network_records r
|
|
7657
|
+
LEFT JOIN saved_network_tags t
|
|
7658
|
+
ON t.record_id = r.record_id
|
|
7659
|
+
${cursor === void 0 ? "" : "WHERE r.saved_at > ? OR (r.saved_at = ? AND r.record_id > ?)"}
|
|
7660
|
+
GROUP BY r.record_id
|
|
7661
|
+
ORDER BY r.saved_at ASC, r.record_id ASC
|
|
7662
|
+
LIMIT ?
|
|
7663
|
+
`
|
|
7664
|
+
).all(
|
|
7665
|
+
...cursor === void 0 ? [] : [cursor.savedAt, cursor.savedAt, cursor.recordId],
|
|
7666
|
+
batchSize
|
|
7667
|
+
);
|
|
7668
|
+
if (rows.length === 0) {
|
|
7669
|
+
return;
|
|
7670
|
+
}
|
|
7671
|
+
yield rows.map((row) => inflateSavedNetworkRow(row, options.includeBodies ?? true));
|
|
7672
|
+
const lastRow = rows.at(-1);
|
|
7673
|
+
if (lastRow === void 0) {
|
|
7674
|
+
return;
|
|
7675
|
+
}
|
|
7676
|
+
cursor = {
|
|
7677
|
+
savedAt: lastRow.saved_at,
|
|
7678
|
+
recordId: lastRow.record_id
|
|
7679
|
+
};
|
|
7680
|
+
}
|
|
7681
|
+
}
|
|
7682
|
+
close() {
|
|
7683
|
+
if (this.database !== void 0) {
|
|
7684
|
+
closeSqliteDatabase(this.database);
|
|
7685
|
+
this.database = void 0;
|
|
7686
|
+
this.databaseInitialization = void 0;
|
|
7687
|
+
}
|
|
7688
|
+
}
|
|
7656
7689
|
async requireDatabase() {
|
|
7657
7690
|
if (this.database) {
|
|
7658
7691
|
return this.database;
|
|
@@ -7684,7 +7717,7 @@ var SqliteSavedNetworkStore = class {
|
|
|
7684
7717
|
}
|
|
7685
7718
|
}
|
|
7686
7719
|
async ensureDatabaseDirectory() {
|
|
7687
|
-
this.directoryInitialization ??= ensureDirectory(
|
|
7720
|
+
this.directoryInitialization ??= ensureDirectory(path10__default.default.dirname(this.databasePath)).catch(
|
|
7688
7721
|
(error) => {
|
|
7689
7722
|
this.directoryInitialization = void 0;
|
|
7690
7723
|
throw error;
|
|
@@ -7737,15 +7770,6 @@ var SqliteSavedNetworkStore = class {
|
|
|
7737
7770
|
saved_at INTEGER NOT NULL
|
|
7738
7771
|
);
|
|
7739
7772
|
|
|
7740
|
-
CREATE UNIQUE INDEX IF NOT EXISTS saved_network_records_scope_request
|
|
7741
|
-
ON saved_network_records (session_ref, page_ref_key, request_id);
|
|
7742
|
-
|
|
7743
|
-
CREATE INDEX IF NOT EXISTS saved_network_records_saved_at
|
|
7744
|
-
ON saved_network_records (saved_at DESC);
|
|
7745
|
-
|
|
7746
|
-
CREATE INDEX IF NOT EXISTS saved_network_records_capture
|
|
7747
|
-
ON saved_network_records (capture);
|
|
7748
|
-
|
|
7749
7773
|
CREATE TABLE IF NOT EXISTS saved_network_tags (
|
|
7750
7774
|
record_id TEXT NOT NULL REFERENCES saved_network_records(record_id) ON DELETE CASCADE,
|
|
7751
7775
|
tag TEXT NOT NULL,
|
|
@@ -7755,6 +7779,19 @@ var SqliteSavedNetworkStore = class {
|
|
|
7755
7779
|
CREATE INDEX IF NOT EXISTS saved_network_tags_tag
|
|
7756
7780
|
ON saved_network_tags (tag);
|
|
7757
7781
|
`);
|
|
7782
|
+
database.exec(`DROP INDEX IF EXISTS saved_network_records_scope_request`);
|
|
7783
|
+
database.exec(`
|
|
7784
|
+
CREATE INDEX IF NOT EXISTS saved_network_records_scope_request
|
|
7785
|
+
ON saved_network_records (session_ref, page_ref_key, request_id)
|
|
7786
|
+
`);
|
|
7787
|
+
database.exec(`
|
|
7788
|
+
CREATE INDEX IF NOT EXISTS saved_network_records_saved_at
|
|
7789
|
+
ON saved_network_records (saved_at DESC)
|
|
7790
|
+
`);
|
|
7791
|
+
database.exec(`
|
|
7792
|
+
CREATE INDEX IF NOT EXISTS saved_network_records_capture
|
|
7793
|
+
ON saved_network_records (capture)
|
|
7794
|
+
`);
|
|
7758
7795
|
this.ensureColumn(
|
|
7759
7796
|
database,
|
|
7760
7797
|
"saved_network_records",
|
|
@@ -8279,7 +8316,7 @@ var FilesystemObservationStoreImpl = class {
|
|
|
8279
8316
|
constructor(rootPath, artifacts) {
|
|
8280
8317
|
this.rootPath = rootPath;
|
|
8281
8318
|
this.artifacts = artifacts;
|
|
8282
|
-
this.sessionsDirectory =
|
|
8319
|
+
this.sessionsDirectory = path10__default.default.join(this.rootPath, "observations", "sessions");
|
|
8283
8320
|
}
|
|
8284
8321
|
sessionsDirectory;
|
|
8285
8322
|
redactors = /* @__PURE__ */ new Map();
|
|
@@ -8376,7 +8413,7 @@ var FilesystemObservationStoreImpl = class {
|
|
|
8376
8413
|
...raw.artifactIds === void 0 || raw.artifactIds.length === 0 ? {} : { artifactIds: [...raw.artifactIds] }
|
|
8377
8414
|
};
|
|
8378
8415
|
await writeJsonFileExclusive(
|
|
8379
|
-
|
|
8416
|
+
path10__default.default.join(this.sessionEventsDirectory(sessionId), eventFileName(sequence)),
|
|
8380
8417
|
event
|
|
8381
8418
|
);
|
|
8382
8419
|
updatedAt = Math.max(updatedAt, createdAt);
|
|
@@ -8434,7 +8471,7 @@ var FilesystemObservationStoreImpl = class {
|
|
|
8434
8471
|
}
|
|
8435
8472
|
const files = await listJsonFiles(directoryPath);
|
|
8436
8473
|
const events = await Promise.all(
|
|
8437
|
-
files.map((fileName) => readJsonFile(
|
|
8474
|
+
files.map((fileName) => readJsonFile(path10__default.default.join(directoryPath, fileName)))
|
|
8438
8475
|
);
|
|
8439
8476
|
const filtered = events.filter((event) => {
|
|
8440
8477
|
if (input.kind !== void 0 && event.kind !== input.kind) return false;
|
|
@@ -8461,7 +8498,7 @@ var FilesystemObservationStoreImpl = class {
|
|
|
8461
8498
|
const files = await listJsonFiles(directoryPath);
|
|
8462
8499
|
const artifacts = await Promise.all(
|
|
8463
8500
|
files.map(
|
|
8464
|
-
(fileName) => readJsonFile(
|
|
8501
|
+
(fileName) => readJsonFile(path10__default.default.join(directoryPath, fileName))
|
|
8465
8502
|
)
|
|
8466
8503
|
);
|
|
8467
8504
|
const filtered = artifacts.filter((artifact) => {
|
|
@@ -8524,25 +8561,25 @@ var FilesystemObservationStoreImpl = class {
|
|
|
8524
8561
|
)).filter((value) => value !== void 0);
|
|
8525
8562
|
}
|
|
8526
8563
|
sessionDirectory(sessionId) {
|
|
8527
|
-
return
|
|
8564
|
+
return path10__default.default.join(this.sessionsDirectory, encodePathSegment(sessionId));
|
|
8528
8565
|
}
|
|
8529
8566
|
sessionManifestPath(sessionId) {
|
|
8530
|
-
return
|
|
8567
|
+
return path10__default.default.join(this.sessionDirectory(sessionId), "session.json");
|
|
8531
8568
|
}
|
|
8532
8569
|
sessionEventsDirectory(sessionId) {
|
|
8533
|
-
return
|
|
8570
|
+
return path10__default.default.join(this.sessionDirectory(sessionId), "events");
|
|
8534
8571
|
}
|
|
8535
8572
|
sessionArtifactsDirectory(sessionId) {
|
|
8536
|
-
return
|
|
8573
|
+
return path10__default.default.join(this.sessionDirectory(sessionId), "artifacts");
|
|
8537
8574
|
}
|
|
8538
8575
|
sessionArtifactPath(sessionId, artifactId) {
|
|
8539
|
-
return
|
|
8576
|
+
return path10__default.default.join(
|
|
8540
8577
|
this.sessionArtifactsDirectory(sessionId),
|
|
8541
8578
|
`${encodePathSegment(artifactId)}.json`
|
|
8542
8579
|
);
|
|
8543
8580
|
}
|
|
8544
8581
|
sessionLockPath(sessionId) {
|
|
8545
|
-
return
|
|
8582
|
+
return path10__default.default.join(this.sessionDirectory(sessionId), ".lock");
|
|
8546
8583
|
}
|
|
8547
8584
|
async reconcileSessionManifest(sessionId) {
|
|
8548
8585
|
const session = await this.getSession(sessionId);
|
|
@@ -8570,14 +8607,14 @@ var FilesystemObservationStoreImpl = class {
|
|
|
8570
8607
|
Promise.all(
|
|
8571
8608
|
eventFiles.map(
|
|
8572
8609
|
(fileName) => readJsonFile(
|
|
8573
|
-
|
|
8610
|
+
path10__default.default.join(this.sessionEventsDirectory(sessionId), fileName)
|
|
8574
8611
|
)
|
|
8575
8612
|
)
|
|
8576
8613
|
),
|
|
8577
8614
|
Promise.all(
|
|
8578
8615
|
artifactFiles.map(
|
|
8579
8616
|
(fileName) => readJsonFile(
|
|
8580
|
-
|
|
8617
|
+
path10__default.default.join(this.sessionArtifactsDirectory(sessionId), fileName)
|
|
8581
8618
|
)
|
|
8582
8619
|
)
|
|
8583
8620
|
)
|
|
@@ -8630,7 +8667,7 @@ var FilesystemTraceStore = class {
|
|
|
8630
8667
|
constructor(rootPath, artifacts) {
|
|
8631
8668
|
this.rootPath = rootPath;
|
|
8632
8669
|
this.artifacts = artifacts;
|
|
8633
|
-
this.runsDirectory =
|
|
8670
|
+
this.runsDirectory = path10__default.default.join(this.rootPath, "traces", "runs");
|
|
8634
8671
|
}
|
|
8635
8672
|
runsDirectory;
|
|
8636
8673
|
async initialize() {
|
|
@@ -8707,7 +8744,7 @@ var FilesystemTraceStore = class {
|
|
|
8707
8744
|
...input.error === void 0 ? {} : { error: input.error }
|
|
8708
8745
|
};
|
|
8709
8746
|
await writeJsonFileExclusive(
|
|
8710
|
-
|
|
8747
|
+
path10__default.default.join(this.runEntriesDirectory(runId), sequenceFileName(sequence)),
|
|
8711
8748
|
entry
|
|
8712
8749
|
);
|
|
8713
8750
|
await writeJsonFileAtomic(this.runManifestPath(runId), {
|
|
@@ -8726,7 +8763,7 @@ var FilesystemTraceStore = class {
|
|
|
8726
8763
|
const files = await listJsonFiles(entriesDirectory);
|
|
8727
8764
|
return Promise.all(
|
|
8728
8765
|
files.map(
|
|
8729
|
-
(fileName) => readJsonFile(
|
|
8766
|
+
(fileName) => readJsonFile(path10__default.default.join(entriesDirectory, fileName))
|
|
8730
8767
|
)
|
|
8731
8768
|
);
|
|
8732
8769
|
}
|
|
@@ -8772,16 +8809,16 @@ var FilesystemTraceStore = class {
|
|
|
8772
8809
|
return { trace, artifacts };
|
|
8773
8810
|
}
|
|
8774
8811
|
runDirectory(runId) {
|
|
8775
|
-
return
|
|
8812
|
+
return path10__default.default.join(this.runsDirectory, encodeURIComponent(runId));
|
|
8776
8813
|
}
|
|
8777
8814
|
runEntriesDirectory(runId) {
|
|
8778
|
-
return
|
|
8815
|
+
return path10__default.default.join(this.runDirectory(runId), "entries");
|
|
8779
8816
|
}
|
|
8780
8817
|
runManifestPath(runId) {
|
|
8781
|
-
return
|
|
8818
|
+
return path10__default.default.join(this.runDirectory(runId), "manifest.json");
|
|
8782
8819
|
}
|
|
8783
8820
|
runWriteLockPath(runId) {
|
|
8784
|
-
return
|
|
8821
|
+
return path10__default.default.join(this.runDirectory(runId), ".append.lock");
|
|
8785
8822
|
}
|
|
8786
8823
|
};
|
|
8787
8824
|
function createTraceStore(rootPath, artifacts) {
|
|
@@ -8795,7 +8832,7 @@ function normalizeWorkspaceId(workspace) {
|
|
|
8795
8832
|
return encodePathSegment(workspace);
|
|
8796
8833
|
}
|
|
8797
8834
|
function resolveFilesystemWorkspacePath(input) {
|
|
8798
|
-
return
|
|
8835
|
+
return path10__default.default.join(
|
|
8799
8836
|
input.rootDir,
|
|
8800
8837
|
".opensteer",
|
|
8801
8838
|
"workspaces",
|
|
@@ -8804,18 +8841,18 @@ function resolveFilesystemWorkspacePath(input) {
|
|
|
8804
8841
|
}
|
|
8805
8842
|
async function createFilesystemOpensteerWorkspace(options) {
|
|
8806
8843
|
await ensureDirectory(options.rootPath);
|
|
8807
|
-
const manifestPath =
|
|
8808
|
-
const browserPath =
|
|
8809
|
-
const browserManifestPath =
|
|
8810
|
-
const browserUserDataDir =
|
|
8811
|
-
const livePath =
|
|
8812
|
-
const liveLocalPath =
|
|
8813
|
-
const liveCloudPath =
|
|
8814
|
-
const artifactsPath =
|
|
8815
|
-
const tracesPath =
|
|
8816
|
-
const observationsPath =
|
|
8817
|
-
const registryPath =
|
|
8818
|
-
const lockPath =
|
|
8844
|
+
const manifestPath = path10__default.default.join(options.rootPath, "workspace.json");
|
|
8845
|
+
const browserPath = path10__default.default.join(options.rootPath, "browser");
|
|
8846
|
+
const browserManifestPath = path10__default.default.join(browserPath, "manifest.json");
|
|
8847
|
+
const browserUserDataDir = path10__default.default.join(browserPath, "user-data");
|
|
8848
|
+
const livePath = path10__default.default.join(options.rootPath, "live");
|
|
8849
|
+
const liveLocalPath = path10__default.default.join(livePath, "local.json");
|
|
8850
|
+
const liveCloudPath = path10__default.default.join(livePath, "cloud.json");
|
|
8851
|
+
const artifactsPath = path10__default.default.join(options.rootPath, "artifacts");
|
|
8852
|
+
const tracesPath = path10__default.default.join(options.rootPath, "traces");
|
|
8853
|
+
const observationsPath = path10__default.default.join(options.rootPath, "observations");
|
|
8854
|
+
const registryPath = path10__default.default.join(options.rootPath, "registry");
|
|
8855
|
+
const lockPath = path10__default.default.join(options.rootPath, ".lock");
|
|
8819
8856
|
let manifest;
|
|
8820
8857
|
if (await pathExists(manifestPath)) {
|
|
8821
8858
|
manifest = await readJsonFile(manifestPath);
|
|
@@ -8942,7 +8979,6 @@ var DEFAULT_TIMEOUTS = {
|
|
|
8942
8979
|
"dom.extract": 15e3,
|
|
8943
8980
|
"network.query": 15e3,
|
|
8944
8981
|
"network.detail": 15e3,
|
|
8945
|
-
"network.replay": 3e4,
|
|
8946
8982
|
"scripts.capture": 15e3,
|
|
8947
8983
|
"session.cookies": 1e4,
|
|
8948
8984
|
"session.storage": 1e4,
|
|
@@ -9571,9 +9607,9 @@ var IFRAME_URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
9571
9607
|
"poster",
|
|
9572
9608
|
"ping"
|
|
9573
9609
|
]);
|
|
9574
|
-
function buildArrayFieldPathCandidates(
|
|
9575
|
-
const strict =
|
|
9576
|
-
const relaxedNodes = stripPositionClauses(
|
|
9610
|
+
function buildArrayFieldPathCandidates(path18) {
|
|
9611
|
+
const strict = path18.nodes.length ? buildPathCandidates(path18.nodes) : [];
|
|
9612
|
+
const relaxedNodes = stripPositionClauses(path18.nodes);
|
|
9577
9613
|
const relaxed = relaxedNodes.length ? buildPathCandidates(relaxedNodes) : [];
|
|
9578
9614
|
return dedupeSelectors([...strict, ...relaxed]);
|
|
9579
9615
|
}
|
|
@@ -10103,18 +10139,18 @@ function cloneStructuralElementAnchor(anchor) {
|
|
|
10103
10139
|
nodes: anchor.nodes.map(clonePathNode)
|
|
10104
10140
|
};
|
|
10105
10141
|
}
|
|
10106
|
-
function cloneReplayElementPath(
|
|
10142
|
+
function cloneReplayElementPath(path18) {
|
|
10107
10143
|
return {
|
|
10108
10144
|
resolution: "deterministic",
|
|
10109
|
-
context: cloneContext(
|
|
10110
|
-
nodes:
|
|
10145
|
+
context: cloneContext(path18.context),
|
|
10146
|
+
nodes: path18.nodes.map(clonePathNode)
|
|
10111
10147
|
};
|
|
10112
10148
|
}
|
|
10113
|
-
function cloneElementPath(
|
|
10114
|
-
return cloneReplayElementPath(
|
|
10149
|
+
function cloneElementPath(path18) {
|
|
10150
|
+
return cloneReplayElementPath(path18);
|
|
10115
10151
|
}
|
|
10116
|
-
function buildPathSelectorHint(
|
|
10117
|
-
const nodes =
|
|
10152
|
+
function buildPathSelectorHint(path18) {
|
|
10153
|
+
const nodes = path18?.nodes || [];
|
|
10118
10154
|
const last = nodes[nodes.length - 1];
|
|
10119
10155
|
if (!last) {
|
|
10120
10156
|
return "*";
|
|
@@ -10163,15 +10199,15 @@ function sanitizeStructuralElementAnchor(anchor) {
|
|
|
10163
10199
|
nodes: sanitizeNodes(anchor.nodes)
|
|
10164
10200
|
};
|
|
10165
10201
|
}
|
|
10166
|
-
function sanitizeReplayElementPath(
|
|
10202
|
+
function sanitizeReplayElementPath(path18) {
|
|
10167
10203
|
return {
|
|
10168
10204
|
resolution: "deterministic",
|
|
10169
|
-
context: sanitizeContext(
|
|
10170
|
-
nodes: sanitizeNodes(
|
|
10205
|
+
context: sanitizeContext(path18.context),
|
|
10206
|
+
nodes: sanitizeNodes(path18.nodes)
|
|
10171
10207
|
};
|
|
10172
10208
|
}
|
|
10173
|
-
function sanitizeElementPath(
|
|
10174
|
-
return sanitizeReplayElementPath(
|
|
10209
|
+
function sanitizeElementPath(path18) {
|
|
10210
|
+
return sanitizeReplayElementPath(path18);
|
|
10175
10211
|
}
|
|
10176
10212
|
function buildLocalStructuralElementAnchor(index, rawTargetNode) {
|
|
10177
10213
|
const targetNode = requireElementNode(index, rawTargetNode);
|
|
@@ -10294,8 +10330,8 @@ function buildTargetNotFoundMessage(domPath, diagnostics) {
|
|
|
10294
10330
|
}
|
|
10295
10331
|
return `${base} Target depth ${String(depth)}. Candidate counts: ${sample}.`;
|
|
10296
10332
|
}
|
|
10297
|
-
function buildArrayFieldCandidates(
|
|
10298
|
-
return buildArrayFieldPathCandidates(
|
|
10333
|
+
function buildArrayFieldCandidates(path18) {
|
|
10334
|
+
return buildArrayFieldPathCandidates(path18);
|
|
10299
10335
|
}
|
|
10300
10336
|
function firstDefinedAttribute(node, keys) {
|
|
10301
10337
|
for (const key of keys) {
|
|
@@ -11831,21 +11867,21 @@ var DefaultDomRuntime = class {
|
|
|
11831
11867
|
return match;
|
|
11832
11868
|
}
|
|
11833
11869
|
async resolvePathTarget(session, pageRef, rawPath, source, persist, descriptor) {
|
|
11834
|
-
const
|
|
11835
|
-
const context = await this.resolvePathContext(session, pageRef,
|
|
11836
|
-
const target = resolveDomPathInScope(context.index,
|
|
11870
|
+
const path18 = sanitizeReplayElementPath(rawPath);
|
|
11871
|
+
const context = await this.resolvePathContext(session, pageRef, path18.context);
|
|
11872
|
+
const target = resolveDomPathInScope(context.index, path18.nodes, context.scope);
|
|
11837
11873
|
if (!target) {
|
|
11838
|
-
throwTargetNotFound(context.index,
|
|
11874
|
+
throwTargetNotFound(context.index, path18.nodes, context.scope);
|
|
11839
11875
|
}
|
|
11840
11876
|
if (target.node.nodeRef === void 0) {
|
|
11841
11877
|
throw new Error(
|
|
11842
|
-
`resolved path "${buildPathSelectorHint(
|
|
11878
|
+
`resolved path "${buildPathSelectorHint(path18)}" does not point to a live element`
|
|
11843
11879
|
);
|
|
11844
11880
|
}
|
|
11845
11881
|
const anchor = await this.buildAnchorFromSnapshotNode(session, context.snapshot, target.node);
|
|
11846
11882
|
return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
|
|
11847
11883
|
...persist === void 0 ? {} : { persist },
|
|
11848
|
-
replayPath:
|
|
11884
|
+
replayPath: path18,
|
|
11849
11885
|
...source === "path" || source === "descriptor" ? { selectorUsed: target.selector } : {},
|
|
11850
11886
|
...descriptor === void 0 ? {} : { descriptor }
|
|
11851
11887
|
});
|
|
@@ -11866,9 +11902,9 @@ var DefaultDomRuntime = class {
|
|
|
11866
11902
|
});
|
|
11867
11903
|
}
|
|
11868
11904
|
async queryAllByElementPath(session, pageRef, rawPath) {
|
|
11869
|
-
const
|
|
11870
|
-
const context = await this.resolvePathContext(session, pageRef,
|
|
11871
|
-
return queryAllDomPathInScope(context.index,
|
|
11905
|
+
const path18 = sanitizeReplayElementPath(rawPath);
|
|
11906
|
+
const context = await this.resolvePathContext(session, pageRef, path18.context);
|
|
11907
|
+
return queryAllDomPathInScope(context.index, path18.nodes, context.scope).filter(
|
|
11872
11908
|
(node) => node.nodeRef !== void 0
|
|
11873
11909
|
).map((node) => this.createSnapshotTarget(context.snapshot, node));
|
|
11874
11910
|
}
|
|
@@ -12054,16 +12090,16 @@ var DefaultDomRuntime = class {
|
|
|
12054
12090
|
const index = createSnapshotIndex(item.snapshot);
|
|
12055
12091
|
return this.resolveFirstArrayFieldTargetInNode(index, item.node, field.path);
|
|
12056
12092
|
}
|
|
12057
|
-
resolveFirstArrayFieldTargetInNode(index, rootNode,
|
|
12058
|
-
const normalizedPath = sanitizeElementPath(
|
|
12093
|
+
resolveFirstArrayFieldTargetInNode(index, rootNode, path18) {
|
|
12094
|
+
const normalizedPath = sanitizeElementPath(path18);
|
|
12059
12095
|
const selectors = buildArrayFieldCandidates(normalizedPath);
|
|
12060
12096
|
if (!selectors.length) {
|
|
12061
12097
|
return rootNode;
|
|
12062
12098
|
}
|
|
12063
12099
|
return resolveFirstWithinNodeBySelectors(index, rootNode, selectors);
|
|
12064
12100
|
}
|
|
12065
|
-
resolveUniqueArrayFieldTargetInNode(index, rootNode,
|
|
12066
|
-
const normalizedPath = sanitizeElementPath(
|
|
12101
|
+
resolveUniqueArrayFieldTargetInNode(index, rootNode, path18) {
|
|
12102
|
+
const normalizedPath = sanitizeElementPath(path18);
|
|
12067
12103
|
const selectors = buildArrayFieldCandidates(normalizedPath);
|
|
12068
12104
|
if (!selectors.length) {
|
|
12069
12105
|
return rootNode;
|
|
@@ -12152,8 +12188,8 @@ function encodeDataPath(tokens) {
|
|
|
12152
12188
|
}
|
|
12153
12189
|
return out;
|
|
12154
12190
|
}
|
|
12155
|
-
function parseDataPath(
|
|
12156
|
-
const input =
|
|
12191
|
+
function parseDataPath(path18) {
|
|
12192
|
+
const input = path18.trim();
|
|
12157
12193
|
if (input.length === 0) {
|
|
12158
12194
|
return [];
|
|
12159
12195
|
}
|
|
@@ -12203,8 +12239,8 @@ function parseDataPath(path15) {
|
|
|
12203
12239
|
function inflateDataPathObject(flat) {
|
|
12204
12240
|
let root = {};
|
|
12205
12241
|
let initialized = false;
|
|
12206
|
-
for (const [
|
|
12207
|
-
const tokens = parseDataPath(
|
|
12242
|
+
for (const [path18, value] of Object.entries(flat)) {
|
|
12243
|
+
const tokens = parseDataPath(path18);
|
|
12208
12244
|
if (!tokens || tokens.length === 0) {
|
|
12209
12245
|
continue;
|
|
12210
12246
|
}
|
|
@@ -12536,8 +12572,8 @@ function buildVariantDescriptorFromCluster(descriptors) {
|
|
|
12536
12572
|
fields: mergedFields
|
|
12537
12573
|
};
|
|
12538
12574
|
}
|
|
12539
|
-
function minimizePathMatchClauses(
|
|
12540
|
-
const normalized = sanitizeElementPath(
|
|
12575
|
+
function minimizePathMatchClauses(path18, mode) {
|
|
12576
|
+
const normalized = sanitizeElementPath(path18);
|
|
12541
12577
|
const nodes = normalized.nodes.map((node, index) => {
|
|
12542
12578
|
const isLast = index === normalized.nodes.length - 1;
|
|
12543
12579
|
const attrs = node.attrs || {};
|
|
@@ -12641,8 +12677,8 @@ function seedMinimalAttrClause(attrs) {
|
|
|
12641
12677
|
}
|
|
12642
12678
|
return null;
|
|
12643
12679
|
}
|
|
12644
|
-
function relaxPathForSingleSample(
|
|
12645
|
-
const normalized = sanitizeElementPath(
|
|
12680
|
+
function relaxPathForSingleSample(path18, mode) {
|
|
12681
|
+
const normalized = sanitizeElementPath(path18);
|
|
12646
12682
|
const relaxedNodes = normalized.nodes.map((node, index) => {
|
|
12647
12683
|
const isLast = index === normalized.nodes.length - 1;
|
|
12648
12684
|
const attrs = normalizeAttrsForSingleSample(node.attrs || {});
|
|
@@ -12727,8 +12763,8 @@ function shouldKeepAttrForSingleSample(key) {
|
|
|
12727
12763
|
}
|
|
12728
12764
|
return true;
|
|
12729
12765
|
}
|
|
12730
|
-
function buildPathStructureKey(
|
|
12731
|
-
const normalized = sanitizeElementPath(
|
|
12766
|
+
function buildPathStructureKey(path18) {
|
|
12767
|
+
const normalized = sanitizeElementPath(path18);
|
|
12732
12768
|
return canonicalJsonString({
|
|
12733
12769
|
context: (normalized.context || []).map((hop) => ({
|
|
12734
12770
|
kind: hop.kind,
|
|
@@ -12855,30 +12891,30 @@ function buildArrayItemNode(fields) {
|
|
|
12855
12891
|
}
|
|
12856
12892
|
return node;
|
|
12857
12893
|
}
|
|
12858
|
-
function insertNodeAtPath(root,
|
|
12859
|
-
const tokens = parseDataPath(
|
|
12894
|
+
function insertNodeAtPath(root, path18, node) {
|
|
12895
|
+
const tokens = parseDataPath(path18);
|
|
12860
12896
|
if (!tokens || !tokens.length) {
|
|
12861
12897
|
throw new Error(
|
|
12862
|
-
`Invalid persisted extraction path "${
|
|
12898
|
+
`Invalid persisted extraction path "${path18}": expected a non-empty object path.`
|
|
12863
12899
|
);
|
|
12864
12900
|
}
|
|
12865
12901
|
if (tokens.some((token) => token.kind === "index")) {
|
|
12866
12902
|
throw new Error(
|
|
12867
|
-
`Invalid persisted extraction path "${
|
|
12903
|
+
`Invalid persisted extraction path "${path18}": nested array indices are not supported in cached descriptors.`
|
|
12868
12904
|
);
|
|
12869
12905
|
}
|
|
12870
12906
|
let current = root;
|
|
12871
12907
|
for (let index = 0; index < tokens.length; index += 1) {
|
|
12872
12908
|
const token = tokens[index];
|
|
12873
12909
|
if (!token || token.kind !== "prop") {
|
|
12874
|
-
throw new Error(`Invalid persisted extraction path "${
|
|
12910
|
+
throw new Error(`Invalid persisted extraction path "${path18}": expected object segment.`);
|
|
12875
12911
|
}
|
|
12876
12912
|
const isLast = index === tokens.length - 1;
|
|
12877
12913
|
if (isLast) {
|
|
12878
12914
|
const existing = current[token.key];
|
|
12879
12915
|
if (existing) {
|
|
12880
12916
|
throw new Error(
|
|
12881
|
-
`Conflicting persisted extraction path "${
|
|
12917
|
+
`Conflicting persisted extraction path "${path18}" detected while building descriptor tree.`
|
|
12882
12918
|
);
|
|
12883
12919
|
}
|
|
12884
12920
|
current[token.key] = node;
|
|
@@ -12893,7 +12929,7 @@ function insertNodeAtPath(root, path15, node) {
|
|
|
12893
12929
|
}
|
|
12894
12930
|
if (!isPersistedObjectNode(next)) {
|
|
12895
12931
|
throw new Error(
|
|
12896
|
-
`Conflicting persisted extraction path "${
|
|
12932
|
+
`Conflicting persisted extraction path "${path18}" detected at "${token.key}".`
|
|
12897
12933
|
);
|
|
12898
12934
|
}
|
|
12899
12935
|
current = next;
|
|
@@ -12928,7 +12964,7 @@ function buildItemRootForArrayIndex(entries) {
|
|
|
12928
12964
|
}
|
|
12929
12965
|
const paths = entries.map(
|
|
12930
12966
|
(entry) => isPersistablePathField(entry.source) ? sanitizeElementPath(entry.source.path) : null
|
|
12931
|
-
).filter((
|
|
12967
|
+
).filter((path18) => path18 !== null);
|
|
12932
12968
|
if (!paths.length) {
|
|
12933
12969
|
return null;
|
|
12934
12970
|
}
|
|
@@ -12949,7 +12985,7 @@ function getCommonPathPrefixLength(paths) {
|
|
|
12949
12985
|
if (!paths.length) {
|
|
12950
12986
|
return 0;
|
|
12951
12987
|
}
|
|
12952
|
-
const nodeChains = paths.map((
|
|
12988
|
+
const nodeChains = paths.map((path18) => path18.nodes);
|
|
12953
12989
|
const minLength = Math.min(...nodeChains.map((nodes) => nodes.length));
|
|
12954
12990
|
if (!Number.isFinite(minLength) || minLength <= 0) {
|
|
12955
12991
|
return 0;
|
|
@@ -13018,30 +13054,30 @@ function mergeElementPathsByMajority(paths) {
|
|
|
13018
13054
|
if (!paths.length) {
|
|
13019
13055
|
return null;
|
|
13020
13056
|
}
|
|
13021
|
-
const normalized = paths.map((
|
|
13057
|
+
const normalized = paths.map((path18) => sanitizeElementPath(path18));
|
|
13022
13058
|
const contextKey = pickModeString(
|
|
13023
|
-
normalized.map((
|
|
13059
|
+
normalized.map((path18) => canonicalJsonString(path18.context)),
|
|
13024
13060
|
1
|
|
13025
13061
|
);
|
|
13026
13062
|
if (!contextKey) {
|
|
13027
13063
|
return null;
|
|
13028
13064
|
}
|
|
13029
|
-
const sameContext = normalized.filter((
|
|
13065
|
+
const sameContext = normalized.filter((path18) => canonicalJsonString(path18.context) === contextKey);
|
|
13030
13066
|
if (!sameContext.length) {
|
|
13031
13067
|
return null;
|
|
13032
13068
|
}
|
|
13033
13069
|
const targetLength = pickModeNumber(
|
|
13034
|
-
sameContext.map((
|
|
13070
|
+
sameContext.map((path18) => path18.nodes.length),
|
|
13035
13071
|
1
|
|
13036
13072
|
) ?? sameContext[0]?.nodes.length ?? 0;
|
|
13037
|
-
const aligned = sameContext.filter((
|
|
13073
|
+
const aligned = sameContext.filter((path18) => path18.nodes.length === targetLength);
|
|
13038
13074
|
if (!aligned.length) {
|
|
13039
13075
|
return null;
|
|
13040
13076
|
}
|
|
13041
13077
|
const threshold = majorityThreshold(aligned.length);
|
|
13042
13078
|
const nodes = [];
|
|
13043
13079
|
for (let index = 0; index < targetLength; index += 1) {
|
|
13044
|
-
const nodesAtIndex = aligned.map((
|
|
13080
|
+
const nodesAtIndex = aligned.map((path18) => path18.nodes[index]).filter((node) => node !== void 0);
|
|
13045
13081
|
if (!nodesAtIndex.length) {
|
|
13046
13082
|
return null;
|
|
13047
13083
|
}
|
|
@@ -13287,8 +13323,8 @@ function clonePathContext(context) {
|
|
|
13287
13323
|
function clonePathNodes(nodes) {
|
|
13288
13324
|
return JSON.parse(JSON.stringify(nodes || []));
|
|
13289
13325
|
}
|
|
13290
|
-
function cloneElementPath2(
|
|
13291
|
-
return JSON.parse(JSON.stringify(
|
|
13326
|
+
function cloneElementPath2(path18) {
|
|
13327
|
+
return JSON.parse(JSON.stringify(path18));
|
|
13292
13328
|
}
|
|
13293
13329
|
function clonePersistedOpensteerExtractionNode(node) {
|
|
13294
13330
|
return JSON.parse(JSON.stringify(node));
|
|
@@ -13606,8 +13642,8 @@ function collectPersistedValueNodeRefs(node) {
|
|
|
13606
13642
|
return [
|
|
13607
13643
|
{
|
|
13608
13644
|
path: sanitizeElementPath(node.$path),
|
|
13609
|
-
replacePath: (
|
|
13610
|
-
node.$path = sanitizeElementPath(
|
|
13645
|
+
replacePath: (path18) => {
|
|
13646
|
+
node.$path = sanitizeElementPath(path18);
|
|
13611
13647
|
}
|
|
13612
13648
|
}
|
|
13613
13649
|
];
|
|
@@ -13621,13 +13657,13 @@ function collectPersistedValueNodeRefs(node) {
|
|
|
13621
13657
|
}
|
|
13622
13658
|
return refs;
|
|
13623
13659
|
}
|
|
13624
|
-
function hasPositionClause(
|
|
13625
|
-
return
|
|
13660
|
+
function hasPositionClause(path18) {
|
|
13661
|
+
return path18.nodes.some((node) => node.match.some((clause) => clause.kind === "position"));
|
|
13626
13662
|
}
|
|
13627
|
-
function stripPositionClauses2(
|
|
13663
|
+
function stripPositionClauses2(path18) {
|
|
13628
13664
|
return sanitizeElementPath({
|
|
13629
|
-
context:
|
|
13630
|
-
nodes:
|
|
13665
|
+
context: path18.context,
|
|
13666
|
+
nodes: path18.nodes.map((node) => ({
|
|
13631
13667
|
...node,
|
|
13632
13668
|
match: node.match.filter((clause) => clause.kind !== "position")
|
|
13633
13669
|
}))
|
|
@@ -14037,17 +14073,57 @@ function normalizeNonEmptyString2(name, value) {
|
|
|
14037
14073
|
function normalizeKey(value) {
|
|
14038
14074
|
return String(value ?? "").trim();
|
|
14039
14075
|
}
|
|
14040
|
-
function labelForPath(
|
|
14041
|
-
return
|
|
14076
|
+
function labelForPath(path18) {
|
|
14077
|
+
return path18.trim().length === 0 ? "$" : path18;
|
|
14042
14078
|
}
|
|
14043
14079
|
function sha256Hex3(value) {
|
|
14044
14080
|
return crypto.createHash("sha256").update(value).digest("hex");
|
|
14045
14081
|
}
|
|
14046
|
-
util.promisify(child_process.execFile);
|
|
14047
|
-
Math.floor(Date.now() - process.uptime() * 1e3);
|
|
14048
|
-
|
|
14049
|
-
|
|
14050
|
-
|
|
14082
|
+
var execFileAsync = util.promisify(child_process.execFile);
|
|
14083
|
+
var PROCESS_STARTED_AT_MS = Math.floor(Date.now() - process.uptime() * 1e3);
|
|
14084
|
+
var PROCESS_START_TIME_TOLERANCE_MS = 1e3;
|
|
14085
|
+
var PROCESS_LIST_MAX_BUFFER_BYTES = 16 * 1024 * 1024;
|
|
14086
|
+
var PS_COMMAND_ENV = { ...process.env, LC_ALL: "C" };
|
|
14087
|
+
var LINUX_STAT_START_TIME_FIELD_INDEX = 19;
|
|
14088
|
+
var CURRENT_PROCESS_OWNER = {
|
|
14089
|
+
pid: process.pid,
|
|
14090
|
+
processStartedAtMs: PROCESS_STARTED_AT_MS
|
|
14091
|
+
};
|
|
14092
|
+
var linuxClockTicksPerSecondPromise = null;
|
|
14093
|
+
function parseProcessOwner(value) {
|
|
14094
|
+
if (!value || typeof value !== "object") {
|
|
14095
|
+
return null;
|
|
14096
|
+
}
|
|
14097
|
+
const parsed = value;
|
|
14098
|
+
const pid = Number(parsed.pid);
|
|
14099
|
+
const processStartedAtMs = Number(parsed.processStartedAtMs);
|
|
14100
|
+
if (!Number.isInteger(pid) || pid <= 0) {
|
|
14101
|
+
return null;
|
|
14102
|
+
}
|
|
14103
|
+
if (!Number.isInteger(processStartedAtMs) || processStartedAtMs <= 0) {
|
|
14104
|
+
return null;
|
|
14105
|
+
}
|
|
14106
|
+
return {
|
|
14107
|
+
pid,
|
|
14108
|
+
processStartedAtMs
|
|
14109
|
+
};
|
|
14110
|
+
}
|
|
14111
|
+
function processOwnersEqual(left, right) {
|
|
14112
|
+
if (!left || !right) {
|
|
14113
|
+
return left === right;
|
|
14114
|
+
}
|
|
14115
|
+
return left.pid === right.pid && left.processStartedAtMs === right.processStartedAtMs;
|
|
14116
|
+
}
|
|
14117
|
+
async function getProcessLiveness(owner) {
|
|
14118
|
+
if (owner.pid === process.pid && hasMatchingProcessStartTime(owner.processStartedAtMs, PROCESS_STARTED_AT_MS)) {
|
|
14119
|
+
return "live";
|
|
14120
|
+
}
|
|
14121
|
+
const startedAtMs = await readProcessStartedAtMs(owner.pid);
|
|
14122
|
+
if (typeof startedAtMs === "number") {
|
|
14123
|
+
return hasMatchingProcessStartTime(owner.processStartedAtMs, startedAtMs) ? "live" : "dead";
|
|
14124
|
+
}
|
|
14125
|
+
return isProcessRunning(owner.pid) ? "unknown" : "dead";
|
|
14126
|
+
}
|
|
14051
14127
|
function isProcessRunning(pid) {
|
|
14052
14128
|
try {
|
|
14053
14129
|
process.kill(pid, 0);
|
|
@@ -14057,6 +14133,116 @@ function isProcessRunning(pid) {
|
|
|
14057
14133
|
return code !== "ESRCH";
|
|
14058
14134
|
}
|
|
14059
14135
|
}
|
|
14136
|
+
function hasMatchingProcessStartTime(expectedStartedAtMs, actualStartedAtMs) {
|
|
14137
|
+
return Math.abs(expectedStartedAtMs - actualStartedAtMs) <= PROCESS_START_TIME_TOLERANCE_MS;
|
|
14138
|
+
}
|
|
14139
|
+
async function readProcessStartedAtMs(pid) {
|
|
14140
|
+
if (pid <= 0) {
|
|
14141
|
+
return null;
|
|
14142
|
+
}
|
|
14143
|
+
if (process.platform === "linux") {
|
|
14144
|
+
return readLinuxProcessStartedAtMs(pid);
|
|
14145
|
+
}
|
|
14146
|
+
if (process.platform === "win32") {
|
|
14147
|
+
return readWindowsProcessStartedAtMs(pid);
|
|
14148
|
+
}
|
|
14149
|
+
return readPsProcessStartedAtMs(pid);
|
|
14150
|
+
}
|
|
14151
|
+
async function readLinuxProcessStartedAtMs(pid) {
|
|
14152
|
+
let statRaw;
|
|
14153
|
+
try {
|
|
14154
|
+
statRaw = await promises.readFile(`/proc/${String(pid)}/stat`, "utf8");
|
|
14155
|
+
} catch {
|
|
14156
|
+
return null;
|
|
14157
|
+
}
|
|
14158
|
+
const startTicks = parseLinuxProcessStartTicks(statRaw);
|
|
14159
|
+
if (startTicks === null) {
|
|
14160
|
+
return null;
|
|
14161
|
+
}
|
|
14162
|
+
const [bootTimeMs, clockTicksPerSecond] = await Promise.all([
|
|
14163
|
+
readLinuxBootTimeMs(),
|
|
14164
|
+
readLinuxClockTicksPerSecond()
|
|
14165
|
+
]);
|
|
14166
|
+
if (bootTimeMs === null || clockTicksPerSecond === null) {
|
|
14167
|
+
return null;
|
|
14168
|
+
}
|
|
14169
|
+
return Math.floor(bootTimeMs + startTicks * 1e3 / clockTicksPerSecond);
|
|
14170
|
+
}
|
|
14171
|
+
function parseLinuxProcessStartTicks(statRaw) {
|
|
14172
|
+
const closingParenIndex = statRaw.lastIndexOf(")");
|
|
14173
|
+
if (closingParenIndex === -1) {
|
|
14174
|
+
return null;
|
|
14175
|
+
}
|
|
14176
|
+
const fields = statRaw.slice(closingParenIndex + 2).trim().split(/\s+/);
|
|
14177
|
+
const startTicks = Number(fields[LINUX_STAT_START_TIME_FIELD_INDEX]);
|
|
14178
|
+
return Number.isFinite(startTicks) && startTicks >= 0 ? startTicks : null;
|
|
14179
|
+
}
|
|
14180
|
+
async function readLinuxBootTimeMs() {
|
|
14181
|
+
try {
|
|
14182
|
+
const statRaw = await promises.readFile("/proc/stat", "utf8");
|
|
14183
|
+
const bootTimeLine = statRaw.split("\n").find((line) => line.startsWith("btime "));
|
|
14184
|
+
if (!bootTimeLine) {
|
|
14185
|
+
return null;
|
|
14186
|
+
}
|
|
14187
|
+
const bootTimeSeconds = Number.parseInt(bootTimeLine.slice("btime ".length), 10);
|
|
14188
|
+
return Number.isFinite(bootTimeSeconds) ? bootTimeSeconds * 1e3 : null;
|
|
14189
|
+
} catch {
|
|
14190
|
+
return null;
|
|
14191
|
+
}
|
|
14192
|
+
}
|
|
14193
|
+
async function readLinuxClockTicksPerSecond() {
|
|
14194
|
+
if (!linuxClockTicksPerSecondPromise) {
|
|
14195
|
+
linuxClockTicksPerSecondPromise = execFileAsync("getconf", ["CLK_TCK"], {
|
|
14196
|
+
encoding: "utf8",
|
|
14197
|
+
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES
|
|
14198
|
+
}).then(({ stdout }) => {
|
|
14199
|
+
const value = Number.parseInt(stdout.trim(), 10);
|
|
14200
|
+
return Number.isFinite(value) && value > 0 ? value : null;
|
|
14201
|
+
}).catch(() => null);
|
|
14202
|
+
}
|
|
14203
|
+
return linuxClockTicksPerSecondPromise;
|
|
14204
|
+
}
|
|
14205
|
+
async function readWindowsProcessStartedAtMs(pid) {
|
|
14206
|
+
try {
|
|
14207
|
+
const { stdout } = await execFileAsync(
|
|
14208
|
+
"powershell.exe",
|
|
14209
|
+
[
|
|
14210
|
+
"-NoProfile",
|
|
14211
|
+
"-Command",
|
|
14212
|
+
`(Get-Process -Id ${String(pid)}).StartTime.ToUniversalTime().ToString("o")`
|
|
14213
|
+
],
|
|
14214
|
+
{
|
|
14215
|
+
encoding: "utf8",
|
|
14216
|
+
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES
|
|
14217
|
+
}
|
|
14218
|
+
);
|
|
14219
|
+
const isoTimestamp = stdout.trim();
|
|
14220
|
+
if (!isoTimestamp) {
|
|
14221
|
+
return null;
|
|
14222
|
+
}
|
|
14223
|
+
const startedAtMs = Date.parse(isoTimestamp);
|
|
14224
|
+
return Number.isFinite(startedAtMs) ? startedAtMs : null;
|
|
14225
|
+
} catch {
|
|
14226
|
+
return null;
|
|
14227
|
+
}
|
|
14228
|
+
}
|
|
14229
|
+
async function readPsProcessStartedAtMs(pid) {
|
|
14230
|
+
try {
|
|
14231
|
+
const { stdout } = await execFileAsync("ps", ["-o", "lstart=", "-p", String(pid)], {
|
|
14232
|
+
encoding: "utf8",
|
|
14233
|
+
env: PS_COMMAND_ENV,
|
|
14234
|
+
maxBuffer: PROCESS_LIST_MAX_BUFFER_BYTES
|
|
14235
|
+
});
|
|
14236
|
+
const startedAt = stdout.trim();
|
|
14237
|
+
if (!startedAt) {
|
|
14238
|
+
return null;
|
|
14239
|
+
}
|
|
14240
|
+
const startedAtMs = Date.parse(startedAt.replace(/\s+/g, " "));
|
|
14241
|
+
return Number.isFinite(startedAtMs) ? startedAtMs : null;
|
|
14242
|
+
} catch {
|
|
14243
|
+
return null;
|
|
14244
|
+
}
|
|
14245
|
+
}
|
|
14060
14246
|
var CHROME_SINGLETON_ARTIFACTS = [
|
|
14061
14247
|
"SingletonCookie",
|
|
14062
14248
|
"SingletonLock",
|
|
@@ -14067,7 +14253,7 @@ var CHROME_SINGLETON_ARTIFACTS = [
|
|
|
14067
14253
|
async function clearChromeSingletonEntries(userDataDir) {
|
|
14068
14254
|
await Promise.all(
|
|
14069
14255
|
CHROME_SINGLETON_ARTIFACTS.map(
|
|
14070
|
-
(entry) => promises.rm(
|
|
14256
|
+
(entry) => promises.rm(path10.join(userDataDir, entry), {
|
|
14071
14257
|
recursive: true,
|
|
14072
14258
|
force: true
|
|
14073
14259
|
}).catch(() => void 0)
|
|
@@ -14082,7 +14268,7 @@ async function sanitizeChromeProfile(userDataDir) {
|
|
|
14082
14268
|
await Promise.all(profileDirs.map((dir) => sanitizeProfilePreferences(userDataDir, dir)));
|
|
14083
14269
|
}
|
|
14084
14270
|
async function sanitizeProfilePreferences(userDataDir, profileDir) {
|
|
14085
|
-
const prefsPath =
|
|
14271
|
+
const prefsPath = path10.join(userDataDir, profileDir, "Preferences");
|
|
14086
14272
|
try {
|
|
14087
14273
|
const raw = await promises.readFile(prefsPath, "utf8");
|
|
14088
14274
|
const prefs = JSON.parse(raw);
|
|
@@ -14094,7 +14280,7 @@ async function sanitizeProfilePreferences(userDataDir, profileDir) {
|
|
|
14094
14280
|
profile.exited_cleanly = true;
|
|
14095
14281
|
prefs.profile = profile;
|
|
14096
14282
|
await promises.writeFile(prefsPath, JSON.stringify(prefs), "utf8");
|
|
14097
|
-
await promises.rm(
|
|
14283
|
+
await promises.rm(path10.join(userDataDir, profileDir, "Secure Preferences"), { force: true }).catch(
|
|
14098
14284
|
() => void 0
|
|
14099
14285
|
);
|
|
14100
14286
|
} catch {
|
|
@@ -14115,9 +14301,9 @@ var BROWSER_BRANDS = [
|
|
|
14115
14301
|
},
|
|
14116
14302
|
win32: {
|
|
14117
14303
|
executableCandidates: [
|
|
14118
|
-
|
|
14119
|
-
|
|
14120
|
-
|
|
14304
|
+
path10.join(WINDOWS_PROGRAM_FILES, "Google", "Chrome", "Application", "chrome.exe"),
|
|
14305
|
+
path10.join(WINDOWS_PROGRAM_FILES_X86, "Google", "Chrome", "Application", "chrome.exe"),
|
|
14306
|
+
path10.join("~", "AppData", "Local", "Google", "Chrome", "Application", "chrome.exe")
|
|
14121
14307
|
],
|
|
14122
14308
|
userDataDir: "~/AppData/Local/Google/Chrome/User Data",
|
|
14123
14309
|
processNames: ["/google/chrome/application/chrome.exe"]
|
|
@@ -14147,7 +14333,7 @@ var BROWSER_BRANDS = [
|
|
|
14147
14333
|
},
|
|
14148
14334
|
win32: {
|
|
14149
14335
|
executableCandidates: [
|
|
14150
|
-
|
|
14336
|
+
path10.join("~", "AppData", "Local", "Google", "Chrome SxS", "Application", "chrome.exe")
|
|
14151
14337
|
],
|
|
14152
14338
|
userDataDir: "~/AppData/Local/Google/Chrome SxS/User Data",
|
|
14153
14339
|
processNames: ["/google/chrome sxs/application/chrome.exe"]
|
|
@@ -14164,9 +14350,9 @@ var BROWSER_BRANDS = [
|
|
|
14164
14350
|
},
|
|
14165
14351
|
win32: {
|
|
14166
14352
|
executableCandidates: [
|
|
14167
|
-
|
|
14168
|
-
|
|
14169
|
-
|
|
14353
|
+
path10.join(WINDOWS_PROGRAM_FILES, "Chromium", "Application", "chrome.exe"),
|
|
14354
|
+
path10.join(WINDOWS_PROGRAM_FILES_X86, "Chromium", "Application", "chrome.exe"),
|
|
14355
|
+
path10.join("~", "AppData", "Local", "Chromium", "Application", "chrome.exe")
|
|
14170
14356
|
],
|
|
14171
14357
|
userDataDir: "~/AppData/Local/Chromium/User Data",
|
|
14172
14358
|
processNames: ["/chromium/application/chrome.exe"]
|
|
@@ -14193,15 +14379,15 @@ var BROWSER_BRANDS = [
|
|
|
14193
14379
|
},
|
|
14194
14380
|
win32: {
|
|
14195
14381
|
executableCandidates: [
|
|
14196
|
-
|
|
14197
|
-
|
|
14382
|
+
path10.join(WINDOWS_PROGRAM_FILES, "BraveSoftware", "Brave-Browser", "Application", "brave.exe"),
|
|
14383
|
+
path10.join(
|
|
14198
14384
|
WINDOWS_PROGRAM_FILES_X86,
|
|
14199
14385
|
"BraveSoftware",
|
|
14200
14386
|
"Brave-Browser",
|
|
14201
14387
|
"Application",
|
|
14202
14388
|
"brave.exe"
|
|
14203
14389
|
),
|
|
14204
|
-
|
|
14390
|
+
path10.join("~", "AppData", "Local", "BraveSoftware", "Brave-Browser", "Application", "brave.exe")
|
|
14205
14391
|
],
|
|
14206
14392
|
userDataDir: "~/AppData/Local/BraveSoftware/Brave-Browser/User Data",
|
|
14207
14393
|
processNames: ["/bravesoftware/brave-browser/application/brave.exe"]
|
|
@@ -14227,9 +14413,9 @@ var BROWSER_BRANDS = [
|
|
|
14227
14413
|
},
|
|
14228
14414
|
win32: {
|
|
14229
14415
|
executableCandidates: [
|
|
14230
|
-
|
|
14231
|
-
|
|
14232
|
-
|
|
14416
|
+
path10.join(WINDOWS_PROGRAM_FILES, "Microsoft", "Edge", "Application", "msedge.exe"),
|
|
14417
|
+
path10.join(WINDOWS_PROGRAM_FILES_X86, "Microsoft", "Edge", "Application", "msedge.exe"),
|
|
14418
|
+
path10.join("~", "AppData", "Local", "Microsoft", "Edge", "Application", "msedge.exe")
|
|
14233
14419
|
],
|
|
14234
14420
|
userDataDir: "~/AppData/Local/Microsoft/Edge/User Data",
|
|
14235
14421
|
processNames: ["/microsoft/edge/application/msedge.exe"]
|
|
@@ -14257,9 +14443,9 @@ var BROWSER_BRANDS = [
|
|
|
14257
14443
|
},
|
|
14258
14444
|
win32: {
|
|
14259
14445
|
executableCandidates: [
|
|
14260
|
-
|
|
14261
|
-
|
|
14262
|
-
|
|
14446
|
+
path10.join(WINDOWS_PROGRAM_FILES, "Vivaldi", "Application", "vivaldi.exe"),
|
|
14447
|
+
path10.join(WINDOWS_PROGRAM_FILES_X86, "Vivaldi", "Application", "vivaldi.exe"),
|
|
14448
|
+
path10.join("~", "AppData", "Local", "Vivaldi", "Application", "vivaldi.exe")
|
|
14263
14449
|
],
|
|
14264
14450
|
userDataDir: "~/AppData/Local/Vivaldi/User Data",
|
|
14265
14451
|
processNames: ["/vivaldi/application/vivaldi.exe"]
|
|
@@ -14323,35 +14509,35 @@ function detectInstalledBrowserBrands() {
|
|
|
14323
14509
|
brandId: brand2.id,
|
|
14324
14510
|
displayName: brand2.displayName,
|
|
14325
14511
|
executablePath,
|
|
14326
|
-
userDataDir:
|
|
14512
|
+
userDataDir: path10.resolve(expandHome(platformConfig.userDataDir))
|
|
14327
14513
|
});
|
|
14328
14514
|
}
|
|
14329
14515
|
return installations;
|
|
14330
14516
|
}
|
|
14331
14517
|
function resolveBrandUserDataDir(brand2, explicitDir) {
|
|
14332
14518
|
if (explicitDir !== void 0) {
|
|
14333
|
-
return
|
|
14519
|
+
return path10.resolve(expandHome(explicitDir));
|
|
14334
14520
|
}
|
|
14335
14521
|
const platformConfig = resolveBrandPlatformConfig(brand2);
|
|
14336
14522
|
if (!platformConfig) {
|
|
14337
14523
|
throw new Error(`${brand2.displayName} is not supported on ${process.platform}.`);
|
|
14338
14524
|
}
|
|
14339
|
-
return
|
|
14525
|
+
return path10.resolve(expandHome(platformConfig.userDataDir));
|
|
14340
14526
|
}
|
|
14341
14527
|
function resolveExecutableCandidates(candidates) {
|
|
14342
|
-
return candidates.map((candidate) => candidate ?
|
|
14528
|
+
return candidates.map((candidate) => candidate ? path10.resolve(expandHome(candidate)) : null);
|
|
14343
14529
|
}
|
|
14344
14530
|
|
|
14345
14531
|
// src/local-browser/chrome-discovery.ts
|
|
14346
14532
|
function expandHome(value) {
|
|
14347
14533
|
if (value === "~" || value.startsWith("~/")) {
|
|
14348
|
-
return
|
|
14534
|
+
return path10.join(os.homedir(), value.slice(1));
|
|
14349
14535
|
}
|
|
14350
14536
|
return value;
|
|
14351
14537
|
}
|
|
14352
14538
|
function resolveChromeUserDataDir(userDataDir) {
|
|
14353
14539
|
const installation = detectLocalChromeInstallations().find(
|
|
14354
|
-
(candidate) => fs.existsSync(
|
|
14540
|
+
(candidate) => fs.existsSync(path10.join(candidate.userDataDir, "Local State")) || candidate.executablePath !== null
|
|
14355
14541
|
);
|
|
14356
14542
|
if (!installation) {
|
|
14357
14543
|
throw new Error("Could not find a local Chrome or Chromium profile directory.");
|
|
@@ -14360,7 +14546,7 @@ function resolveChromeUserDataDir(userDataDir) {
|
|
|
14360
14546
|
}
|
|
14361
14547
|
function resolveChromeExecutablePath(executablePath) {
|
|
14362
14548
|
if (executablePath !== void 0) {
|
|
14363
|
-
const resolvedPath =
|
|
14549
|
+
const resolvedPath = path10.resolve(expandHome(executablePath));
|
|
14364
14550
|
if (!fs.existsSync(resolvedPath)) {
|
|
14365
14551
|
throw new Error(`Chrome executable was not found at "${resolvedPath}".`);
|
|
14366
14552
|
}
|
|
@@ -14384,37 +14570,37 @@ function detectLocalChromeInstallations() {
|
|
|
14384
14570
|
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
14385
14571
|
"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"
|
|
14386
14572
|
]),
|
|
14387
|
-
userDataDir:
|
|
14573
|
+
userDataDir: path10.join(os.homedir(), "Library", "Application Support", "Google", "Chrome")
|
|
14388
14574
|
},
|
|
14389
14575
|
{
|
|
14390
14576
|
brand: "chromium",
|
|
14391
14577
|
executablePath: firstExistingPath(["/Applications/Chromium.app/Contents/MacOS/Chromium"]),
|
|
14392
|
-
userDataDir:
|
|
14578
|
+
userDataDir: path10.join(os.homedir(), "Library", "Application Support", "Chromium")
|
|
14393
14579
|
}
|
|
14394
14580
|
];
|
|
14395
14581
|
}
|
|
14396
14582
|
if (process.platform === "win32") {
|
|
14397
14583
|
const programFiles = process.env.PROGRAMFILES ?? "C:\\Program Files";
|
|
14398
14584
|
const programFilesX86 = process.env["PROGRAMFILES(X86)"] ?? "C:\\Program Files (x86)";
|
|
14399
|
-
const localAppData = process.env.LOCALAPPDATA ??
|
|
14585
|
+
const localAppData = process.env.LOCALAPPDATA ?? path10.join(os.homedir(), "AppData", "Local");
|
|
14400
14586
|
return [
|
|
14401
14587
|
{
|
|
14402
14588
|
brand: "chrome",
|
|
14403
14589
|
executablePath: firstExistingPath([
|
|
14404
|
-
|
|
14405
|
-
|
|
14406
|
-
|
|
14590
|
+
path10.join(programFiles, "Google", "Chrome", "Application", "chrome.exe"),
|
|
14591
|
+
path10.join(programFilesX86, "Google", "Chrome", "Application", "chrome.exe"),
|
|
14592
|
+
path10.join(localAppData, "Google", "Chrome", "Application", "chrome.exe")
|
|
14407
14593
|
]),
|
|
14408
|
-
userDataDir:
|
|
14594
|
+
userDataDir: path10.join(localAppData, "Google", "Chrome", "User Data")
|
|
14409
14595
|
},
|
|
14410
14596
|
{
|
|
14411
14597
|
brand: "chromium",
|
|
14412
14598
|
executablePath: firstExistingPath([
|
|
14413
|
-
|
|
14414
|
-
|
|
14415
|
-
|
|
14599
|
+
path10.join(programFiles, "Chromium", "Application", "chrome.exe"),
|
|
14600
|
+
path10.join(programFilesX86, "Chromium", "Application", "chrome.exe"),
|
|
14601
|
+
path10.join(localAppData, "Chromium", "Application", "chrome.exe")
|
|
14416
14602
|
]),
|
|
14417
|
-
userDataDir:
|
|
14603
|
+
userDataDir: path10.join(localAppData, "Chromium", "User Data")
|
|
14418
14604
|
}
|
|
14419
14605
|
];
|
|
14420
14606
|
}
|
|
@@ -14427,7 +14613,7 @@ function detectLocalChromeInstallations() {
|
|
|
14427
14613
|
resolveBinaryFromPath("google-chrome"),
|
|
14428
14614
|
resolveBinaryFromPath("google-chrome-stable")
|
|
14429
14615
|
]),
|
|
14430
|
-
userDataDir:
|
|
14616
|
+
userDataDir: path10.join(os.homedir(), ".config", "google-chrome")
|
|
14431
14617
|
},
|
|
14432
14618
|
{
|
|
14433
14619
|
brand: "chromium",
|
|
@@ -14437,7 +14623,7 @@ function detectLocalChromeInstallations() {
|
|
|
14437
14623
|
resolveBinaryFromPath("chromium"),
|
|
14438
14624
|
resolveBinaryFromPath("chromium-browser")
|
|
14439
14625
|
]),
|
|
14440
|
-
userDataDir:
|
|
14626
|
+
userDataDir: path10.join(os.homedir(), ".config", "chromium")
|
|
14441
14627
|
}
|
|
14442
14628
|
];
|
|
14443
14629
|
}
|
|
@@ -14449,8 +14635,8 @@ function detectLocalBrowserInstallations() {
|
|
|
14449
14635
|
}));
|
|
14450
14636
|
}
|
|
14451
14637
|
function listLocalChromeProfiles(userDataDir = resolveChromeUserDataDir()) {
|
|
14452
|
-
const resolvedUserDataDir =
|
|
14453
|
-
const localStatePath =
|
|
14638
|
+
const resolvedUserDataDir = path10.resolve(expandHome(userDataDir));
|
|
14639
|
+
const localStatePath = path10.join(resolvedUserDataDir, "Local State");
|
|
14454
14640
|
if (!fs.existsSync(localStatePath)) {
|
|
14455
14641
|
return [];
|
|
14456
14642
|
}
|
|
@@ -14462,7 +14648,7 @@ function listLocalChromeProfiles(userDataDir = resolveChromeUserDataDir()) {
|
|
|
14462
14648
|
}
|
|
14463
14649
|
return Object.entries(infoCache).map(([directory, info]) => {
|
|
14464
14650
|
const record = info && typeof info === "object" && !Array.isArray(info) ? info : {};
|
|
14465
|
-
const name = typeof record.name === "string" && record.name.trim().length > 0 ? record.name.trim() : directory ||
|
|
14651
|
+
const name = typeof record.name === "string" && record.name.trim().length > 0 ? record.name.trim() : directory || path10.basename(directory);
|
|
14466
14652
|
return {
|
|
14467
14653
|
directory,
|
|
14468
14654
|
name,
|
|
@@ -14474,7 +14660,7 @@ function listLocalChromeProfiles(userDataDir = resolveChromeUserDataDir()) {
|
|
|
14474
14660
|
}
|
|
14475
14661
|
}
|
|
14476
14662
|
function readDevToolsActivePort(userDataDir) {
|
|
14477
|
-
const devToolsPath =
|
|
14663
|
+
const devToolsPath = path10.join(userDataDir, "DevToolsActivePort");
|
|
14478
14664
|
if (!fs.existsSync(devToolsPath)) {
|
|
14479
14665
|
return null;
|
|
14480
14666
|
}
|
|
@@ -14707,8 +14893,8 @@ function buildBrowserWebSocketUrl(httpUrl, webSocketPath) {
|
|
|
14707
14893
|
const protocol = httpUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
14708
14894
|
return `${protocol}//${httpUrl.host}${normalizeWebSocketPath(webSocketPath)}`;
|
|
14709
14895
|
}
|
|
14710
|
-
function normalizeWebSocketPath(
|
|
14711
|
-
return
|
|
14896
|
+
function normalizeWebSocketPath(path18) {
|
|
14897
|
+
return path18.startsWith("/") ? path18 : `/${path18}`;
|
|
14712
14898
|
}
|
|
14713
14899
|
function rewriteBrowserWebSocketHost(browserWsUrl, requestedUrl) {
|
|
14714
14900
|
try {
|
|
@@ -14754,20 +14940,20 @@ var SESSION_SKIPPED_PROFILE_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
|
14754
14940
|
"Network"
|
|
14755
14941
|
]);
|
|
14756
14942
|
async function createBrowserProfileSnapshot(input) {
|
|
14757
|
-
const sourceUserDataDir =
|
|
14758
|
-
const targetUserDataDir =
|
|
14943
|
+
const sourceUserDataDir = path10.resolve(expandHome(input.sourceUserDataDir));
|
|
14944
|
+
const targetUserDataDir = path10.resolve(expandHome(input.targetUserDataDir));
|
|
14759
14945
|
const profileDirectory = input.profileDirectory?.trim();
|
|
14760
14946
|
const copyMode = input.copyMode;
|
|
14761
14947
|
await promises.mkdir(targetUserDataDir, { recursive: true });
|
|
14762
14948
|
await clearChromeSingletonEntries(targetUserDataDir);
|
|
14763
14949
|
if (profileDirectory) {
|
|
14764
|
-
const sourceProfileDir =
|
|
14950
|
+
const sourceProfileDir = path10.join(sourceUserDataDir, profileDirectory);
|
|
14765
14951
|
if (!fs.existsSync(sourceProfileDir)) {
|
|
14766
14952
|
throw new Error(
|
|
14767
14953
|
`Chrome profile "${profileDirectory}" was not found in "${sourceUserDataDir}".`
|
|
14768
14954
|
);
|
|
14769
14955
|
}
|
|
14770
|
-
await promises.cp(sourceProfileDir,
|
|
14956
|
+
await promises.cp(sourceProfileDir, path10.join(targetUserDataDir, profileDirectory), {
|
|
14771
14957
|
recursive: true,
|
|
14772
14958
|
filter: (candidate) => shouldCopyEntry({
|
|
14773
14959
|
candidatePath: candidate,
|
|
@@ -14791,8 +14977,8 @@ async function copyRootLevelEntries(input) {
|
|
|
14791
14977
|
if (CHROME_SINGLETON_ENTRIES.has(entry) || entry === input.selectedProfileDirectory) {
|
|
14792
14978
|
continue;
|
|
14793
14979
|
}
|
|
14794
|
-
const sourcePath =
|
|
14795
|
-
const targetPath =
|
|
14980
|
+
const sourcePath = path10.join(input.sourceUserDataDir, entry);
|
|
14981
|
+
const targetPath = path10.join(input.targetUserDataDir, entry);
|
|
14796
14982
|
const entryStat = await promises.stat(sourcePath).catch(() => null);
|
|
14797
14983
|
if (!entryStat) {
|
|
14798
14984
|
continue;
|
|
@@ -14824,7 +15010,7 @@ async function copyRootLevelEntries(input) {
|
|
|
14824
15010
|
}
|
|
14825
15011
|
}
|
|
14826
15012
|
function isProfileDirectory(userDataDir, entry) {
|
|
14827
|
-
return fs.existsSync(
|
|
15013
|
+
return fs.existsSync(path10.join(userDataDir, entry, "Preferences"));
|
|
14828
15014
|
}
|
|
14829
15015
|
function shouldCopyEntry(input) {
|
|
14830
15016
|
const entryName = input.candidatePath.split("/").at(-1)?.split("\\").at(-1) ?? input.candidatePath;
|
|
@@ -14834,7 +15020,7 @@ function shouldCopyEntry(input) {
|
|
|
14834
15020
|
if (input.copyMode !== "session") {
|
|
14835
15021
|
return true;
|
|
14836
15022
|
}
|
|
14837
|
-
const relativePath =
|
|
15023
|
+
const relativePath = path10.relative(input.rootPath, input.candidatePath);
|
|
14838
15024
|
if (relativePath.length === 0) {
|
|
14839
15025
|
return true;
|
|
14840
15026
|
}
|
|
@@ -15316,7 +15502,7 @@ function pickStealthProfilePreset(overrides) {
|
|
|
15316
15502
|
var OPENSTEER_LIVE_SESSION_LAYOUT = "opensteer-session";
|
|
15317
15503
|
var OPENSTEER_LIVE_SESSION_VERSION = 1;
|
|
15318
15504
|
function resolveLiveSessionRecordPath(rootPath, provider) {
|
|
15319
|
-
return
|
|
15505
|
+
return path10__default.default.join(rootPath, "live", provider === "local" ? "local.json" : "cloud.json");
|
|
15320
15506
|
}
|
|
15321
15507
|
function resolveLocalSessionRecordPath(rootPath) {
|
|
15322
15508
|
return resolveLiveSessionRecordPath(rootPath, "local");
|
|
@@ -15336,27 +15522,467 @@ async function readPersistedSessionRecord(rootPath, provider) {
|
|
|
15336
15522
|
if (provider === "cloud" && isPersistedCloudSessionRecord(parsed)) {
|
|
15337
15523
|
return parsed;
|
|
15338
15524
|
}
|
|
15339
|
-
return void 0;
|
|
15525
|
+
return void 0;
|
|
15526
|
+
}
|
|
15527
|
+
async function readPersistedCloudSessionRecord(rootPath) {
|
|
15528
|
+
const record = await readPersistedSessionRecord(rootPath, "cloud");
|
|
15529
|
+
return record?.provider === "cloud" ? record : void 0;
|
|
15530
|
+
}
|
|
15531
|
+
async function readPersistedLocalBrowserSessionRecord(rootPath) {
|
|
15532
|
+
const record = await readPersistedSessionRecord(rootPath, "local");
|
|
15533
|
+
return record?.provider === "local" ? record : void 0;
|
|
15534
|
+
}
|
|
15535
|
+
async function writePersistedSessionRecord(rootPath, record) {
|
|
15536
|
+
await writeJsonFileAtomic(resolveLiveSessionRecordPath(rootPath, record.provider), record);
|
|
15537
|
+
}
|
|
15538
|
+
async function clearPersistedSessionRecord(rootPath, provider) {
|
|
15539
|
+
await promises.rm(resolveLiveSessionRecordPath(rootPath, provider), { force: true });
|
|
15540
|
+
}
|
|
15541
|
+
function isPersistedCloudSessionRecord(value) {
|
|
15542
|
+
return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "cloud" && typeof value.sessionId === "string" && value.sessionId.length > 0 && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt);
|
|
15543
|
+
}
|
|
15544
|
+
function isPersistedLocalBrowserSessionRecord(value) {
|
|
15545
|
+
return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "local" && (value.engine === "playwright" || value.engine === "abp") && typeof value.pid === "number" && Number.isFinite(value.pid) && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) && typeof value.userDataDir === "string" && value.userDataDir.length > 0;
|
|
15546
|
+
}
|
|
15547
|
+
function resolveOpensteerStateDir() {
|
|
15548
|
+
const explicit = process.env.OPENSTEER_HOME?.trim();
|
|
15549
|
+
if (explicit) {
|
|
15550
|
+
return path10__default.default.resolve(explicit);
|
|
15551
|
+
}
|
|
15552
|
+
if (process.platform === "win32") {
|
|
15553
|
+
return path10__default.default.join(
|
|
15554
|
+
process.env.LOCALAPPDATA ?? path10__default.default.join(os.homedir(), "AppData", "Local"),
|
|
15555
|
+
"Opensteer"
|
|
15556
|
+
);
|
|
15557
|
+
}
|
|
15558
|
+
if (process.platform === "darwin") {
|
|
15559
|
+
return path10__default.default.join(os.homedir(), "Library", "Application Support", "Opensteer");
|
|
15560
|
+
}
|
|
15561
|
+
return path10__default.default.join(
|
|
15562
|
+
process.env.XDG_STATE_HOME ?? path10__default.default.join(os.homedir(), ".local", "state"),
|
|
15563
|
+
"opensteer"
|
|
15564
|
+
);
|
|
15565
|
+
}
|
|
15566
|
+
function resolveLocalViewRootDir() {
|
|
15567
|
+
return path10__default.default.join(resolveOpensteerStateDir(), "local-view");
|
|
15568
|
+
}
|
|
15569
|
+
function resolveLocalViewPreferencesPath() {
|
|
15570
|
+
return path10__default.default.join(resolveLocalViewRootDir(), "preferences.json");
|
|
15571
|
+
}
|
|
15572
|
+
function resolveLocalViewServiceDir() {
|
|
15573
|
+
return path10__default.default.join(resolveLocalViewRootDir(), "service");
|
|
15574
|
+
}
|
|
15575
|
+
function resolveLocalViewSessionsDir() {
|
|
15576
|
+
return path10__default.default.join(resolveLocalViewRootDir(), "sessions");
|
|
15577
|
+
}
|
|
15578
|
+
function resolveLocalViewServiceLockDir() {
|
|
15579
|
+
return path10__default.default.join(resolveLocalViewServiceDir(), "startup.lock");
|
|
15580
|
+
}
|
|
15581
|
+
function resolveLocalViewServiceStatePath() {
|
|
15582
|
+
return path10__default.default.join(resolveLocalViewServiceDir(), "state.json");
|
|
15583
|
+
}
|
|
15584
|
+
|
|
15585
|
+
// src/local-view/preferences.ts
|
|
15586
|
+
var OPENSTEER_LOCAL_VIEW_PREFERENCES_LAYOUT = "opensteer-local-view-preferences";
|
|
15587
|
+
var OPENSTEER_LOCAL_VIEW_PREFERENCES_VERSION = 1;
|
|
15588
|
+
async function resolveLocalViewMode() {
|
|
15589
|
+
const preferences = await readLocalViewPreferences();
|
|
15590
|
+
return preferences?.mode ?? "auto";
|
|
15591
|
+
}
|
|
15592
|
+
async function readLocalViewPreferences() {
|
|
15593
|
+
const preferencesPath = resolveLocalViewPreferencesPath();
|
|
15594
|
+
if (!await pathExists(preferencesPath)) {
|
|
15595
|
+
return void 0;
|
|
15596
|
+
}
|
|
15597
|
+
const parsed = await readJsonFile(preferencesPath);
|
|
15598
|
+
return isPersistedLocalViewPreferences(parsed) ? parsed : void 0;
|
|
15599
|
+
}
|
|
15600
|
+
function isPersistedLocalViewPreferences(value) {
|
|
15601
|
+
return value?.layout === OPENSTEER_LOCAL_VIEW_PREFERENCES_LAYOUT && value.version === OPENSTEER_LOCAL_VIEW_PREFERENCES_VERSION && (value.mode === "auto" || value.mode === "manual") && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt);
|
|
15602
|
+
}
|
|
15603
|
+
var LOCK_OWNER_FILE = "owner.json";
|
|
15604
|
+
var LOCK_RECLAIMER_DIR = "reclaimer";
|
|
15605
|
+
var LOCK_RETRY_DELAY_MS = 50;
|
|
15606
|
+
async function acquireDirLock(lockDirPath) {
|
|
15607
|
+
while (true) {
|
|
15608
|
+
const releaseLock = await tryAcquireDirLock(lockDirPath);
|
|
15609
|
+
if (releaseLock) {
|
|
15610
|
+
return releaseLock;
|
|
15611
|
+
}
|
|
15612
|
+
await sleep(LOCK_RETRY_DELAY_MS);
|
|
15613
|
+
}
|
|
15614
|
+
}
|
|
15615
|
+
async function tryAcquireDirLock(lockDirPath) {
|
|
15616
|
+
await promises.mkdir(path10.dirname(lockDirPath), { recursive: true });
|
|
15617
|
+
while (true) {
|
|
15618
|
+
const tempLockDirPath = `${lockDirPath}-${String(process.pid)}-${String(CURRENT_PROCESS_OWNER.processStartedAtMs)}-${crypto.randomUUID()}`;
|
|
15619
|
+
try {
|
|
15620
|
+
await promises.mkdir(tempLockDirPath);
|
|
15621
|
+
await writeLockOwner(tempLockDirPath, CURRENT_PROCESS_OWNER);
|
|
15622
|
+
try {
|
|
15623
|
+
await promises.rename(tempLockDirPath, lockDirPath);
|
|
15624
|
+
break;
|
|
15625
|
+
} catch (error) {
|
|
15626
|
+
if (!wasDirPublishedByAnotherProcess(error, lockDirPath)) {
|
|
15627
|
+
throw error;
|
|
15628
|
+
}
|
|
15629
|
+
}
|
|
15630
|
+
} finally {
|
|
15631
|
+
await promises.rm(tempLockDirPath, {
|
|
15632
|
+
recursive: true,
|
|
15633
|
+
force: true
|
|
15634
|
+
}).catch(() => void 0);
|
|
15635
|
+
}
|
|
15636
|
+
const owner = await readLockOwner(lockDirPath);
|
|
15637
|
+
if ((!owner || await getProcessLiveness(owner) === "dead") && await tryReclaimStaleLock(lockDirPath, owner)) {
|
|
15638
|
+
continue;
|
|
15639
|
+
}
|
|
15640
|
+
return null;
|
|
15641
|
+
}
|
|
15642
|
+
return async () => {
|
|
15643
|
+
await promises.rm(lockDirPath, {
|
|
15644
|
+
recursive: true,
|
|
15645
|
+
force: true
|
|
15646
|
+
}).catch(() => void 0);
|
|
15647
|
+
};
|
|
15648
|
+
}
|
|
15649
|
+
function getErrorCode(error) {
|
|
15650
|
+
return typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
15651
|
+
}
|
|
15652
|
+
function wasDirPublishedByAnotherProcess(error, targetDirPath) {
|
|
15653
|
+
const code = getErrorCode(error);
|
|
15654
|
+
return fs.existsSync(targetDirPath) && (code === "EEXIST" || code === "ENOTEMPTY" || code === "EPERM");
|
|
15655
|
+
}
|
|
15656
|
+
async function writeLockOwner(lockDirPath, owner) {
|
|
15657
|
+
await promises.writeFile(path10.join(lockDirPath, LOCK_OWNER_FILE), JSON.stringify(owner));
|
|
15658
|
+
}
|
|
15659
|
+
async function readLockOwner(lockDirPath) {
|
|
15660
|
+
return readLockParticipant(path10.join(lockDirPath, LOCK_OWNER_FILE));
|
|
15661
|
+
}
|
|
15662
|
+
async function readLockParticipant(filePath) {
|
|
15663
|
+
return (await readLockParticipantRecord(filePath)).owner;
|
|
15664
|
+
}
|
|
15665
|
+
async function readLockParticipantRecord(filePath) {
|
|
15666
|
+
try {
|
|
15667
|
+
const raw = await promises.readFile(filePath, "utf8");
|
|
15668
|
+
return {
|
|
15669
|
+
exists: true,
|
|
15670
|
+
owner: parseProcessOwner(JSON.parse(raw))
|
|
15671
|
+
};
|
|
15672
|
+
} catch (error) {
|
|
15673
|
+
return {
|
|
15674
|
+
exists: getErrorCode(error) !== "ENOENT",
|
|
15675
|
+
owner: null
|
|
15676
|
+
};
|
|
15677
|
+
}
|
|
15678
|
+
}
|
|
15679
|
+
async function readLockReclaimerRecord(lockDirPath) {
|
|
15680
|
+
return readLockParticipantRecord(path10.join(buildLockReclaimerDirPath(lockDirPath), LOCK_OWNER_FILE));
|
|
15681
|
+
}
|
|
15682
|
+
async function tryReclaimStaleLock(lockDirPath, expectedOwner) {
|
|
15683
|
+
if (!await tryAcquireLockReclaimer(lockDirPath)) {
|
|
15684
|
+
return false;
|
|
15685
|
+
}
|
|
15686
|
+
let reclaimed = false;
|
|
15687
|
+
try {
|
|
15688
|
+
const owner = await readLockOwner(lockDirPath);
|
|
15689
|
+
if (!processOwnersEqual(owner, expectedOwner)) {
|
|
15690
|
+
return false;
|
|
15691
|
+
}
|
|
15692
|
+
if (owner && await getProcessLiveness(owner) !== "dead") {
|
|
15693
|
+
return false;
|
|
15694
|
+
}
|
|
15695
|
+
await promises.rm(lockDirPath, {
|
|
15696
|
+
recursive: true,
|
|
15697
|
+
force: true
|
|
15698
|
+
}).catch(() => void 0);
|
|
15699
|
+
reclaimed = !fs.existsSync(lockDirPath);
|
|
15700
|
+
return reclaimed;
|
|
15701
|
+
} finally {
|
|
15702
|
+
if (!reclaimed) {
|
|
15703
|
+
await promises.rm(buildLockReclaimerDirPath(lockDirPath), {
|
|
15704
|
+
recursive: true,
|
|
15705
|
+
force: true
|
|
15706
|
+
}).catch(() => void 0);
|
|
15707
|
+
}
|
|
15708
|
+
}
|
|
15709
|
+
}
|
|
15710
|
+
async function tryAcquireLockReclaimer(lockDirPath) {
|
|
15711
|
+
const reclaimerDirPath = buildLockReclaimerDirPath(lockDirPath);
|
|
15712
|
+
while (true) {
|
|
15713
|
+
const tempReclaimerDirPath = `${reclaimerDirPath}-${String(process.pid)}-${String(CURRENT_PROCESS_OWNER.processStartedAtMs)}-${crypto.randomUUID()}`;
|
|
15714
|
+
try {
|
|
15715
|
+
await promises.mkdir(tempReclaimerDirPath);
|
|
15716
|
+
await writeLockOwner(tempReclaimerDirPath, CURRENT_PROCESS_OWNER);
|
|
15717
|
+
try {
|
|
15718
|
+
await promises.rename(tempReclaimerDirPath, reclaimerDirPath);
|
|
15719
|
+
return true;
|
|
15720
|
+
} catch (error) {
|
|
15721
|
+
if (getErrorCode(error) === "ENOENT") {
|
|
15722
|
+
return false;
|
|
15723
|
+
}
|
|
15724
|
+
if (!wasDirPublishedByAnotherProcess(error, reclaimerDirPath)) {
|
|
15725
|
+
throw error;
|
|
15726
|
+
}
|
|
15727
|
+
}
|
|
15728
|
+
} catch (error) {
|
|
15729
|
+
if (getErrorCode(error) === "ENOENT") {
|
|
15730
|
+
return false;
|
|
15731
|
+
}
|
|
15732
|
+
throw error;
|
|
15733
|
+
} finally {
|
|
15734
|
+
await promises.rm(tempReclaimerDirPath, {
|
|
15735
|
+
recursive: true,
|
|
15736
|
+
force: true
|
|
15737
|
+
}).catch(() => void 0);
|
|
15738
|
+
}
|
|
15739
|
+
const reclaimerRecord = await readLockReclaimerRecord(lockDirPath);
|
|
15740
|
+
if (!reclaimerRecord.exists || !reclaimerRecord.owner) {
|
|
15741
|
+
return false;
|
|
15742
|
+
}
|
|
15743
|
+
if (await getProcessLiveness(reclaimerRecord.owner) !== "dead") {
|
|
15744
|
+
return false;
|
|
15745
|
+
}
|
|
15746
|
+
await promises.rm(reclaimerDirPath, {
|
|
15747
|
+
recursive: true,
|
|
15748
|
+
force: true
|
|
15749
|
+
}).catch(() => void 0);
|
|
15750
|
+
}
|
|
15751
|
+
}
|
|
15752
|
+
function buildLockReclaimerDirPath(lockDirPath) {
|
|
15753
|
+
return path10.join(lockDirPath, LOCK_RECLAIMER_DIR);
|
|
15754
|
+
}
|
|
15755
|
+
async function sleep(ms) {
|
|
15756
|
+
await new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
15757
|
+
}
|
|
15758
|
+
var OPENSTEER_LOCAL_VIEW_SERVICE_LAYOUT = "opensteer-local-view-service";
|
|
15759
|
+
var OPENSTEER_LOCAL_VIEW_SERVICE_VERSION = 3;
|
|
15760
|
+
async function readLocalViewServiceState() {
|
|
15761
|
+
const statePath = resolveLocalViewServiceStatePath();
|
|
15762
|
+
if (!await pathExists(statePath)) {
|
|
15763
|
+
return void 0;
|
|
15764
|
+
}
|
|
15765
|
+
const parsed = await readJsonFile(statePath);
|
|
15766
|
+
if (!isPersistedLocalViewServiceState(parsed)) {
|
|
15767
|
+
return void 0;
|
|
15768
|
+
}
|
|
15769
|
+
return parsed;
|
|
15770
|
+
}
|
|
15771
|
+
async function isLocalViewServiceStateLive(state) {
|
|
15772
|
+
return await getLocalViewServiceStateLiveness(state) !== "dead";
|
|
15773
|
+
}
|
|
15774
|
+
async function getLocalViewServiceStateLiveness(state) {
|
|
15775
|
+
if (state === void 0) {
|
|
15776
|
+
return "dead";
|
|
15777
|
+
}
|
|
15778
|
+
return getProcessLiveness({
|
|
15779
|
+
pid: state.pid,
|
|
15780
|
+
processStartedAtMs: state.processStartedAtMs
|
|
15781
|
+
});
|
|
15782
|
+
}
|
|
15783
|
+
function isPersistedLocalViewServiceState(value) {
|
|
15784
|
+
return value?.layout === OPENSTEER_LOCAL_VIEW_SERVICE_LAYOUT && value.version === OPENSTEER_LOCAL_VIEW_SERVICE_VERSION && typeof value.pid === "number" && Number.isFinite(value.pid) && typeof value.processStartedAtMs === "number" && Number.isFinite(value.processStartedAtMs) && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.port === "number" && Number.isFinite(value.port) && typeof value.token === "string" && value.token.length > 0 && typeof value.url === "string" && value.url.length > 0;
|
|
15785
|
+
}
|
|
15786
|
+
|
|
15787
|
+
// src/local-view/service.ts
|
|
15788
|
+
var LOCAL_VIEW_STARTUP_TIMEOUT_MS = 1e4;
|
|
15789
|
+
var LOCAL_VIEW_STARTUP_POLL_MS = 100;
|
|
15790
|
+
async function ensureLocalViewServiceRunning() {
|
|
15791
|
+
const current = await readReachableLocalViewServiceState();
|
|
15792
|
+
if (current !== void 0) {
|
|
15793
|
+
return current;
|
|
15794
|
+
}
|
|
15795
|
+
const releaseLock = await acquireDirLock(resolveLocalViewServiceLockDir());
|
|
15796
|
+
try {
|
|
15797
|
+
const lockedState = await readReachableLocalViewServiceState();
|
|
15798
|
+
if (lockedState !== void 0) {
|
|
15799
|
+
return lockedState;
|
|
15800
|
+
}
|
|
15801
|
+
await spawnLocalViewService();
|
|
15802
|
+
const started = await waitForLocalViewService();
|
|
15803
|
+
if (!started) {
|
|
15804
|
+
throw new Error("Timed out while starting the local view service.");
|
|
15805
|
+
}
|
|
15806
|
+
return started;
|
|
15807
|
+
} finally {
|
|
15808
|
+
await releaseLock();
|
|
15809
|
+
}
|
|
15810
|
+
}
|
|
15811
|
+
function spawnLocalViewService() {
|
|
15812
|
+
const command = resolveLocalViewSpawnCommand();
|
|
15813
|
+
const child = child_process.spawn(command.executable, command.args, {
|
|
15814
|
+
cwd: process.cwd(),
|
|
15815
|
+
env: {
|
|
15816
|
+
...process.env,
|
|
15817
|
+
...command.env ?? {},
|
|
15818
|
+
OPENSTEER_LOCAL_VIEW_BOOT_TOKEN: process.env.OPENSTEER_LOCAL_VIEW_BOOT_TOKEN ?? crypto.randomBytes(24).toString("hex")
|
|
15819
|
+
},
|
|
15820
|
+
detached: process.platform !== "win32",
|
|
15821
|
+
stdio: "ignore"
|
|
15822
|
+
});
|
|
15823
|
+
child.unref();
|
|
15824
|
+
}
|
|
15825
|
+
async function waitForLocalViewService() {
|
|
15826
|
+
const deadline = Date.now() + LOCAL_VIEW_STARTUP_TIMEOUT_MS;
|
|
15827
|
+
while (Date.now() < deadline) {
|
|
15828
|
+
const state = await readReachableLocalViewServiceState();
|
|
15829
|
+
if (state !== void 0) {
|
|
15830
|
+
return state;
|
|
15831
|
+
}
|
|
15832
|
+
await delay(LOCAL_VIEW_STARTUP_POLL_MS);
|
|
15833
|
+
}
|
|
15834
|
+
return void 0;
|
|
15835
|
+
}
|
|
15836
|
+
async function readReachableLocalViewServiceState() {
|
|
15837
|
+
const state = await readLocalViewServiceState();
|
|
15838
|
+
if (state === void 0 || !await isLocalViewServiceStateLive(state)) {
|
|
15839
|
+
return void 0;
|
|
15840
|
+
}
|
|
15841
|
+
return await isLocalViewServiceReachable(state.url, state.token) ? state : void 0;
|
|
15842
|
+
}
|
|
15843
|
+
async function isLocalViewServiceReachable(baseUrl, token) {
|
|
15844
|
+
try {
|
|
15845
|
+
const response = await fetch(new URL("/api/health", baseUrl), {
|
|
15846
|
+
headers: {
|
|
15847
|
+
"x-opensteer-local-token": token
|
|
15848
|
+
}
|
|
15849
|
+
});
|
|
15850
|
+
return response.ok;
|
|
15851
|
+
} catch {
|
|
15852
|
+
return false;
|
|
15853
|
+
}
|
|
15854
|
+
}
|
|
15855
|
+
function resolveLocalViewSpawnCommand() {
|
|
15856
|
+
const moduleDir = path10__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
|
|
15857
|
+
const distServicePath = findExistingPath([
|
|
15858
|
+
path10__default.default.join(moduleDir, "local-view", "serve-entry.js"),
|
|
15859
|
+
path10__default.default.join(moduleDir, "serve-entry.js"),
|
|
15860
|
+
path10__default.default.join(moduleDir, "..", "local-view", "serve-entry.js")
|
|
15861
|
+
]);
|
|
15862
|
+
if (distServicePath) {
|
|
15863
|
+
return {
|
|
15864
|
+
executable: process.execPath,
|
|
15865
|
+
args: [distServicePath]
|
|
15866
|
+
};
|
|
15867
|
+
}
|
|
15868
|
+
const distCliPath = findExistingPath([
|
|
15869
|
+
path10__default.default.join(moduleDir, "cli", "bin.js"),
|
|
15870
|
+
path10__default.default.join(moduleDir, "..", "cli", "bin.js")
|
|
15871
|
+
]);
|
|
15872
|
+
if (distCliPath) {
|
|
15873
|
+
return {
|
|
15874
|
+
executable: process.execPath,
|
|
15875
|
+
args: [distCliPath, "view", "serve"]
|
|
15876
|
+
};
|
|
15877
|
+
}
|
|
15878
|
+
const srcServicePath = findExistingPath([
|
|
15879
|
+
path10__default.default.join(moduleDir, "serve-entry.ts"),
|
|
15880
|
+
path10__default.default.join(moduleDir, "..", "local-view", "serve-entry.ts"),
|
|
15881
|
+
path10__default.default.join(moduleDir, "..", "src", "local-view", "serve-entry.ts")
|
|
15882
|
+
]);
|
|
15883
|
+
if (srcServicePath) {
|
|
15884
|
+
const require2 = 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)));
|
|
15885
|
+
const tsxLoaderPath = require2.resolve("tsx");
|
|
15886
|
+
const tsconfigPath = findNearestTsconfig(path10__default.default.resolve(moduleDir, "..", "..", ".."));
|
|
15887
|
+
return {
|
|
15888
|
+
executable: process.execPath,
|
|
15889
|
+
args: ["--import", tsxLoaderPath, srcServicePath],
|
|
15890
|
+
...tsconfigPath ? { env: { TSX_TSCONFIG_PATH: tsconfigPath } } : {}
|
|
15891
|
+
};
|
|
15892
|
+
}
|
|
15893
|
+
const srcCliPath = findExistingPath([
|
|
15894
|
+
path10__default.default.join(moduleDir, "..", "cli", "bin.ts"),
|
|
15895
|
+
path10__default.default.join(moduleDir, "..", "src", "cli", "bin.ts")
|
|
15896
|
+
]);
|
|
15897
|
+
if (srcCliPath) {
|
|
15898
|
+
const require2 = 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)));
|
|
15899
|
+
const tsxLoaderPath = require2.resolve("tsx");
|
|
15900
|
+
const tsconfigPath = findNearestTsconfig(path10__default.default.resolve(moduleDir, "..", "..", ".."));
|
|
15901
|
+
return {
|
|
15902
|
+
executable: process.execPath,
|
|
15903
|
+
args: ["--import", tsxLoaderPath, srcCliPath, "view", "serve"],
|
|
15904
|
+
...tsconfigPath ? { env: { TSX_TSCONFIG_PATH: tsconfigPath } } : {}
|
|
15905
|
+
};
|
|
15906
|
+
}
|
|
15907
|
+
throw new Error(`Could not resolve the Opensteer CLI entrypoint from ${moduleDir}.`);
|
|
15908
|
+
}
|
|
15909
|
+
function findExistingPath(candidates) {
|
|
15910
|
+
return candidates.find((candidate) => fs.existsSync(candidate));
|
|
15911
|
+
}
|
|
15912
|
+
function findNearestTsconfig(startDir) {
|
|
15913
|
+
let currentDir = startDir;
|
|
15914
|
+
while (true) {
|
|
15915
|
+
const candidate = path10__default.default.join(currentDir, "tsconfig.json");
|
|
15916
|
+
if (fs.existsSync(candidate)) {
|
|
15917
|
+
return candidate;
|
|
15918
|
+
}
|
|
15919
|
+
const parentDir = path10__default.default.dirname(currentDir);
|
|
15920
|
+
if (parentDir === currentDir) {
|
|
15921
|
+
return void 0;
|
|
15922
|
+
}
|
|
15923
|
+
currentDir = parentDir;
|
|
15924
|
+
}
|
|
15340
15925
|
}
|
|
15341
|
-
|
|
15342
|
-
|
|
15343
|
-
|
|
15926
|
+
function delay(ms) {
|
|
15927
|
+
return new Promise((resolve4) => {
|
|
15928
|
+
setTimeout(resolve4, ms);
|
|
15929
|
+
});
|
|
15344
15930
|
}
|
|
15345
|
-
|
|
15346
|
-
|
|
15347
|
-
|
|
15931
|
+
var OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT = "opensteer-local-view-session";
|
|
15932
|
+
var OPENSTEER_LOCAL_VIEW_SESSION_VERSION = 1;
|
|
15933
|
+
function buildLocalViewSessionId(input) {
|
|
15934
|
+
const hash = crypto.createHash("sha256").update(`${input.rootPath}
|
|
15935
|
+
${String(input.pid)}
|
|
15936
|
+
${String(input.startedAt)}`).digest("hex");
|
|
15937
|
+
return `local_${hash.slice(0, 24)}`;
|
|
15348
15938
|
}
|
|
15349
|
-
|
|
15350
|
-
|
|
15939
|
+
function createLocalViewSessionManifest(input) {
|
|
15940
|
+
return {
|
|
15941
|
+
layout: OPENSTEER_LOCAL_VIEW_SESSION_LAYOUT,
|
|
15942
|
+
version: OPENSTEER_LOCAL_VIEW_SESSION_VERSION,
|
|
15943
|
+
sessionId: buildLocalViewSessionId({
|
|
15944
|
+
rootPath: input.rootPath,
|
|
15945
|
+
pid: input.live.pid,
|
|
15946
|
+
startedAt: input.live.startedAt
|
|
15947
|
+
}),
|
|
15948
|
+
rootPath: input.rootPath,
|
|
15949
|
+
...input.workspace === void 0 ? {} : { workspace: input.workspace },
|
|
15950
|
+
engine: input.live.engine,
|
|
15951
|
+
ownership: input.ownership,
|
|
15952
|
+
pid: input.live.pid,
|
|
15953
|
+
startedAt: input.live.startedAt,
|
|
15954
|
+
updatedAt: Date.now()
|
|
15955
|
+
};
|
|
15351
15956
|
}
|
|
15352
|
-
async function
|
|
15353
|
-
await
|
|
15957
|
+
async function writeLocalViewSessionManifest(manifest) {
|
|
15958
|
+
await ensureDirectory(resolveLocalViewSessionsDir());
|
|
15959
|
+
await writeJsonFileAtomic(resolveLocalViewSessionManifestPath(manifest.sessionId), manifest);
|
|
15354
15960
|
}
|
|
15355
|
-
function
|
|
15356
|
-
|
|
15961
|
+
async function deleteLocalViewSessionManifest(sessionId) {
|
|
15962
|
+
await promises.rm(resolveLocalViewSessionManifestPath(sessionId), { force: true }).catch(() => void 0);
|
|
15357
15963
|
}
|
|
15358
|
-
function
|
|
15359
|
-
return
|
|
15964
|
+
function resolveLocalViewSessionManifestPath(sessionId) {
|
|
15965
|
+
return path10__default.default.join(resolveLocalViewSessionsDir(), `${sessionId}.json`);
|
|
15966
|
+
}
|
|
15967
|
+
|
|
15968
|
+
// src/local-view/registration.ts
|
|
15969
|
+
async function bestEffortRegisterLocalViewSession(input) {
|
|
15970
|
+
try {
|
|
15971
|
+
const manifest = createLocalViewSessionManifest(input);
|
|
15972
|
+
await writeLocalViewSessionManifest(manifest);
|
|
15973
|
+
if (await resolveLocalViewMode() === "auto") {
|
|
15974
|
+
void ensureLocalViewServiceRunning().catch(() => void 0);
|
|
15975
|
+
}
|
|
15976
|
+
return manifest;
|
|
15977
|
+
} catch {
|
|
15978
|
+
return void 0;
|
|
15979
|
+
}
|
|
15980
|
+
}
|
|
15981
|
+
async function bestEffortUnregisterLocalViewSession(sessionId) {
|
|
15982
|
+
if (!sessionId) {
|
|
15983
|
+
return;
|
|
15984
|
+
}
|
|
15985
|
+
await deleteLocalViewSessionManifest(sessionId).catch(() => void 0);
|
|
15360
15986
|
}
|
|
15361
15987
|
|
|
15362
15988
|
// ../runtime-core/src/internal/engine-selection.ts
|
|
@@ -15476,8 +16102,8 @@ var OpensteerBrowserManager = class {
|
|
|
15476
16102
|
...options.browser === void 0 ? {} : { browser: options.browser },
|
|
15477
16103
|
...this.contextOptions === void 0 ? {} : { context: this.contextOptions }
|
|
15478
16104
|
});
|
|
15479
|
-
this.rootPath = options.rootPath ?? (this.workspace === void 0 ?
|
|
15480
|
-
rootDir:
|
|
16105
|
+
this.rootPath = options.rootPath ?? (this.workspace === void 0 ? path10__default.default.join(os.tmpdir(), `${TEMPORARY_WORKSPACE_PREFIX}${crypto.randomUUID()}`) : resolveFilesystemWorkspacePath({
|
|
16106
|
+
rootDir: path10__default.default.resolve(options.rootDir ?? process.cwd()),
|
|
15481
16107
|
workspace: this.workspace
|
|
15482
16108
|
}));
|
|
15483
16109
|
this.cleanupRootOnDisconnect = this.workspace === void 0;
|
|
@@ -15538,7 +16164,7 @@ var OpensteerBrowserManager = class {
|
|
|
15538
16164
|
userDataDir: "browser/user-data",
|
|
15539
16165
|
bootstrap: {
|
|
15540
16166
|
kind: "cloneLocalProfile",
|
|
15541
|
-
sourceUserDataDir:
|
|
16167
|
+
sourceUserDataDir: path10__default.default.resolve(input.sourceUserDataDir),
|
|
15542
16168
|
...input.sourceProfileDirectory === void 0 ? {} : { sourceProfileDirectory: input.sourceProfileDirectory }
|
|
15543
16169
|
}
|
|
15544
16170
|
};
|
|
@@ -15611,6 +16237,12 @@ var OpensteerBrowserManager = class {
|
|
|
15611
16237
|
`workspace "${this.workspace}" already has a live ${live.engine} browser. Close it before reopening with engine "abp".`
|
|
15612
16238
|
);
|
|
15613
16239
|
}
|
|
16240
|
+
await bestEffortRegisterLocalViewSession({
|
|
16241
|
+
rootPath: workspace.rootPath,
|
|
16242
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
16243
|
+
live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
|
|
16244
|
+
ownership: "owned"
|
|
16245
|
+
});
|
|
15614
16246
|
return this.createAdoptedAbpEngine(live);
|
|
15615
16247
|
}
|
|
15616
16248
|
await this.ensurePersistentBrowserManifest(workspace);
|
|
@@ -15643,9 +16275,17 @@ var OpensteerBrowserManager = class {
|
|
|
15643
16275
|
...launch?.browserExecutablePath === void 0 ? {} : { executablePath: launch.browserExecutablePath }
|
|
15644
16276
|
};
|
|
15645
16277
|
await this.writeLivePersistentBrowser(workspace, liveRecord);
|
|
16278
|
+
const persistedLiveRecord = toPersistedLocalBrowserSessionRecord(this.workspace, liveRecord);
|
|
16279
|
+
await bestEffortRegisterLocalViewSession({
|
|
16280
|
+
rootPath: workspace.rootPath,
|
|
16281
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
16282
|
+
live: persistedLiveRecord,
|
|
16283
|
+
ownership: "owned"
|
|
16284
|
+
});
|
|
15646
16285
|
try {
|
|
15647
16286
|
return await this.createAdoptedAbpEngine(liveRecord);
|
|
15648
16287
|
} catch (error) {
|
|
16288
|
+
await this.unregisterLocalViewSessionForRecord(workspace.rootPath, persistedLiveRecord);
|
|
15649
16289
|
await terminateProcess(launched.process.pid ?? 0).catch(() => void 0);
|
|
15650
16290
|
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
15651
16291
|
throw error;
|
|
@@ -15665,23 +16305,45 @@ var OpensteerBrowserManager = class {
|
|
|
15665
16305
|
});
|
|
15666
16306
|
}
|
|
15667
16307
|
async createTemporaryEngine() {
|
|
15668
|
-
const userDataDir = await promises.mkdtemp(
|
|
16308
|
+
const userDataDir = await promises.mkdtemp(path10__default.default.join(os.tmpdir(), "opensteer-temporary-browser-"));
|
|
15669
16309
|
await clearChromeSingletonEntries(userDataDir);
|
|
15670
16310
|
const launched = await launchOwnedBrowser({
|
|
15671
16311
|
userDataDir,
|
|
15672
16312
|
...this.launchOptions === void 0 ? {} : { launch: this.launchOptions },
|
|
15673
16313
|
...this.contextOptions?.viewport === void 0 ? {} : { viewport: this.contextOptions.viewport }
|
|
15674
16314
|
});
|
|
16315
|
+
const temporaryLiveRecord = {
|
|
16316
|
+
layout: "opensteer-session",
|
|
16317
|
+
version: 1,
|
|
16318
|
+
provider: "local",
|
|
16319
|
+
engine: "playwright",
|
|
16320
|
+
endpoint: launched.endpoint,
|
|
16321
|
+
pid: launched.pid,
|
|
16322
|
+
startedAt: Date.now(),
|
|
16323
|
+
updatedAt: Date.now(),
|
|
16324
|
+
executablePath: launched.executablePath,
|
|
16325
|
+
userDataDir
|
|
16326
|
+
};
|
|
16327
|
+
await writePersistedSessionRecord(this.rootPath, temporaryLiveRecord);
|
|
16328
|
+
const localViewManifest = await bestEffortRegisterLocalViewSession({
|
|
16329
|
+
rootPath: this.rootPath,
|
|
16330
|
+
live: temporaryLiveRecord,
|
|
16331
|
+
ownership: "owned"
|
|
16332
|
+
});
|
|
15675
16333
|
try {
|
|
15676
16334
|
return await this.createAttachedEngine({
|
|
15677
16335
|
endpoint: launched.endpoint,
|
|
15678
16336
|
freshTab: false,
|
|
15679
16337
|
onDispose: async () => {
|
|
16338
|
+
await bestEffortUnregisterLocalViewSession(localViewManifest?.sessionId);
|
|
16339
|
+
await clearPersistedSessionRecord(this.rootPath, "local").catch(() => void 0);
|
|
15680
16340
|
await terminateProcess(launched.pid).catch(() => void 0);
|
|
15681
16341
|
await promises.rm(userDataDir, { recursive: true, force: true }).catch(() => void 0);
|
|
15682
16342
|
}
|
|
15683
16343
|
});
|
|
15684
16344
|
} catch (error) {
|
|
16345
|
+
await bestEffortUnregisterLocalViewSession(localViewManifest?.sessionId);
|
|
16346
|
+
await clearPersistedSessionRecord(this.rootPath, "local").catch(() => void 0);
|
|
15685
16347
|
await terminateProcess(launched.pid).catch(() => void 0);
|
|
15686
16348
|
await promises.rm(userDataDir, { recursive: true, force: true }).catch(() => void 0);
|
|
15687
16349
|
throw error;
|
|
@@ -15709,6 +16371,12 @@ var OpensteerBrowserManager = class {
|
|
|
15709
16371
|
if (live.endpoint === void 0) {
|
|
15710
16372
|
throw new Error("workspace live browser record is missing a DevTools endpoint.");
|
|
15711
16373
|
}
|
|
16374
|
+
await bestEffortRegisterLocalViewSession({
|
|
16375
|
+
rootPath: workspace.rootPath,
|
|
16376
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
16377
|
+
live: toPersistedLocalBrowserSessionRecord(this.workspace, live),
|
|
16378
|
+
ownership: "owned"
|
|
16379
|
+
});
|
|
15712
16380
|
return this.createAttachedEngine({
|
|
15713
16381
|
endpoint: live.endpoint,
|
|
15714
16382
|
freshTab: false,
|
|
@@ -15731,6 +16399,13 @@ var OpensteerBrowserManager = class {
|
|
|
15731
16399
|
userDataDir: workspace.browserUserDataDir
|
|
15732
16400
|
};
|
|
15733
16401
|
await this.writeLivePersistentBrowser(workspace, liveRecord);
|
|
16402
|
+
const persistedLiveRecord = toPersistedLocalBrowserSessionRecord(this.workspace, liveRecord);
|
|
16403
|
+
await bestEffortRegisterLocalViewSession({
|
|
16404
|
+
rootPath: workspace.rootPath,
|
|
16405
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace },
|
|
16406
|
+
live: persistedLiveRecord,
|
|
16407
|
+
ownership: "owned"
|
|
16408
|
+
});
|
|
15734
16409
|
try {
|
|
15735
16410
|
return await this.createAttachedEngine({
|
|
15736
16411
|
endpoint: launched.endpoint,
|
|
@@ -15738,6 +16413,7 @@ var OpensteerBrowserManager = class {
|
|
|
15738
16413
|
onDispose: async () => void 0
|
|
15739
16414
|
});
|
|
15740
16415
|
} catch (error) {
|
|
16416
|
+
await this.unregisterLocalViewSessionForRecord(workspace.rootPath, persistedLiveRecord);
|
|
15741
16417
|
await terminateProcess(launched.pid).catch(() => void 0);
|
|
15742
16418
|
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
15743
16419
|
throw error;
|
|
@@ -15888,6 +16564,10 @@ var OpensteerBrowserManager = class {
|
|
|
15888
16564
|
await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
|
|
15889
16565
|
return;
|
|
15890
16566
|
}
|
|
16567
|
+
await this.unregisterLocalViewSessionForRecord(
|
|
16568
|
+
workspace.rootPath,
|
|
16569
|
+
toPersistedLocalBrowserSessionRecord(this.workspace, live)
|
|
16570
|
+
);
|
|
15891
16571
|
if (live.engine === "playwright") {
|
|
15892
16572
|
if (live.endpoint !== void 0) {
|
|
15893
16573
|
await requestBrowserClose(live.endpoint).catch(() => void 0);
|
|
@@ -15914,6 +16594,15 @@ var OpensteerBrowserManager = class {
|
|
|
15914
16594
|
throw new Error(`browser.${method}() requires a persistent workspace browser.`);
|
|
15915
16595
|
}
|
|
15916
16596
|
}
|
|
16597
|
+
async unregisterLocalViewSessionForRecord(rootPath, record) {
|
|
16598
|
+
await bestEffortUnregisterLocalViewSession(
|
|
16599
|
+
buildLocalViewSessionId({
|
|
16600
|
+
rootPath,
|
|
16601
|
+
pid: record.pid,
|
|
16602
|
+
startedAt: record.startedAt
|
|
16603
|
+
})
|
|
16604
|
+
);
|
|
16605
|
+
}
|
|
15917
16606
|
};
|
|
15918
16607
|
function normalizeWorkspace(workspace) {
|
|
15919
16608
|
const normalized = workspace?.trim();
|
|
@@ -15977,8 +16666,14 @@ async function launchOwnedBrowser(input) {
|
|
|
15977
16666
|
await ensureDirectory(input.userDataDir);
|
|
15978
16667
|
await clearChromeSingletonEntries(input.userDataDir);
|
|
15979
16668
|
await sanitizeChromeProfile(input.userDataDir);
|
|
16669
|
+
const requestedRemoteDebuggingPort = readRequestedRemoteDebuggingPort(input.launch?.args);
|
|
15980
16670
|
const executablePath = resolveChromeExecutablePath(input.launch?.executablePath);
|
|
15981
|
-
const args = buildChromeArgs(
|
|
16671
|
+
const args = buildChromeArgs(
|
|
16672
|
+
input.userDataDir,
|
|
16673
|
+
input.launch,
|
|
16674
|
+
input.viewport,
|
|
16675
|
+
requestedRemoteDebuggingPort
|
|
16676
|
+
);
|
|
15982
16677
|
const child = child_process.spawn(executablePath, args, {
|
|
15983
16678
|
stdio: ["ignore", "ignore", "pipe"],
|
|
15984
16679
|
detached: process.platform !== "win32"
|
|
@@ -15994,7 +16689,8 @@ async function launchOwnedBrowser(input) {
|
|
|
15994
16689
|
userDataDir: input.userDataDir,
|
|
15995
16690
|
timeoutMs: input.launch?.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
15996
16691
|
childExited: async () => child.exitCode,
|
|
15997
|
-
stderrLines
|
|
16692
|
+
stderrLines,
|
|
16693
|
+
...requestedRemoteDebuggingPort !== void 0 && requestedRemoteDebuggingPort > 0 ? { requestedRemoteDebuggingPort } : {}
|
|
15998
16694
|
}).catch(async (error) => {
|
|
15999
16695
|
child.kill("SIGKILL");
|
|
16000
16696
|
throw error;
|
|
@@ -16005,10 +16701,10 @@ async function launchOwnedBrowser(input) {
|
|
|
16005
16701
|
executablePath
|
|
16006
16702
|
};
|
|
16007
16703
|
}
|
|
16008
|
-
function buildChromeArgs(userDataDir, launch, viewport) {
|
|
16704
|
+
function buildChromeArgs(userDataDir, launch, viewport, requestedRemoteDebuggingPort) {
|
|
16009
16705
|
const isHeadless = launch?.headless ?? true;
|
|
16010
16706
|
const args = [
|
|
16011
|
-
"--remote-debugging-port=0",
|
|
16707
|
+
...requestedRemoteDebuggingPort === void 0 ? ["--remote-debugging-port=0"] : [],
|
|
16012
16708
|
"--no-first-run",
|
|
16013
16709
|
"--no-default-browser-check",
|
|
16014
16710
|
"--disable-blink-features=AutomationControlled",
|
|
@@ -16059,14 +16755,69 @@ async function waitForDevToolsEndpoint(input) {
|
|
|
16059
16755
|
return `ws://127.0.0.1:${String(activePort.port)}${activePort.webSocketPath}`;
|
|
16060
16756
|
}
|
|
16061
16757
|
}
|
|
16758
|
+
if (input.requestedRemoteDebuggingPort !== void 0) {
|
|
16759
|
+
const endpoint = await tryInspectRemoteDebuggingPort(
|
|
16760
|
+
input.requestedRemoteDebuggingPort,
|
|
16761
|
+
input.timeoutMs
|
|
16762
|
+
);
|
|
16763
|
+
if (endpoint !== void 0) {
|
|
16764
|
+
return endpoint;
|
|
16765
|
+
}
|
|
16766
|
+
}
|
|
16062
16767
|
const exitCode = await input.childExited();
|
|
16063
16768
|
if (exitCode !== null) {
|
|
16064
16769
|
throw new Error(formatChromeLaunchError(input.stderrLines));
|
|
16065
16770
|
}
|
|
16066
|
-
await
|
|
16771
|
+
await sleep2(DEVTOOLS_POLL_INTERVAL_MS);
|
|
16067
16772
|
}
|
|
16068
16773
|
throw new Error(formatChromeLaunchError(input.stderrLines));
|
|
16069
16774
|
}
|
|
16775
|
+
function readRequestedRemoteDebuggingPort(args) {
|
|
16776
|
+
if (args === void 0 || args.length === 0) {
|
|
16777
|
+
return void 0;
|
|
16778
|
+
}
|
|
16779
|
+
let explicitFlagFound = false;
|
|
16780
|
+
let port;
|
|
16781
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
16782
|
+
const entry = args[index];
|
|
16783
|
+
if (entry === "--remote-debugging-port") {
|
|
16784
|
+
explicitFlagFound = true;
|
|
16785
|
+
const next = args[index + 1];
|
|
16786
|
+
if (next !== void 0) {
|
|
16787
|
+
port = parseRemoteDebuggingPort(next);
|
|
16788
|
+
index += 1;
|
|
16789
|
+
}
|
|
16790
|
+
continue;
|
|
16791
|
+
}
|
|
16792
|
+
if (entry.startsWith("--remote-debugging-port=")) {
|
|
16793
|
+
explicitFlagFound = true;
|
|
16794
|
+
port = parseRemoteDebuggingPort(entry.slice("--remote-debugging-port=".length));
|
|
16795
|
+
}
|
|
16796
|
+
}
|
|
16797
|
+
return explicitFlagFound ? port : void 0;
|
|
16798
|
+
}
|
|
16799
|
+
function parseRemoteDebuggingPort(value) {
|
|
16800
|
+
const trimmed = value.trim();
|
|
16801
|
+
if (!/^\d+$/.test(trimmed)) {
|
|
16802
|
+
return void 0;
|
|
16803
|
+
}
|
|
16804
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
16805
|
+
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
16806
|
+
return void 0;
|
|
16807
|
+
}
|
|
16808
|
+
return parsed;
|
|
16809
|
+
}
|
|
16810
|
+
async function tryInspectRemoteDebuggingPort(port, timeoutMs) {
|
|
16811
|
+
try {
|
|
16812
|
+
const inspected = await inspectCdpEndpoint({
|
|
16813
|
+
endpoint: `http://127.0.0.1:${String(port)}`,
|
|
16814
|
+
timeoutMs: Math.min(2e3, timeoutMs)
|
|
16815
|
+
});
|
|
16816
|
+
return inspected.endpoint;
|
|
16817
|
+
} catch {
|
|
16818
|
+
return void 0;
|
|
16819
|
+
}
|
|
16820
|
+
}
|
|
16070
16821
|
function formatChromeLaunchError(stderrLines) {
|
|
16071
16822
|
const collapsed = stderrLines.join("").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
16072
16823
|
if (collapsed.length === 0) {
|
|
@@ -16165,12 +16916,12 @@ async function waitForProcessExit(pid, timeoutMs) {
|
|
|
16165
16916
|
if (!isProcessRunning(pid)) {
|
|
16166
16917
|
return true;
|
|
16167
16918
|
}
|
|
16168
|
-
await
|
|
16919
|
+
await sleep2(50);
|
|
16169
16920
|
}
|
|
16170
16921
|
return !isProcessRunning(pid);
|
|
16171
16922
|
}
|
|
16172
16923
|
function resolveAbpSessionDir(workspace) {
|
|
16173
|
-
return
|
|
16924
|
+
return path10__default.default.join(workspace.livePath, "abp-session");
|
|
16174
16925
|
}
|
|
16175
16926
|
async function allocateEphemeralPort() {
|
|
16176
16927
|
const { allocatePort } = await loadAbpModule();
|
|
@@ -16227,14 +16978,14 @@ function resolveStealthProfile(input) {
|
|
|
16227
16978
|
function isStealthProfile(input) {
|
|
16228
16979
|
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;
|
|
16229
16980
|
}
|
|
16230
|
-
async function
|
|
16981
|
+
async function sleep2(ms) {
|
|
16231
16982
|
await new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
16232
16983
|
}
|
|
16233
16984
|
var ENV_FILENAMES = [".env", ".env.local"];
|
|
16234
16985
|
var OPENSTEER_ENV_PREFIX = "OPENSTEER_";
|
|
16235
16986
|
var opensteerEnvironmentCache = /* @__PURE__ */ new Map();
|
|
16236
16987
|
function resolveOpensteerEnvironment(cwd = process.cwd(), baseEnv = process.env) {
|
|
16237
|
-
const resolvedCwd =
|
|
16988
|
+
const resolvedCwd = path10__default.default.resolve(cwd);
|
|
16238
16989
|
const signature = buildEnvironmentSignature(baseEnv, isOpensteerEnvironmentKey);
|
|
16239
16990
|
const cached = opensteerEnvironmentCache.get(resolvedCwd);
|
|
16240
16991
|
if (cached && cached.signature === signature) {
|
|
@@ -16249,10 +17000,10 @@ function resolveOpensteerEnvironment(cwd = process.cwd(), baseEnv = process.env)
|
|
|
16249
17000
|
}
|
|
16250
17001
|
function collectDirectories(cwd) {
|
|
16251
17002
|
const directories = [];
|
|
16252
|
-
let current =
|
|
17003
|
+
let current = path10__default.default.resolve(cwd);
|
|
16253
17004
|
for (; ; ) {
|
|
16254
17005
|
directories.unshift(current);
|
|
16255
|
-
const parent =
|
|
17006
|
+
const parent = path10__default.default.dirname(current);
|
|
16256
17007
|
if (parent === current) {
|
|
16257
17008
|
return directories;
|
|
16258
17009
|
}
|
|
@@ -16295,7 +17046,7 @@ function resolveEnvironmentFiles(cwd, baseEnv, predicate) {
|
|
|
16295
17046
|
const directories = collectDirectories(cwd);
|
|
16296
17047
|
for (const directory of directories) {
|
|
16297
17048
|
for (const filename of ENV_FILENAMES) {
|
|
16298
|
-
const filePath =
|
|
17049
|
+
const filePath = path10__default.default.join(directory, filename);
|
|
16299
17050
|
if (!fs.existsSync(filePath)) {
|
|
16300
17051
|
continue;
|
|
16301
17052
|
}
|
|
@@ -16374,17 +17125,17 @@ async function readBrowserCookies(input = {}) {
|
|
|
16374
17125
|
const brand2 = resolveRequestedBrand(input);
|
|
16375
17126
|
const userDataDir = resolveBrandUserDataDir(brand2, input.userDataDir);
|
|
16376
17127
|
const profileDirectory = input.profileDirectory ?? "Default";
|
|
16377
|
-
const cookiesPath =
|
|
17128
|
+
const cookiesPath = path10.join(userDataDir, profileDirectory, "Cookies");
|
|
16378
17129
|
if (!fs.existsSync(cookiesPath)) {
|
|
16379
17130
|
throw new Error(
|
|
16380
17131
|
`Cookies database not found at "${cookiesPath}". Verify the browser brand, user-data-dir, and profile-directory are correct.`
|
|
16381
17132
|
);
|
|
16382
17133
|
}
|
|
16383
|
-
const tempDir = await promises.mkdtemp(
|
|
17134
|
+
const tempDir = await promises.mkdtemp(path10.join(os.tmpdir(), "opensteer-cookies-"));
|
|
16384
17135
|
try {
|
|
16385
17136
|
await copyCookiesDatabase(cookiesPath, tempDir);
|
|
16386
17137
|
const decryptionKey = await resolveDecryptionKey(brand2.id, userDataDir);
|
|
16387
|
-
const rows = queryAllCookies(
|
|
17138
|
+
const rows = queryAllCookies(path10.join(tempDir, "Cookies"));
|
|
16388
17139
|
const cookies = decryptCookieRows(rows, decryptionKey);
|
|
16389
17140
|
return {
|
|
16390
17141
|
cookies,
|
|
@@ -16410,11 +17161,11 @@ function resolveRequestedBrand(input) {
|
|
|
16410
17161
|
return installed.brand;
|
|
16411
17162
|
}
|
|
16412
17163
|
async function copyCookiesDatabase(cookiesPath, destDir) {
|
|
16413
|
-
await promises.copyFile(cookiesPath,
|
|
17164
|
+
await promises.copyFile(cookiesPath, path10.join(destDir, "Cookies"));
|
|
16414
17165
|
for (const suffix of ["-wal", "-journal", "-shm"]) {
|
|
16415
17166
|
const src = cookiesPath + suffix;
|
|
16416
17167
|
if (fs.existsSync(src)) {
|
|
16417
|
-
await promises.copyFile(src,
|
|
17168
|
+
await promises.copyFile(src, path10.join(destDir, "Cookies" + suffix)).catch(() => void 0);
|
|
16418
17169
|
}
|
|
16419
17170
|
}
|
|
16420
17171
|
}
|
|
@@ -16491,7 +17242,7 @@ async function resolveKeychainPassword(brandId) {
|
|
|
16491
17242
|
}
|
|
16492
17243
|
}
|
|
16493
17244
|
async function resolveWindowsMasterKey(userDataDir) {
|
|
16494
|
-
const localStatePath =
|
|
17245
|
+
const localStatePath = path10.join(userDataDir, "Local State");
|
|
16495
17246
|
let localState;
|
|
16496
17247
|
try {
|
|
16497
17248
|
localState = JSON.parse(await promises.readFile(localStatePath, "utf8"));
|
|
@@ -16692,14 +17443,14 @@ function toPortableBrowserProfileCookieRecord(cookie) {
|
|
|
16692
17443
|
if (!name || !domain) {
|
|
16693
17444
|
return null;
|
|
16694
17445
|
}
|
|
16695
|
-
const
|
|
17446
|
+
const path18 = typeof cookie.path === "string" && cookie.path.trim().length > 0 ? cookie.path : "/";
|
|
16696
17447
|
const expiresAt = typeof cookie.expires === "number" && Number.isFinite(cookie.expires) && cookie.expires > 0 ? Math.floor(cookie.expires * 1e3) : null;
|
|
16697
17448
|
const sameSite = normalizeSameSite(cookie.sameSite);
|
|
16698
17449
|
return {
|
|
16699
17450
|
name,
|
|
16700
17451
|
value: cookie.value,
|
|
16701
17452
|
domain,
|
|
16702
|
-
path:
|
|
17453
|
+
path: path18,
|
|
16703
17454
|
secure: cookie.secure,
|
|
16704
17455
|
httpOnly: cookie.httpOnly,
|
|
16705
17456
|
...sameSite === void 0 ? {} : { sameSite },
|
|
@@ -16768,7 +17519,7 @@ async function waitForBrowserProfileImport(client, importId) {
|
|
|
16768
17519
|
if (current.status === "failed") {
|
|
16769
17520
|
throw new Error(current.error ?? "Browser profile sync failed.");
|
|
16770
17521
|
}
|
|
16771
|
-
await
|
|
17522
|
+
await sleep3(DEFAULT_POLL_INTERVAL_MS);
|
|
16772
17523
|
}
|
|
16773
17524
|
throw new Error(`Timed out waiting for browser profile sync "${importId}" to finish.`);
|
|
16774
17525
|
}
|
|
@@ -16777,7 +17528,7 @@ function normalizePlatform(platform) {
|
|
|
16777
17528
|
if (platform === "win32") return "windows";
|
|
16778
17529
|
return platform;
|
|
16779
17530
|
}
|
|
16780
|
-
async function
|
|
17531
|
+
async function sleep3(ms) {
|
|
16781
17532
|
await new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
16782
17533
|
}
|
|
16783
17534
|
|
|
@@ -16791,21 +17542,24 @@ var OpensteerCloudClient = class {
|
|
|
16791
17542
|
getConfig() {
|
|
16792
17543
|
return this.config;
|
|
16793
17544
|
}
|
|
16794
|
-
async createSession(input = {}) {
|
|
16795
|
-
const response = await this.request(
|
|
16796
|
-
|
|
16797
|
-
|
|
16798
|
-
|
|
16799
|
-
|
|
16800
|
-
|
|
16801
|
-
|
|
16802
|
-
|
|
16803
|
-
|
|
16804
|
-
|
|
16805
|
-
|
|
16806
|
-
|
|
16807
|
-
|
|
16808
|
-
|
|
17545
|
+
async createSession(input = {}, options = {}) {
|
|
17546
|
+
const response = await this.request(
|
|
17547
|
+
"/v1/sessions",
|
|
17548
|
+
{
|
|
17549
|
+
method: "POST",
|
|
17550
|
+
body: {
|
|
17551
|
+
...input.name === void 0 ? {} : { name: input.name },
|
|
17552
|
+
...input.browser === void 0 ? {} : { browser: input.browser },
|
|
17553
|
+
...input.context === void 0 ? {} : { context: input.context },
|
|
17554
|
+
...input.browserProfile === void 0 ? {} : { browserProfile: input.browserProfile },
|
|
17555
|
+
...input.observability === void 0 ? {} : { observability: input.observability },
|
|
17556
|
+
...input.sourceType === void 0 ? {} : { sourceType: input.sourceType },
|
|
17557
|
+
...input.sourceRef === void 0 ? {} : { sourceRef: input.sourceRef },
|
|
17558
|
+
...input.localWorkspaceRootPath === void 0 ? {} : { localWorkspaceRootPath: input.localWorkspaceRootPath }
|
|
17559
|
+
}
|
|
17560
|
+
},
|
|
17561
|
+
options
|
|
17562
|
+
);
|
|
16809
17563
|
return await response.json();
|
|
16810
17564
|
}
|
|
16811
17565
|
async listSessions() {
|
|
@@ -16814,19 +17568,27 @@ var OpensteerCloudClient = class {
|
|
|
16814
17568
|
});
|
|
16815
17569
|
return response.json();
|
|
16816
17570
|
}
|
|
16817
|
-
async getSession(sessionId) {
|
|
16818
|
-
const response = await this.request(
|
|
16819
|
-
|
|
16820
|
-
|
|
17571
|
+
async getSession(sessionId, options = {}) {
|
|
17572
|
+
const response = await this.request(
|
|
17573
|
+
`/v1/sessions/${encodeURIComponent(sessionId)}`,
|
|
17574
|
+
{
|
|
17575
|
+
method: "GET"
|
|
17576
|
+
},
|
|
17577
|
+
options
|
|
17578
|
+
);
|
|
16821
17579
|
return await response.json();
|
|
16822
17580
|
}
|
|
16823
|
-
async issueAccess(sessionId, capabilities) {
|
|
16824
|
-
const response = await this.request(
|
|
16825
|
-
|
|
16826
|
-
|
|
16827
|
-
|
|
16828
|
-
|
|
16829
|
-
|
|
17581
|
+
async issueAccess(sessionId, capabilities, options = {}) {
|
|
17582
|
+
const response = await this.request(
|
|
17583
|
+
`/v1/sessions/${encodeURIComponent(sessionId)}/access`,
|
|
17584
|
+
{
|
|
17585
|
+
method: "POST",
|
|
17586
|
+
body: {
|
|
17587
|
+
capabilities
|
|
17588
|
+
}
|
|
17589
|
+
},
|
|
17590
|
+
options
|
|
17591
|
+
);
|
|
16830
17592
|
return await response.json();
|
|
16831
17593
|
}
|
|
16832
17594
|
async getSessionRecording(sessionId) {
|
|
@@ -16908,28 +17670,17 @@ var OpensteerCloudClient = class {
|
|
|
16908
17670
|
async syncBrowserProfileCookies(input) {
|
|
16909
17671
|
return syncBrowserProfileCookies(this, input);
|
|
16910
17672
|
}
|
|
16911
|
-
async
|
|
16912
|
-
const response = await this.request("/
|
|
17673
|
+
async importDescriptors(entries) {
|
|
17674
|
+
const response = await this.request("/registry/descriptors/import", {
|
|
16913
17675
|
method: "POST",
|
|
16914
|
-
body: {
|
|
16915
|
-
entries: entries.map((entry) => ({
|
|
16916
|
-
workspace: entry.workspace,
|
|
16917
|
-
method: entry.method,
|
|
16918
|
-
persistHash: entry.persistHash,
|
|
16919
|
-
...entry.persist === void 0 ? {} : { persist: entry.persist },
|
|
16920
|
-
path: entry.path,
|
|
16921
|
-
...entry.schemaHash === void 0 ? {} : { schemaHash: entry.schemaHash },
|
|
16922
|
-
createdAt: entry.createdAt,
|
|
16923
|
-
updatedAt: entry.updatedAt
|
|
16924
|
-
}))
|
|
16925
|
-
}
|
|
17676
|
+
body: { entries }
|
|
16926
17677
|
});
|
|
16927
17678
|
return await response.json();
|
|
16928
17679
|
}
|
|
16929
|
-
async
|
|
16930
|
-
const response = await this.request("/registry/
|
|
17680
|
+
async importRequestPlans(input) {
|
|
17681
|
+
const response = await this.request("/registry/request-plans/import", {
|
|
16931
17682
|
method: "POST",
|
|
16932
|
-
body:
|
|
17683
|
+
body: input
|
|
16933
17684
|
});
|
|
16934
17685
|
return await response.json();
|
|
16935
17686
|
}
|
|
@@ -16942,7 +17693,7 @@ var OpensteerCloudClient = class {
|
|
|
16942
17693
|
"content-type": "application/json; charset=utf-8"
|
|
16943
17694
|
};
|
|
16944
17695
|
}
|
|
16945
|
-
async request(pathname, init) {
|
|
17696
|
+
async request(pathname, init, options = {}) {
|
|
16946
17697
|
const url = `${this.config.baseUrl}${pathname}`;
|
|
16947
17698
|
let response;
|
|
16948
17699
|
try {
|
|
@@ -16950,7 +17701,7 @@ var OpensteerCloudClient = class {
|
|
|
16950
17701
|
method: init.method,
|
|
16951
17702
|
headers: this.buildHeaders(),
|
|
16952
17703
|
...init.body === void 0 ? {} : { body: JSON.stringify(init.body) },
|
|
16953
|
-
signal:
|
|
17704
|
+
signal: createRequestSignal(options)
|
|
16954
17705
|
});
|
|
16955
17706
|
} catch (error) {
|
|
16956
17707
|
throw wrapCloudFetchError(error, {
|
|
@@ -16975,12 +17726,19 @@ var OpensteerCloudClient = class {
|
|
|
16975
17726
|
`Unexpected cloud session status "${String(session.status)}" while waiting for close.`
|
|
16976
17727
|
);
|
|
16977
17728
|
}
|
|
16978
|
-
await
|
|
17729
|
+
await delay2(CLOUD_CLOSE_POLL_INTERVAL_MS);
|
|
16979
17730
|
}
|
|
16980
17731
|
throw new Error(`Timed out waiting for cloud session ${sessionId} to close.`);
|
|
16981
17732
|
}
|
|
16982
17733
|
};
|
|
16983
|
-
function
|
|
17734
|
+
function createRequestSignal(options) {
|
|
17735
|
+
const timeoutSignal = AbortSignal.timeout(options.timeoutMs ?? 3e4);
|
|
17736
|
+
if (options.signal === void 0) {
|
|
17737
|
+
return timeoutSignal;
|
|
17738
|
+
}
|
|
17739
|
+
return AbortSignal.any([options.signal, timeoutSignal]);
|
|
17740
|
+
}
|
|
17741
|
+
function delay2(ms) {
|
|
16984
17742
|
return new Promise((resolve4) => {
|
|
16985
17743
|
setTimeout(resolve4, ms);
|
|
16986
17744
|
});
|
|
@@ -17030,7 +17788,7 @@ function resolveCloudConfig(input = {}) {
|
|
|
17030
17788
|
|
|
17031
17789
|
// ../runtime-core/package.json
|
|
17032
17790
|
var package_default = {
|
|
17033
|
-
version: "0.1
|
|
17791
|
+
version: "0.2.1"};
|
|
17034
17792
|
|
|
17035
17793
|
// ../runtime-core/src/version.ts
|
|
17036
17794
|
var OPENSTEER_RUNTIME_CORE_VERSION = package_default.version;
|
|
@@ -17786,11 +18544,11 @@ var NetworkHistory = class {
|
|
|
17786
18544
|
var MATCHED_TLS_BINARY_NAMES = ["curl-impersonate-chrome", "curl_chrome"];
|
|
17787
18545
|
async function executeMatchedTlsTransportRequest(input) {
|
|
17788
18546
|
const binary = await resolveMatchedTlsBinary();
|
|
17789
|
-
const workingDirectory = await promises.mkdtemp(
|
|
17790
|
-
const headersPath =
|
|
17791
|
-
const bodyPath =
|
|
17792
|
-
const cookiesPath =
|
|
17793
|
-
const requestBodyPath =
|
|
18547
|
+
const workingDirectory = await promises.mkdtemp(path10__default.default.join(os.tmpdir(), "opensteer-matched-tls-"));
|
|
18548
|
+
const headersPath = path10__default.default.join(workingDirectory, "headers.txt");
|
|
18549
|
+
const bodyPath = path10__default.default.join(workingDirectory, "body.bin");
|
|
18550
|
+
const cookiesPath = path10__default.default.join(workingDirectory, "cookies.txt");
|
|
18551
|
+
const requestBodyPath = path10__default.default.join(workingDirectory, "request-body.bin");
|
|
17794
18552
|
try {
|
|
17795
18553
|
await promises.writeFile(cookiesPath, toNetscapeCookieJar(input.cookies ?? []), "utf8");
|
|
17796
18554
|
if (input.request.body !== void 0) {
|
|
@@ -17847,10 +18605,10 @@ async function executeMatchedTlsTransportRequest(input) {
|
|
|
17847
18605
|
}
|
|
17848
18606
|
}
|
|
17849
18607
|
async function resolveMatchedTlsBinary() {
|
|
17850
|
-
const pathEntries = (process.env.PATH ?? "").split(
|
|
18608
|
+
const pathEntries = (process.env.PATH ?? "").split(path10__default.default.delimiter).filter((entry) => entry.length > 0);
|
|
17851
18609
|
for (const directory of pathEntries) {
|
|
17852
18610
|
for (const name of MATCHED_TLS_BINARY_NAMES) {
|
|
17853
|
-
const candidate =
|
|
18611
|
+
const candidate = path10__default.default.join(directory, name);
|
|
17854
18612
|
if (await isExecutable(candidate)) {
|
|
17855
18613
|
return candidate;
|
|
17856
18614
|
}
|
|
@@ -17858,7 +18616,7 @@ async function resolveMatchedTlsBinary() {
|
|
|
17858
18616
|
const files = await readDirSafe(directory);
|
|
17859
18617
|
const discovered = files.find((file) => file.startsWith("curl_chrome"));
|
|
17860
18618
|
if (discovered !== void 0) {
|
|
17861
|
-
const candidate =
|
|
18619
|
+
const candidate = path10__default.default.join(directory, discovered);
|
|
17862
18620
|
if (await isExecutable(candidate)) {
|
|
17863
18621
|
return candidate;
|
|
17864
18622
|
}
|
|
@@ -20312,11 +21070,11 @@ var SandboxClock = class {
|
|
|
20312
21070
|
performanceNow() {
|
|
20313
21071
|
return this.mode === "manual" ? this.manualNow - this.startedAt : (globalThis.performance?.now() ?? 0) - this.performanceStartedAt;
|
|
20314
21072
|
}
|
|
20315
|
-
setTimeout(callback,
|
|
20316
|
-
return this.registerTimer(false, callback,
|
|
21073
|
+
setTimeout(callback, delay4 = 0, ...args) {
|
|
21074
|
+
return this.registerTimer(false, callback, delay4, args);
|
|
20317
21075
|
}
|
|
20318
|
-
setInterval(callback,
|
|
20319
|
-
return this.registerTimer(true, callback,
|
|
21076
|
+
setInterval(callback, delay4 = 0, ...args) {
|
|
21077
|
+
return this.registerTimer(true, callback, delay4, args);
|
|
20320
21078
|
}
|
|
20321
21079
|
clearTimeout(timerId) {
|
|
20322
21080
|
this.clearTimer(timerId);
|
|
@@ -20337,9 +21095,9 @@ var SandboxClock = class {
|
|
|
20337
21095
|
this.clearTimer(timerId);
|
|
20338
21096
|
}
|
|
20339
21097
|
}
|
|
20340
|
-
registerTimer(repeat, callback,
|
|
21098
|
+
registerTimer(repeat, callback, delay4, args) {
|
|
20341
21099
|
const timerId = this.nextTimerId++;
|
|
20342
|
-
const normalizedDelay = Math.max(0,
|
|
21100
|
+
const normalizedDelay = Math.max(0, delay4);
|
|
20343
21101
|
const record = {
|
|
20344
21102
|
callback,
|
|
20345
21103
|
args,
|
|
@@ -20503,7 +21261,7 @@ async function pollTask(apiKey, taskId, signal) {
|
|
|
20503
21261
|
const deadline = Date.now() + 12e4;
|
|
20504
21262
|
while (Date.now() < deadline) {
|
|
20505
21263
|
signal?.throwIfAborted?.();
|
|
20506
|
-
await
|
|
21264
|
+
await sleep4(3e3, signal);
|
|
20507
21265
|
const response = await fetch(CAPSOLVER_GET_TASK_RESULT_URL, {
|
|
20508
21266
|
method: "POST",
|
|
20509
21267
|
headers: {
|
|
@@ -20547,7 +21305,7 @@ function extractCaptchaToken(solution) {
|
|
|
20547
21305
|
function readString(value) {
|
|
20548
21306
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
20549
21307
|
}
|
|
20550
|
-
function
|
|
21308
|
+
function sleep4(ms, signal) {
|
|
20551
21309
|
return new Promise((resolve4, reject) => {
|
|
20552
21310
|
const timeout = setTimeout(resolve4, ms);
|
|
20553
21311
|
const abort = () => {
|
|
@@ -20601,7 +21359,7 @@ async function pollTask2(apiKey, taskId, signal) {
|
|
|
20601
21359
|
const deadline = Date.now() + 12e4;
|
|
20602
21360
|
while (Date.now() < deadline) {
|
|
20603
21361
|
signal?.throwIfAborted?.();
|
|
20604
|
-
await
|
|
21362
|
+
await sleep5(5e3, signal);
|
|
20605
21363
|
const response = await fetch(TWO_CAPTCHA_GET_TASK_RESULT_URL, {
|
|
20606
21364
|
method: "POST",
|
|
20607
21365
|
headers: {
|
|
@@ -20645,7 +21403,7 @@ function extractCaptchaToken2(solution) {
|
|
|
20645
21403
|
function readString2(value) {
|
|
20646
21404
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
20647
21405
|
}
|
|
20648
|
-
function
|
|
21406
|
+
function sleep5(ms, signal) {
|
|
20649
21407
|
return new Promise((resolve4, reject) => {
|
|
20650
21408
|
const timeout = setTimeout(resolve4, ms);
|
|
20651
21409
|
const abort = () => {
|
|
@@ -20848,6 +21606,9 @@ var MUTATION_CAPTURE_FINALIZE_TIMEOUT_MS = 5e3;
|
|
|
20848
21606
|
var PERSISTED_NETWORK_FLUSH_TIMEOUT_MS = 5e3;
|
|
20849
21607
|
var PENDING_OPERATION_EVENT_CAPTURE_LIMIT = 64;
|
|
20850
21608
|
var PENDING_OPERATION_EVENT_CAPTURE_SKEW_MS = 1e3;
|
|
21609
|
+
var REPLAY_PROBE_MIN_ATTEMPT_TIMEOUT_MS = 3e3;
|
|
21610
|
+
var REPLAY_PROBE_MAX_ATTEMPT_TIMEOUT_MS = 15e3;
|
|
21611
|
+
var REPLAY_PROBE_POST_SUCCESS_ATTEMPT_TIMEOUT_MS = 5e3;
|
|
20851
21612
|
var OpensteerSessionRuntime = class {
|
|
20852
21613
|
workspace;
|
|
20853
21614
|
rootPath;
|
|
@@ -20879,7 +21640,7 @@ var OpensteerSessionRuntime = class {
|
|
|
20879
21640
|
this.workspace = normalizeNamespace2(options.name);
|
|
20880
21641
|
this.workspaceName = options.workspaceName?.trim() === void 0 || options.workspaceName?.trim().length === 0 ? void 0 : options.workspaceName.trim();
|
|
20881
21642
|
this.root = options.workspace;
|
|
20882
|
-
this.rootPath = options.workspace?.rootPath ?? options.rootPath ??
|
|
21643
|
+
this.rootPath = options.workspace?.rootPath ?? options.rootPath ?? path10__default.default.resolve(process.cwd(), ".opensteer", "temporary", crypto.randomUUID());
|
|
20883
21644
|
this.injectedEngine = options.engine;
|
|
20884
21645
|
this.engineFactory = options.engineFactory;
|
|
20885
21646
|
this.policy = options.policy ?? defaultPolicy();
|
|
@@ -21709,26 +22470,27 @@ var OpensteerSessionRuntime = class {
|
|
|
21709
22470
|
}
|
|
21710
22471
|
}
|
|
21711
22472
|
async queryNetwork(input = {}, options = {}) {
|
|
21712
|
-
|
|
22473
|
+
const normalizedInput = normalizeNetworkQueryInput(input);
|
|
22474
|
+
assertValidSemanticOperationInput("network.query", normalizedInput);
|
|
21713
22475
|
const root = await this.ensureRoot();
|
|
21714
22476
|
const startedAt = Date.now();
|
|
21715
22477
|
try {
|
|
21716
22478
|
const output = await this.runWithOperationTimeout(
|
|
21717
22479
|
"network.query",
|
|
21718
22480
|
async (timeout) => {
|
|
21719
|
-
await this.syncPersistedNetworkSelection(timeout,
|
|
22481
|
+
await this.syncPersistedNetworkSelection(timeout, normalizedInput, {
|
|
21720
22482
|
includeBodies: false
|
|
21721
22483
|
});
|
|
21722
22484
|
const rawRecords = await timeout.runStep(
|
|
21723
22485
|
() => root.registry.savedNetwork.query({
|
|
21724
|
-
...this.toSavedNetworkQueryInput(
|
|
21725
|
-
limit: Math.max(
|
|
22486
|
+
...this.toSavedNetworkQueryInput(normalizedInput),
|
|
22487
|
+
limit: Math.max(normalizedInput.limit ?? 50, 1e3)
|
|
21726
22488
|
})
|
|
21727
22489
|
);
|
|
21728
|
-
const filtered = filterNetworkSummaryRecords(rawRecords,
|
|
22490
|
+
const filtered = filterNetworkSummaryRecords(rawRecords, normalizedInput);
|
|
21729
22491
|
const sorted = sortPersistedNetworkRecordsChronologically(filtered);
|
|
21730
|
-
const sliced = sliceNetworkSummaryWindow(sorted,
|
|
21731
|
-
const limited = sliced.slice(0, Math.max(1, Math.min(
|
|
22492
|
+
const sliced = sliceNetworkSummaryWindow(sorted, normalizedInput);
|
|
22493
|
+
const limited = sliced.slice(0, Math.max(1, Math.min(normalizedInput.limit ?? 50, 200)));
|
|
21732
22494
|
const summaries = await this.buildNetworkSummaryRecords(limited, timeout);
|
|
21733
22495
|
return {
|
|
21734
22496
|
records: summaries
|
|
@@ -21742,9 +22504,9 @@ var OpensteerSessionRuntime = class {
|
|
|
21742
22504
|
completedAt: Date.now(),
|
|
21743
22505
|
outcome: "ok",
|
|
21744
22506
|
data: {
|
|
21745
|
-
limit:
|
|
21746
|
-
...
|
|
21747
|
-
...
|
|
22507
|
+
limit: normalizedInput.limit ?? 50,
|
|
22508
|
+
...normalizedInput.capture === void 0 ? {} : { capture: normalizedInput.capture },
|
|
22509
|
+
...normalizedInput.json === true ? { json: true } : {},
|
|
21748
22510
|
count: output.records.length
|
|
21749
22511
|
},
|
|
21750
22512
|
context: buildRuntimeTraceContext({
|
|
@@ -21769,12 +22531,13 @@ var OpensteerSessionRuntime = class {
|
|
|
21769
22531
|
}
|
|
21770
22532
|
}
|
|
21771
22533
|
async getNetworkDetail(input, options = {}) {
|
|
22534
|
+
const normalizedRecordId = normalizeNetworkRecordId(input.recordId);
|
|
21772
22535
|
const startedAt = Date.now();
|
|
21773
22536
|
try {
|
|
21774
22537
|
const output = await this.runWithOperationTimeout(
|
|
21775
22538
|
"network.detail",
|
|
21776
22539
|
async (timeout) => {
|
|
21777
|
-
const record = await this.resolveNetworkRecordByRecordId(
|
|
22540
|
+
const record = await this.resolveNetworkRecordByRecordId(normalizedRecordId, timeout, {
|
|
21778
22541
|
includeBodies: true,
|
|
21779
22542
|
redactSecretHeaders: false
|
|
21780
22543
|
});
|
|
@@ -21793,8 +22556,8 @@ var OpensteerSessionRuntime = class {
|
|
|
21793
22556
|
completedAt: Date.now(),
|
|
21794
22557
|
outcome: "ok",
|
|
21795
22558
|
data: {
|
|
21796
|
-
recordId:
|
|
21797
|
-
status: output.summary.status,
|
|
22559
|
+
recordId: normalizedRecordId,
|
|
22560
|
+
...output.summary.status === void 0 ? {} : { status: output.summary.status },
|
|
21798
22561
|
url: output.summary.url
|
|
21799
22562
|
},
|
|
21800
22563
|
context: buildRuntimeTraceContext({
|
|
@@ -23198,7 +23961,9 @@ var OpensteerSessionRuntime = class {
|
|
|
23198
23961
|
...graphql.persisted === void 0 ? {} : { persisted: graphql.persisted },
|
|
23199
23962
|
...graphqlVariables === void 0 ? {} : { variables: graphqlVariables }
|
|
23200
23963
|
};
|
|
23201
|
-
const requestBody = shouldShowRequestBody(record.record.method) && record.record.requestBody !== void 0 ? buildStructuredBodyPreview(record.record.requestBody, record.record.requestHeaders
|
|
23964
|
+
const requestBody = shouldShowRequestBody(record.record.method) && record.record.requestBody !== void 0 ? buildStructuredBodyPreview(record.record.requestBody, record.record.requestHeaders, {
|
|
23965
|
+
truncateData: false
|
|
23966
|
+
}) : void 0;
|
|
23202
23967
|
const responseBody = record.record.responseBody === void 0 ? void 0 : buildStructuredBodyPreview(record.record.responseBody, record.record.responseHeaders);
|
|
23203
23968
|
const notes = detectNetworkRecordNotes(record);
|
|
23204
23969
|
return {
|
|
@@ -23228,8 +23993,18 @@ var OpensteerSessionRuntime = class {
|
|
|
23228
23993
|
let recommended;
|
|
23229
23994
|
for (const transport of REPLAY_TRANSPORT_LADDER) {
|
|
23230
23995
|
const attemptStartedAt = Date.now();
|
|
23996
|
+
const attemptTimeoutMs = resolveReplayProbeAttemptTimeoutMs({
|
|
23997
|
+
remainingMs: timeout.remainingMs(),
|
|
23998
|
+
transportsRemaining: REPLAY_TRANSPORT_LADDER.length - attempts.length,
|
|
23999
|
+
recommendedFound: recommended !== void 0
|
|
24000
|
+
});
|
|
23231
24001
|
try {
|
|
23232
|
-
const output = await this.
|
|
24002
|
+
const output = await this.executeReplayTransportAttemptWithinBudget(
|
|
24003
|
+
transport,
|
|
24004
|
+
request,
|
|
24005
|
+
timeout,
|
|
24006
|
+
attemptTimeoutMs
|
|
24007
|
+
);
|
|
23233
24008
|
const ok = matchesSuccessFingerprintFromProtocolResponse(output.response, fingerprint);
|
|
23234
24009
|
attempts.push({
|
|
23235
24010
|
transport,
|
|
@@ -23245,7 +24020,7 @@ var OpensteerSessionRuntime = class {
|
|
|
23245
24020
|
transport,
|
|
23246
24021
|
ok: false,
|
|
23247
24022
|
durationMs: Date.now() - attemptStartedAt,
|
|
23248
|
-
error:
|
|
24023
|
+
error: normalizeProbeTransportAttemptError(transport, error, attemptTimeoutMs)
|
|
23249
24024
|
});
|
|
23250
24025
|
}
|
|
23251
24026
|
}
|
|
@@ -23449,6 +24224,23 @@ var OpensteerSessionRuntime = class {
|
|
|
23449
24224
|
}
|
|
23450
24225
|
}
|
|
23451
24226
|
}
|
|
24227
|
+
async executeReplayTransportAttemptWithinBudget(transport, request, timeout, attemptTimeoutMs) {
|
|
24228
|
+
if (attemptTimeoutMs === void 0) {
|
|
24229
|
+
return this.executeReplayTransportAttempt(transport, request, timeout);
|
|
24230
|
+
}
|
|
24231
|
+
return runWithPolicyTimeout(
|
|
24232
|
+
{
|
|
24233
|
+
resolveTimeoutMs() {
|
|
24234
|
+
return attemptTimeoutMs;
|
|
24235
|
+
}
|
|
24236
|
+
},
|
|
24237
|
+
{
|
|
24238
|
+
operation: timeout.operation,
|
|
24239
|
+
signal: timeout.signal
|
|
24240
|
+
},
|
|
24241
|
+
(attemptTimeout) => this.executeReplayTransportAttempt(transport, request, attemptTimeout)
|
|
24242
|
+
);
|
|
24243
|
+
}
|
|
23452
24244
|
async executeFetchTransportAttempt(transport, request, timeout, input) {
|
|
23453
24245
|
let prepared = finalizeMaterializedTransportRequest(request, transport);
|
|
23454
24246
|
if (input.cookies !== false && transport === "direct-http" && this.currentBinding() !== void 0) {
|
|
@@ -24363,10 +25155,15 @@ var OpensteerSessionRuntime = class {
|
|
|
24363
25155
|
return this.observationSessionId ?? this.sessionRef;
|
|
24364
25156
|
}
|
|
24365
25157
|
runWithOperationTimeout(operation, callback, options = {}) {
|
|
25158
|
+
const timeoutPolicy = options.timeoutMs === void 0 ? this.policy.timeout : {
|
|
25159
|
+
resolveTimeoutMs() {
|
|
25160
|
+
return options.timeoutMs;
|
|
25161
|
+
}
|
|
25162
|
+
};
|
|
24366
25163
|
const existingCollector = this.operationEventStorage.getStore();
|
|
24367
25164
|
if (existingCollector !== void 0) {
|
|
24368
25165
|
return runWithPolicyTimeout(
|
|
24369
|
-
|
|
25166
|
+
timeoutPolicy,
|
|
24370
25167
|
{
|
|
24371
25168
|
operation,
|
|
24372
25169
|
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
@@ -24379,7 +25176,7 @@ var OpensteerSessionRuntime = class {
|
|
|
24379
25176
|
return this.operationEventStorage.run(collector, async () => {
|
|
24380
25177
|
try {
|
|
24381
25178
|
return await runWithPolicyTimeout(
|
|
24382
|
-
|
|
25179
|
+
timeoutPolicy,
|
|
24383
25180
|
{
|
|
24384
25181
|
operation,
|
|
24385
25182
|
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
@@ -24549,6 +25346,21 @@ function buildEngineNetworkRecordFilters(input) {
|
|
|
24549
25346
|
function normalizeNetworkStatusFilter(status) {
|
|
24550
25347
|
return String(status);
|
|
24551
25348
|
}
|
|
25349
|
+
function normalizeNetworkQueryInput(input) {
|
|
25350
|
+
return {
|
|
25351
|
+
...input,
|
|
25352
|
+
...input.recordId === void 0 ? {} : { recordId: normalizeNetworkRecordId(input.recordId) },
|
|
25353
|
+
...input.before === void 0 ? {} : { before: normalizeNetworkRecordId(input.before) },
|
|
25354
|
+
...input.after === void 0 ? {} : { after: normalizeNetworkRecordId(input.after) }
|
|
25355
|
+
};
|
|
25356
|
+
}
|
|
25357
|
+
function normalizeNetworkRecordId(recordId) {
|
|
25358
|
+
const trimmed = recordId.trim();
|
|
25359
|
+
if (trimmed.length === 0 || trimmed.startsWith("record:")) {
|
|
25360
|
+
return trimmed;
|
|
25361
|
+
}
|
|
25362
|
+
return `record:${trimmed}`;
|
|
25363
|
+
}
|
|
24552
25364
|
function resolveLiveQueryRequestIds(input, history) {
|
|
24553
25365
|
const requestIdCandidates = [];
|
|
24554
25366
|
if (input.recordId !== void 0) {
|
|
@@ -24761,6 +25573,20 @@ var REPLAY_TRANSPORT_LADDER = [
|
|
|
24761
25573
|
"context-http",
|
|
24762
25574
|
"page-http"
|
|
24763
25575
|
];
|
|
25576
|
+
function resolveReplayProbeAttemptTimeoutMs(input) {
|
|
25577
|
+
const attemptCapMs = input.recommendedFound ? REPLAY_PROBE_POST_SUCCESS_ATTEMPT_TIMEOUT_MS : REPLAY_PROBE_MAX_ATTEMPT_TIMEOUT_MS;
|
|
25578
|
+
const clampedRemaining = input.remainingMs === void 0 ? void 0 : Math.max(0, input.remainingMs);
|
|
25579
|
+
if (clampedRemaining === 0) {
|
|
25580
|
+
return 0;
|
|
25581
|
+
}
|
|
25582
|
+
if (clampedRemaining === void 0) {
|
|
25583
|
+
return attemptCapMs;
|
|
25584
|
+
}
|
|
25585
|
+
const sliceMs = Math.floor(clampedRemaining / Math.max(1, input.transportsRemaining));
|
|
25586
|
+
const minimumBudgetAffordable = clampedRemaining >= REPLAY_PROBE_MIN_ATTEMPT_TIMEOUT_MS * input.transportsRemaining;
|
|
25587
|
+
const attemptBudgetMs = minimumBudgetAffordable ? Math.max(REPLAY_PROBE_MIN_ATTEMPT_TIMEOUT_MS, sliceMs) : sliceMs;
|
|
25588
|
+
return Math.min(clampedRemaining, attemptCapMs, Math.max(1, attemptBudgetMs));
|
|
25589
|
+
}
|
|
24764
25590
|
function filterNetworkSummaryRecords(records, input) {
|
|
24765
25591
|
return records.filter((record) => {
|
|
24766
25592
|
if (record.record.resourceType === "preflight" || record.record.method === "OPTIONS") {
|
|
@@ -24933,10 +25759,10 @@ function extractGraphqlOperationName(queryText) {
|
|
|
24933
25759
|
function shouldShowRequestBody(method) {
|
|
24934
25760
|
return !["GET", "HEAD", "DELETE", "OPTIONS"].includes(method.trim().toUpperCase());
|
|
24935
25761
|
}
|
|
24936
|
-
function buildStructuredBodyPreview(body, headers) {
|
|
25762
|
+
function buildStructuredBodyPreview(body, headers, options = {}) {
|
|
24937
25763
|
const contentType = headerValue(headers, "content-type") ?? body?.mimeType;
|
|
24938
25764
|
const parsed = parseStructuredPayload(body, contentType);
|
|
24939
|
-
const data = parsed === void 0 ? void 0 : typeof parsed === "string" ? truncateInlineText(parsed) : truncateStructuredValue(parsed);
|
|
25765
|
+
const data = parsed === void 0 ? void 0 : options.truncateData === false ? parsed : typeof parsed === "string" ? truncateInlineText(parsed) : truncateStructuredValue(parsed);
|
|
24940
25766
|
return {
|
|
24941
25767
|
bytes: body?.originalByteLength ?? body?.capturedByteLength ?? 0,
|
|
24942
25768
|
...contentType === void 0 ? {} : { contentType },
|
|
@@ -25149,10 +25975,12 @@ function resolveSessionFetchTransportLadder(transport) {
|
|
|
25149
25975
|
return ["direct-http"];
|
|
25150
25976
|
case "matched-tls":
|
|
25151
25977
|
return ["matched-tls"];
|
|
25978
|
+
case "context":
|
|
25979
|
+
return ["context-http"];
|
|
25152
25980
|
case "page":
|
|
25153
25981
|
return ["page-http"];
|
|
25154
25982
|
case "auto":
|
|
25155
|
-
return ["direct-http", "matched-tls", "page-http"];
|
|
25983
|
+
return ["direct-http", "matched-tls", "context-http", "page-http"];
|
|
25156
25984
|
}
|
|
25157
25985
|
}
|
|
25158
25986
|
function detectChallengeNoteFromRecord(record) {
|
|
@@ -25297,6 +26125,12 @@ function diffStorageSnapshot(left, right) {
|
|
|
25297
26125
|
function normalizeRuntimeErrorMessage(error) {
|
|
25298
26126
|
return error instanceof Error ? error.message : String(error);
|
|
25299
26127
|
}
|
|
26128
|
+
function normalizeProbeTransportAttemptError(transport, error, attemptTimeoutMs) {
|
|
26129
|
+
if (attemptTimeoutMs !== void 0 && error instanceof OpensteerProtocolError && error.code === "timeout") {
|
|
26130
|
+
return `${transport} probe exceeded ${String(attemptTimeoutMs)}ms`;
|
|
26131
|
+
}
|
|
26132
|
+
return normalizeRuntimeErrorMessage(error);
|
|
26133
|
+
}
|
|
25300
26134
|
function applyBrowserCookiesToTransportRequest(request, cookies) {
|
|
25301
26135
|
if (cookies.length === 0) {
|
|
25302
26136
|
return request;
|
|
@@ -26064,10 +26898,10 @@ var OpensteerSemanticRestClient = class {
|
|
|
26064
26898
|
constructor(connection) {
|
|
26065
26899
|
this.connection = connection;
|
|
26066
26900
|
}
|
|
26067
|
-
async invoke(operation, input) {
|
|
26068
|
-
return this.invokeInternal(operation, input, false);
|
|
26901
|
+
async invoke(operation, input, options = {}) {
|
|
26902
|
+
return this.invokeInternal(operation, input, false, options);
|
|
26069
26903
|
}
|
|
26070
|
-
async invokeInternal(operation, input, hasRetried) {
|
|
26904
|
+
async invokeInternal(operation, input, hasRetried, options) {
|
|
26071
26905
|
const endpoint = opensteerSemanticRestEndpoints.find((entry) => entry.name === operation);
|
|
26072
26906
|
if (!endpoint) {
|
|
26073
26907
|
throw new Error(`unsupported semantic operation ${operation}`);
|
|
@@ -26081,10 +26915,11 @@ var OpensteerSemanticRestClient = class {
|
|
|
26081
26915
|
method: "POST",
|
|
26082
26916
|
headers: {
|
|
26083
26917
|
authorization: await this.connection.getAuthorizationHeader(),
|
|
26084
|
-
"content-type": "application/json; charset=utf-8"
|
|
26918
|
+
"content-type": "application/json; charset=utf-8",
|
|
26919
|
+
...options.timeoutMs === void 0 ? {} : { "x-opensteer-timeout-ms": String(options.timeoutMs) }
|
|
26085
26920
|
},
|
|
26086
26921
|
body: JSON.stringify(request),
|
|
26087
|
-
signal:
|
|
26922
|
+
signal: createRequestSignal2(options)
|
|
26088
26923
|
});
|
|
26089
26924
|
} catch (error) {
|
|
26090
26925
|
if (operation === "session.close" && isFetchFailure(error)) {
|
|
@@ -26100,7 +26935,7 @@ var OpensteerSemanticRestClient = class {
|
|
|
26100
26935
|
return envelope.data;
|
|
26101
26936
|
} catch (error) {
|
|
26102
26937
|
if (!hasRetried && this.connection.handleError && await this.connection.handleError(error, { operation })) {
|
|
26103
|
-
return this.invokeInternal(operation, input, true);
|
|
26938
|
+
return this.invokeInternal(operation, input, true, options);
|
|
26104
26939
|
}
|
|
26105
26940
|
if (operation === "session.close" && isFetchFailure(error)) {
|
|
26106
26941
|
return { closed: true };
|
|
@@ -26112,6 +26947,13 @@ var OpensteerSemanticRestClient = class {
|
|
|
26112
26947
|
return this.invoke("session.close", {});
|
|
26113
26948
|
}
|
|
26114
26949
|
};
|
|
26950
|
+
function createRequestSignal2(options) {
|
|
26951
|
+
const timeoutSignal = AbortSignal.timeout(options.timeoutMs ?? 3e4);
|
|
26952
|
+
if (options.signal === void 0) {
|
|
26953
|
+
return timeoutSignal;
|
|
26954
|
+
}
|
|
26955
|
+
return AbortSignal.any([options.signal, timeoutSignal]);
|
|
26956
|
+
}
|
|
26115
26957
|
function isFetchFailure(error) {
|
|
26116
26958
|
if (!(error instanceof Error)) {
|
|
26117
26959
|
return false;
|
|
@@ -26478,13 +27320,44 @@ function asRecord(value) {
|
|
|
26478
27320
|
return value;
|
|
26479
27321
|
}
|
|
26480
27322
|
|
|
26481
|
-
// src/cloud/
|
|
26482
|
-
var
|
|
26483
|
-
var
|
|
26484
|
-
async function
|
|
27323
|
+
// src/cloud/workspace-sync.ts
|
|
27324
|
+
var WORKSPACE_SYNC_MAX_PAYLOAD_BYTES = 15e5;
|
|
27325
|
+
var WORKSPACE_SYNC_MAX_ENTRIES_PER_BATCH = 100;
|
|
27326
|
+
async function syncLocalWorkspaceToCloud(client, workspace, store) {
|
|
27327
|
+
await syncDescriptorRegistryToCloud(client, workspace, store);
|
|
27328
|
+
await syncRequestPlansToCloud(client, workspace, store);
|
|
27329
|
+
}
|
|
27330
|
+
async function syncDescriptorRegistryToCloud(client, workspace, store) {
|
|
26485
27331
|
const descriptors = await store.registry.descriptors.list();
|
|
26486
|
-
const
|
|
26487
|
-
await importInBatches(
|
|
27332
|
+
const entries = descriptors.map((record) => toDescriptorImportEntry(workspace, record));
|
|
27333
|
+
await importInBatches(entries, {
|
|
27334
|
+
getPayloadByteLength: (batch) => payloadByteLength({ entries: batch }),
|
|
27335
|
+
importBatch: (batch) => client.importDescriptors(batch)
|
|
27336
|
+
});
|
|
27337
|
+
}
|
|
27338
|
+
async function syncRequestPlansToCloud(client, workspace, store) {
|
|
27339
|
+
const requestPlans = await store.registry.requestPlans.list();
|
|
27340
|
+
const entries = requestPlans.map((record) => toRequestPlanImportEntry(workspace, record)).filter((entry) => entry !== void 0);
|
|
27341
|
+
await importInBatches(entries, {
|
|
27342
|
+
getPayloadByteLength: (batch) => payloadByteLength({ entries: batch }),
|
|
27343
|
+
importBatch: (batch) => client.importRequestPlans({ entries: batch })
|
|
27344
|
+
});
|
|
27345
|
+
}
|
|
27346
|
+
function toRequestPlanImportEntry(workspace, record) {
|
|
27347
|
+
const entry = {
|
|
27348
|
+
workspace,
|
|
27349
|
+
recordId: record.id,
|
|
27350
|
+
key: record.key,
|
|
27351
|
+
version: record.version,
|
|
27352
|
+
contentHash: record.contentHash,
|
|
27353
|
+
tags: [...record.tags],
|
|
27354
|
+
...record.provenance === void 0 ? {} : { provenance: record.provenance },
|
|
27355
|
+
...record.freshness === void 0 ? {} : { freshness: record.freshness },
|
|
27356
|
+
payload: record.payload,
|
|
27357
|
+
createdAt: record.createdAt,
|
|
27358
|
+
updatedAt: record.updatedAt
|
|
27359
|
+
};
|
|
27360
|
+
return payloadByteLength({ entries: [entry] }) <= WORKSPACE_SYNC_MAX_PAYLOAD_BYTES ? entry : void 0;
|
|
26488
27361
|
}
|
|
26489
27362
|
function toDescriptorImportEntry(workspace, record) {
|
|
26490
27363
|
return {
|
|
@@ -26500,19 +27373,19 @@ function toDescriptorImportEntry(workspace, record) {
|
|
|
26500
27373
|
updatedAt: record.updatedAt
|
|
26501
27374
|
};
|
|
26502
27375
|
}
|
|
26503
|
-
async function importInBatches(entries,
|
|
27376
|
+
async function importInBatches(entries, options) {
|
|
26504
27377
|
if (entries.length === 0) {
|
|
26505
27378
|
return;
|
|
26506
27379
|
}
|
|
26507
|
-
for (const batch of chunkEntries(entries)) {
|
|
26508
|
-
await importBatch(batch);
|
|
27380
|
+
for (const batch of chunkEntries(entries, options.getPayloadByteLength)) {
|
|
27381
|
+
await options.importBatch(batch);
|
|
26509
27382
|
}
|
|
26510
27383
|
}
|
|
26511
|
-
function chunkEntries(entries) {
|
|
27384
|
+
function chunkEntries(entries, getPayloadByteLength) {
|
|
26512
27385
|
const batches = [];
|
|
26513
27386
|
let currentBatch = [];
|
|
26514
27387
|
for (const entry of entries) {
|
|
26515
|
-
if (
|
|
27388
|
+
if (getPayloadByteLength([entry]) > WORKSPACE_SYNC_MAX_PAYLOAD_BYTES) {
|
|
26516
27389
|
continue;
|
|
26517
27390
|
}
|
|
26518
27391
|
if (currentBatch.length === 0) {
|
|
@@ -26520,7 +27393,7 @@ function chunkEntries(entries) {
|
|
|
26520
27393
|
continue;
|
|
26521
27394
|
}
|
|
26522
27395
|
const nextBatch = [...currentBatch, entry];
|
|
26523
|
-
if (nextBatch.length >
|
|
27396
|
+
if (nextBatch.length > WORKSPACE_SYNC_MAX_ENTRIES_PER_BATCH || getPayloadByteLength(nextBatch) > WORKSPACE_SYNC_MAX_PAYLOAD_BYTES) {
|
|
26524
27397
|
batches.push(currentBatch);
|
|
26525
27398
|
currentBatch = [entry];
|
|
26526
27399
|
continue;
|
|
@@ -26532,8 +27405,8 @@ function chunkEntries(entries) {
|
|
|
26532
27405
|
}
|
|
26533
27406
|
return batches;
|
|
26534
27407
|
}
|
|
26535
|
-
function payloadByteLength(
|
|
26536
|
-
return Buffer.byteLength(JSON.stringify(
|
|
27408
|
+
function payloadByteLength(value) {
|
|
27409
|
+
return Buffer.byteLength(JSON.stringify(value), "utf8");
|
|
26537
27410
|
}
|
|
26538
27411
|
|
|
26539
27412
|
// src/cloud/session-proxy.ts
|
|
@@ -26544,30 +27417,36 @@ var CloudSessionProxy = class {
|
|
|
26544
27417
|
cleanupRootOnClose;
|
|
26545
27418
|
cloud;
|
|
26546
27419
|
observability;
|
|
27420
|
+
policy;
|
|
26547
27421
|
sessionId;
|
|
26548
27422
|
semanticGrant;
|
|
26549
27423
|
client;
|
|
26550
27424
|
automation;
|
|
26551
27425
|
workspaceStore;
|
|
27426
|
+
syncWorkspaceOnClose = false;
|
|
26552
27427
|
constructor(cloud, options = {}) {
|
|
26553
27428
|
this.cloud = cloud;
|
|
26554
27429
|
this.workspace = options.workspace;
|
|
27430
|
+
this.policy = options.policy ?? defaultPolicy();
|
|
26555
27431
|
this.observability = options.observability;
|
|
26556
|
-
this.rootPath = options.rootPath ?? (this.workspace === void 0 ?
|
|
26557
|
-
rootDir:
|
|
27432
|
+
this.rootPath = options.rootPath ?? (this.workspace === void 0 ? path10__default.default.join(os.tmpdir(), `${TEMPORARY_CLOUD_WORKSPACE_PREFIX}${crypto.randomUUID()}`) : resolveFilesystemWorkspacePath({
|
|
27433
|
+
rootDir: path10__default.default.resolve(options.rootDir ?? process.cwd()),
|
|
26558
27434
|
workspace: this.workspace
|
|
26559
27435
|
}));
|
|
26560
27436
|
this.cleanupRootOnClose = options.cleanupRootOnClose ?? this.workspace === void 0;
|
|
26561
27437
|
}
|
|
26562
27438
|
async open(input = {}) {
|
|
26563
|
-
|
|
26564
|
-
|
|
26565
|
-
|
|
26566
|
-
|
|
26567
|
-
|
|
26568
|
-
|
|
26569
|
-
|
|
26570
|
-
|
|
27439
|
+
return this.invokeSemanticOperation(
|
|
27440
|
+
"session.open",
|
|
27441
|
+
{
|
|
27442
|
+
...input.url === void 0 ? {} : { url: input.url }
|
|
27443
|
+
},
|
|
27444
|
+
{
|
|
27445
|
+
...input.browser === void 0 ? {} : { browser: input.browser },
|
|
27446
|
+
...input.launch === void 0 ? {} : { launch: input.launch },
|
|
27447
|
+
...input.context === void 0 ? {} : { context: input.context }
|
|
27448
|
+
}
|
|
27449
|
+
);
|
|
26571
27450
|
}
|
|
26572
27451
|
async info() {
|
|
26573
27452
|
const persisted = this.client !== void 0 || this.sessionId !== void 0 ? void 0 : await this.loadPersistedSession();
|
|
@@ -26610,108 +27489,88 @@ var CloudSessionProxy = class {
|
|
|
26610
27489
|
};
|
|
26611
27490
|
}
|
|
26612
27491
|
async listPages(input = {}) {
|
|
26613
|
-
|
|
26614
|
-
return this.requireClient().invoke("page.list", input);
|
|
27492
|
+
return this.invokeSemanticOperation("page.list", input);
|
|
26615
27493
|
}
|
|
26616
27494
|
async newPage(input = {}) {
|
|
26617
|
-
|
|
26618
|
-
|
|
27495
|
+
return this.invokeAutomationOperation(
|
|
27496
|
+
"page.new",
|
|
27497
|
+
(automation) => automation.invoke("page.new", input)
|
|
27498
|
+
);
|
|
26619
27499
|
}
|
|
26620
27500
|
async activatePage(input) {
|
|
26621
|
-
|
|
26622
|
-
return this.requireClient().invoke("page.activate", input);
|
|
27501
|
+
return this.invokeSemanticOperation("page.activate", input);
|
|
26623
27502
|
}
|
|
26624
27503
|
async closePage(input = {}) {
|
|
26625
|
-
|
|
26626
|
-
return this.requireClient().invoke("page.close", input);
|
|
27504
|
+
return this.invokeSemanticOperation("page.close", input);
|
|
26627
27505
|
}
|
|
26628
27506
|
async goto(input) {
|
|
26629
|
-
|
|
26630
|
-
return this.requireClient().invoke("page.goto", input);
|
|
27507
|
+
return this.invokeSemanticOperation("page.goto", input);
|
|
26631
27508
|
}
|
|
26632
27509
|
async evaluate(input) {
|
|
26633
|
-
|
|
26634
|
-
|
|
27510
|
+
return this.invokeAutomationOperation(
|
|
27511
|
+
"page.evaluate",
|
|
27512
|
+
(automation) => automation.invoke("page.evaluate", input)
|
|
27513
|
+
);
|
|
26635
27514
|
}
|
|
26636
27515
|
async addInitScript(input) {
|
|
26637
|
-
|
|
26638
|
-
return this.requireClient().invoke("page.add-init-script", input);
|
|
27516
|
+
return this.invokeSemanticOperation("page.add-init-script", input);
|
|
26639
27517
|
}
|
|
26640
27518
|
async snapshot(input = {}) {
|
|
26641
|
-
|
|
26642
|
-
return this.requireClient().invoke("page.snapshot", input);
|
|
27519
|
+
return this.invokeSemanticOperation("page.snapshot", input);
|
|
26643
27520
|
}
|
|
26644
27521
|
async click(input) {
|
|
26645
|
-
|
|
26646
|
-
return this.requireClient().invoke("dom.click", input);
|
|
27522
|
+
return this.invokeSemanticOperation("dom.click", input);
|
|
26647
27523
|
}
|
|
26648
27524
|
async hover(input) {
|
|
26649
|
-
|
|
26650
|
-
return this.requireClient().invoke("dom.hover", input);
|
|
27525
|
+
return this.invokeSemanticOperation("dom.hover", input);
|
|
26651
27526
|
}
|
|
26652
27527
|
async input(input) {
|
|
26653
|
-
|
|
26654
|
-
return this.requireClient().invoke("dom.input", input);
|
|
27528
|
+
return this.invokeSemanticOperation("dom.input", input);
|
|
26655
27529
|
}
|
|
26656
27530
|
async scroll(input) {
|
|
26657
|
-
|
|
26658
|
-
return this.requireClient().invoke("dom.scroll", input);
|
|
27531
|
+
return this.invokeSemanticOperation("dom.scroll", input);
|
|
26659
27532
|
}
|
|
26660
27533
|
async extract(input) {
|
|
26661
|
-
|
|
26662
|
-
return this.requireClient().invoke("dom.extract", input);
|
|
27534
|
+
return this.invokeSemanticOperation("dom.extract", input);
|
|
26663
27535
|
}
|
|
26664
27536
|
async queryNetwork(input = {}) {
|
|
26665
|
-
|
|
26666
|
-
return this.requireClient().invoke("network.query", input);
|
|
27537
|
+
return this.invokeSemanticOperation("network.query", input);
|
|
26667
27538
|
}
|
|
26668
27539
|
async getNetworkDetail(input) {
|
|
26669
|
-
|
|
26670
|
-
return this.requireClient().invoke("network.detail", input);
|
|
27540
|
+
return this.invokeSemanticOperation("network.detail", input);
|
|
26671
27541
|
}
|
|
26672
27542
|
async captureInteraction(input) {
|
|
26673
|
-
|
|
26674
|
-
return this.requireClient().invoke("interaction.capture", input);
|
|
27543
|
+
return this.invokeSemanticOperation("interaction.capture", input);
|
|
26675
27544
|
}
|
|
26676
27545
|
async getInteraction(input) {
|
|
26677
|
-
|
|
26678
|
-
return this.requireClient().invoke("interaction.get", input);
|
|
27546
|
+
return this.invokeSemanticOperation("interaction.get", input);
|
|
26679
27547
|
}
|
|
26680
27548
|
async diffInteraction(input) {
|
|
26681
|
-
|
|
26682
|
-
return this.requireClient().invoke("interaction.diff", input);
|
|
27549
|
+
return this.invokeSemanticOperation("interaction.diff", input);
|
|
26683
27550
|
}
|
|
26684
27551
|
async replayInteraction(input) {
|
|
26685
|
-
|
|
26686
|
-
return this.requireClient().invoke("interaction.replay", input);
|
|
27552
|
+
return this.invokeSemanticOperation("interaction.replay", input);
|
|
26687
27553
|
}
|
|
26688
27554
|
async captureScripts(input = {}) {
|
|
26689
|
-
|
|
26690
|
-
return this.requireClient().invoke("scripts.capture", input);
|
|
27555
|
+
return this.invokeSemanticOperation("scripts.capture", input);
|
|
26691
27556
|
}
|
|
26692
27557
|
async readArtifact(input) {
|
|
26693
|
-
|
|
26694
|
-
return this.requireClient().invoke("artifact.read", input);
|
|
27558
|
+
return this.invokeSemanticOperation("artifact.read", input);
|
|
26695
27559
|
}
|
|
26696
27560
|
async beautifyScript(input) {
|
|
26697
|
-
|
|
26698
|
-
return this.requireClient().invoke("scripts.beautify", input);
|
|
27561
|
+
return this.invokeSemanticOperation("scripts.beautify", input);
|
|
26699
27562
|
}
|
|
26700
27563
|
async deobfuscateScript(input) {
|
|
26701
|
-
|
|
26702
|
-
return this.requireClient().invoke("scripts.deobfuscate", input);
|
|
27564
|
+
return this.invokeSemanticOperation("scripts.deobfuscate", input);
|
|
26703
27565
|
}
|
|
26704
27566
|
async sandboxScript(input) {
|
|
26705
|
-
|
|
26706
|
-
return this.requireClient().invoke("scripts.sandbox", input);
|
|
27567
|
+
return this.invokeSemanticOperation("scripts.sandbox", input);
|
|
26707
27568
|
}
|
|
26708
27569
|
async solveCaptcha(input) {
|
|
26709
|
-
|
|
26710
|
-
return this.requireClient().invoke("captcha.solve", input);
|
|
27570
|
+
return this.invokeSemanticOperation("captcha.solve", input);
|
|
26711
27571
|
}
|
|
26712
27572
|
async getCookies(input = {}) {
|
|
26713
|
-
|
|
26714
|
-
return this.requireClient().invoke("session.cookies", input);
|
|
27573
|
+
return this.invokeSemanticOperation("session.cookies", input);
|
|
26715
27574
|
}
|
|
26716
27575
|
async route(input) {
|
|
26717
27576
|
await this.ensureSession();
|
|
@@ -26722,20 +27581,16 @@ var CloudSessionProxy = class {
|
|
|
26722
27581
|
return this.requireAutomation().interceptScript(input);
|
|
26723
27582
|
}
|
|
26724
27583
|
async getStorageSnapshot(input = {}) {
|
|
26725
|
-
|
|
26726
|
-
return this.requireClient().invoke("session.storage", input);
|
|
27584
|
+
return this.invokeSemanticOperation("session.storage", input);
|
|
26727
27585
|
}
|
|
26728
27586
|
async getBrowserState(input = {}) {
|
|
26729
|
-
|
|
26730
|
-
return this.requireClient().invoke("session.state", input);
|
|
27587
|
+
return this.invokeSemanticOperation("session.state", input);
|
|
26731
27588
|
}
|
|
26732
27589
|
async fetch(input) {
|
|
26733
|
-
|
|
26734
|
-
return this.requireClient().invoke("session.fetch", input);
|
|
27590
|
+
return this.invokeSemanticOperation("session.fetch", input);
|
|
26735
27591
|
}
|
|
26736
27592
|
async computerExecute(input) {
|
|
26737
|
-
|
|
26738
|
-
return this.requireClient().invoke("computer.execute", input);
|
|
27593
|
+
return this.invokeSemanticOperation("computer.execute", input);
|
|
26739
27594
|
}
|
|
26740
27595
|
async close() {
|
|
26741
27596
|
const session = await this.loadPersistedSession() ?? (this.sessionId === void 0 ? void 0 : {
|
|
@@ -26747,6 +27602,14 @@ var CloudSessionProxy = class {
|
|
|
26747
27602
|
startedAt: Date.now(),
|
|
26748
27603
|
updatedAt: Date.now()
|
|
26749
27604
|
});
|
|
27605
|
+
let syncError;
|
|
27606
|
+
if (this.syncWorkspaceOnClose) {
|
|
27607
|
+
try {
|
|
27608
|
+
await this.syncWorkspaceToCloud();
|
|
27609
|
+
} catch (error) {
|
|
27610
|
+
syncError = error;
|
|
27611
|
+
}
|
|
27612
|
+
}
|
|
26750
27613
|
try {
|
|
26751
27614
|
if (session !== void 0) {
|
|
26752
27615
|
await this.cloud.closeSession(session.sessionId).catch((error) => {
|
|
@@ -26767,6 +27630,9 @@ var CloudSessionProxy = class {
|
|
|
26767
27630
|
await promises.rm(this.rootPath, { recursive: true, force: true }).catch(() => void 0);
|
|
26768
27631
|
}
|
|
26769
27632
|
}
|
|
27633
|
+
if (syncError !== void 0) {
|
|
27634
|
+
throw syncError;
|
|
27635
|
+
}
|
|
26770
27636
|
return { closed: true };
|
|
26771
27637
|
}
|
|
26772
27638
|
async disconnect() {
|
|
@@ -26774,34 +27640,38 @@ var CloudSessionProxy = class {
|
|
|
26774
27640
|
await this.close();
|
|
26775
27641
|
return;
|
|
26776
27642
|
}
|
|
27643
|
+
let syncError;
|
|
27644
|
+
if (this.syncWorkspaceOnClose) {
|
|
27645
|
+
try {
|
|
27646
|
+
await this.syncWorkspaceToCloud();
|
|
27647
|
+
} catch (error) {
|
|
27648
|
+
syncError = error;
|
|
27649
|
+
}
|
|
27650
|
+
}
|
|
26777
27651
|
this.client = void 0;
|
|
26778
27652
|
await this.automation?.close().catch(() => void 0);
|
|
26779
27653
|
this.automation = void 0;
|
|
26780
27654
|
this.sessionId = void 0;
|
|
26781
27655
|
this.semanticGrant = void 0;
|
|
27656
|
+
if (syncError !== void 0) {
|
|
27657
|
+
throw syncError;
|
|
27658
|
+
}
|
|
26782
27659
|
}
|
|
26783
|
-
async ensureSession(input = {}) {
|
|
27660
|
+
async ensureSession(input = {}, timeout) {
|
|
26784
27661
|
if (this.client) {
|
|
26785
27662
|
return;
|
|
26786
27663
|
}
|
|
26787
27664
|
assertSupportedCloudBrowserMode(input.browser);
|
|
26788
27665
|
const localCloud = this.shouldUseLocalCloudTransport();
|
|
27666
|
+
this.syncWorkspaceOnClose = localCloud && this.workspace !== void 0;
|
|
26789
27667
|
const browserProfile = resolveCloudBrowserProfile(this.cloud, input);
|
|
26790
27668
|
const persisted = await this.loadPersistedSession();
|
|
26791
|
-
if (persisted !== void 0 && await this.isReusableCloudSession(persisted.sessionId)) {
|
|
26792
|
-
|
|
26793
|
-
void this.syncRegistryToCloud();
|
|
26794
|
-
} else {
|
|
26795
|
-
await this.syncRegistryToCloud();
|
|
26796
|
-
}
|
|
27669
|
+
if (persisted !== void 0 && await this.isReusableCloudSession(persisted.sessionId, timeout)) {
|
|
27670
|
+
await this.syncWorkspaceToCloud();
|
|
26797
27671
|
this.bindClient(persisted);
|
|
26798
27672
|
return;
|
|
26799
27673
|
}
|
|
26800
|
-
|
|
26801
|
-
void this.syncRegistryToCloud();
|
|
26802
|
-
} else {
|
|
26803
|
-
await this.syncRegistryToCloud();
|
|
26804
|
-
}
|
|
27674
|
+
await this.syncWorkspaceToCloud();
|
|
26805
27675
|
const baseCreateInput = {
|
|
26806
27676
|
...this.workspace === void 0 ? {} : { name: this.workspace },
|
|
26807
27677
|
...input.launch === void 0 ? {} : { browser: input.launch },
|
|
@@ -26813,10 +27683,12 @@ var CloudSessionProxy = class {
|
|
|
26813
27683
|
...baseCreateInput,
|
|
26814
27684
|
sourceType: "local-cloud",
|
|
26815
27685
|
sourceRef: this.workspace,
|
|
26816
|
-
localWorkspaceRootPath: this.rootPath
|
|
26817
|
-
locality: "auto"
|
|
27686
|
+
localWorkspaceRootPath: this.rootPath
|
|
26818
27687
|
} : baseCreateInput;
|
|
26819
|
-
const session = await this.cloud.createSession(createInput
|
|
27688
|
+
const session = await this.cloud.createSession(createInput, {
|
|
27689
|
+
signal: timeout?.signal,
|
|
27690
|
+
timeoutMs: timeout?.remainingMs()
|
|
27691
|
+
});
|
|
26820
27692
|
const record = {
|
|
26821
27693
|
layout: "opensteer-session",
|
|
26822
27694
|
version: 1,
|
|
@@ -26829,15 +27701,12 @@ var CloudSessionProxy = class {
|
|
|
26829
27701
|
await this.writePersistedSession(record);
|
|
26830
27702
|
this.bindClient(record, session.initialGrants?.semantic);
|
|
26831
27703
|
}
|
|
26832
|
-
async
|
|
27704
|
+
async syncWorkspaceToCloud() {
|
|
26833
27705
|
if (this.workspace === void 0) {
|
|
26834
27706
|
return;
|
|
26835
27707
|
}
|
|
26836
|
-
|
|
26837
|
-
|
|
26838
|
-
await syncLocalRegistryToCloud(this.cloud, this.workspace, workspaceStore);
|
|
26839
|
-
} catch {
|
|
26840
|
-
}
|
|
27708
|
+
const workspaceStore = await this.ensureWorkspaceStore();
|
|
27709
|
+
await syncLocalWorkspaceToCloud(this.cloud, this.workspace, workspaceStore);
|
|
26841
27710
|
}
|
|
26842
27711
|
bindClient(record, initialSemanticGrant) {
|
|
26843
27712
|
this.sessionId = record.sessionId;
|
|
@@ -26871,9 +27740,12 @@ var CloudSessionProxy = class {
|
|
|
26871
27740
|
async clearPersistedSession() {
|
|
26872
27741
|
await clearPersistedSessionRecord(this.rootPath, "cloud").catch(() => void 0);
|
|
26873
27742
|
}
|
|
26874
|
-
async isReusableCloudSession(sessionId) {
|
|
27743
|
+
async isReusableCloudSession(sessionId, timeout) {
|
|
26875
27744
|
try {
|
|
26876
|
-
const session = await this.cloud.getSession(sessionId
|
|
27745
|
+
const session = await this.cloud.getSession(sessionId, {
|
|
27746
|
+
signal: timeout?.signal,
|
|
27747
|
+
timeoutMs: timeout?.remainingMs()
|
|
27748
|
+
});
|
|
26877
27749
|
return session.status !== "closed" && session.status !== "failed";
|
|
26878
27750
|
} catch (error) {
|
|
26879
27751
|
if (isMissingCloudSessionError(error)) {
|
|
@@ -26894,14 +27766,17 @@ var CloudSessionProxy = class {
|
|
|
26894
27766
|
}
|
|
26895
27767
|
return this.automation;
|
|
26896
27768
|
}
|
|
26897
|
-
async ensureSemanticGrant(forceRefresh = false) {
|
|
27769
|
+
async ensureSemanticGrant(forceRefresh = false, timeout) {
|
|
26898
27770
|
if (!forceRefresh && this.semanticGrant?.kind === "semantic" && this.semanticGrant.expiresAt > Date.now() + 1e4) {
|
|
26899
27771
|
return this.semanticGrant;
|
|
26900
27772
|
}
|
|
26901
27773
|
if (!this.sessionId) {
|
|
26902
27774
|
throw new Error("Cloud session has not been initialized.");
|
|
26903
27775
|
}
|
|
26904
|
-
const issued = await this.cloud.issueAccess(this.sessionId, ["semantic"]
|
|
27776
|
+
const issued = await this.cloud.issueAccess(this.sessionId, ["semantic"], {
|
|
27777
|
+
signal: timeout?.signal,
|
|
27778
|
+
timeoutMs: timeout?.remainingMs()
|
|
27779
|
+
});
|
|
26905
27780
|
const grant = issued.grants.semantic;
|
|
26906
27781
|
if (!grant || grant.transport !== "http") {
|
|
26907
27782
|
throw new Error("cloud did not issue a valid semantic grant");
|
|
@@ -26924,6 +27799,25 @@ var CloudSessionProxy = class {
|
|
|
26924
27799
|
return false;
|
|
26925
27800
|
}
|
|
26926
27801
|
}
|
|
27802
|
+
async invokeSemanticOperation(operation, input, sessionInit = {}) {
|
|
27803
|
+
return this.runOperationWithPolicy(operation, async (timeout) => {
|
|
27804
|
+
await this.ensureSession(sessionInit, timeout);
|
|
27805
|
+
await this.ensureSemanticGrant(false, timeout);
|
|
27806
|
+
return this.requireClient().invoke(operation, input, {
|
|
27807
|
+
signal: timeout.signal,
|
|
27808
|
+
timeoutMs: timeout.remainingMs()
|
|
27809
|
+
});
|
|
27810
|
+
});
|
|
27811
|
+
}
|
|
27812
|
+
async invokeAutomationOperation(operation, invoke, sessionInit = {}) {
|
|
27813
|
+
return this.runOperationWithPolicy(operation, async (timeout) => {
|
|
27814
|
+
await this.ensureSession(sessionInit, timeout);
|
|
27815
|
+
return invoke(this.requireAutomation());
|
|
27816
|
+
});
|
|
27817
|
+
}
|
|
27818
|
+
async runOperationWithPolicy(operation, invoke) {
|
|
27819
|
+
return runWithPolicyTimeout(this.policy.timeout, { operation }, invoke);
|
|
27820
|
+
}
|
|
26927
27821
|
shouldUseLocalCloudTransport() {
|
|
26928
27822
|
if (this.workspace === void 0) {
|
|
26929
27823
|
return false;
|
|
@@ -26958,8 +27852,8 @@ function isLoopbackBaseUrl(baseUrl) {
|
|
|
26958
27852
|
var OpensteerRuntime = class extends OpensteerSessionRuntime {
|
|
26959
27853
|
constructor(options = {}) {
|
|
26960
27854
|
const publicWorkspace = normalizeWorkspace2(options.workspace);
|
|
26961
|
-
const rootPath = options.rootPath ?? (publicWorkspace === void 0 ?
|
|
26962
|
-
rootDir:
|
|
27855
|
+
const rootPath = options.rootPath ?? (publicWorkspace === void 0 ? path10__default.default.resolve(options.rootDir ?? process.cwd(), ".opensteer", "temporary", crypto.randomUUID()) : resolveFilesystemWorkspacePath({
|
|
27856
|
+
rootDir: path10__default.default.resolve(options.rootDir ?? process.cwd()),
|
|
26963
27857
|
workspace: publicWorkspace
|
|
26964
27858
|
}));
|
|
26965
27859
|
const cleanupRootOnClose = options.cleanupRootOnClose ?? publicWorkspace === void 0;
|
|
@@ -26993,7 +27887,7 @@ var OpensteerRuntime = class extends OpensteerSessionRuntime {
|
|
|
26993
27887
|
};
|
|
26994
27888
|
var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
|
|
26995
27889
|
constructor(options) {
|
|
26996
|
-
const rootPath = options.rootPath ??
|
|
27890
|
+
const rootPath = options.rootPath ?? path10__default.default.resolve(options.rootDir ?? process.cwd());
|
|
26997
27891
|
const cleanupRootOnClose = options.cleanupRootOnClose ?? false;
|
|
26998
27892
|
const engineName = options.engineName ?? DEFAULT_OPENSTEER_ENGINE;
|
|
26999
27893
|
assertSupportedEngineOptions({
|
|
@@ -27098,6 +27992,7 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
27098
27992
|
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
27099
27993
|
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
27100
27994
|
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
27995
|
+
...runtimeOptions.policy === void 0 ? {} : { policy: runtimeOptions.policy },
|
|
27101
27996
|
...runtimeOptions.cleanupRootOnClose === void 0 ? {} : { cleanupRootOnClose: runtimeOptions.cleanupRootOnClose },
|
|
27102
27997
|
...runtimeOptions.observability === void 0 ? {} : { observability: runtimeOptions.observability }
|
|
27103
27998
|
});
|
|
@@ -27282,7 +28177,7 @@ var Opensteer = class {
|
|
|
27282
28177
|
if (Date.now() >= timeoutAt) {
|
|
27283
28178
|
throw new Error("waitForNetwork timed out");
|
|
27284
28179
|
}
|
|
27285
|
-
await
|
|
28180
|
+
await delay3(pollInterval);
|
|
27286
28181
|
}
|
|
27287
28182
|
}
|
|
27288
28183
|
async waitForResponse(input) {
|
|
@@ -27311,7 +28206,7 @@ var Opensteer = class {
|
|
|
27311
28206
|
if (Date.now() >= timeoutAt) {
|
|
27312
28207
|
throw new Error("waitForPage timed out");
|
|
27313
28208
|
}
|
|
27314
|
-
await
|
|
28209
|
+
await delay3(pollIntervalMs);
|
|
27315
28210
|
}
|
|
27316
28211
|
}
|
|
27317
28212
|
async snapshot(mode = "action") {
|
|
@@ -27463,7 +28358,7 @@ function decodeBody(response) {
|
|
|
27463
28358
|
}
|
|
27464
28359
|
return Uint8Array.from(Buffer.from(response.body.data, "base64"));
|
|
27465
28360
|
}
|
|
27466
|
-
function
|
|
28361
|
+
function delay3(ms) {
|
|
27467
28362
|
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
27468
28363
|
}
|
|
27469
28364
|
|