opensteer 0.9.0 → 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.
Files changed (38) hide show
  1. package/dist/chunk-4LP7QP2O.js +4336 -0
  2. package/dist/chunk-4LP7QP2O.js.map +1 -0
  3. package/dist/{chunk-656MQUSM.js → chunk-6PGXWW3X.js} +4787 -9519
  4. package/dist/chunk-6PGXWW3X.js.map +1 -0
  5. package/dist/chunk-BMPUL66S.js +1170 -0
  6. package/dist/chunk-BMPUL66S.js.map +1 -0
  7. package/dist/{chunk-OIKLSFXA.js → chunk-L4FWHBQJ.js} +4 -3
  8. package/dist/chunk-L4FWHBQJ.js.map +1 -0
  9. package/dist/chunk-Z53HNZ7Z.js +1800 -0
  10. package/dist/chunk-Z53HNZ7Z.js.map +1 -0
  11. package/dist/cli/bin.cjs +3050 -281
  12. package/dist/cli/bin.cjs.map +1 -1
  13. package/dist/cli/bin.js +124 -7
  14. package/dist/cli/bin.js.map +1 -1
  15. package/dist/index.cjs +918 -263
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +1 -0
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.js +4 -2
  20. package/dist/local-view/public/assets/app.css +770 -0
  21. package/dist/local-view/public/assets/app.js +2053 -0
  22. package/dist/local-view/public/index.html +235 -0
  23. package/dist/local-view/serve-entry.cjs +7436 -0
  24. package/dist/local-view/serve-entry.cjs.map +1 -0
  25. package/dist/local-view/serve-entry.d.cts +1 -0
  26. package/dist/local-view/serve-entry.d.ts +1 -0
  27. package/dist/local-view/serve-entry.js +23 -0
  28. package/dist/local-view/serve-entry.js.map +1 -0
  29. package/dist/opensteer-KZCRP425.js +6 -0
  30. package/dist/{opensteer-LKX3233A.js.map → opensteer-KZCRP425.js.map} +1 -1
  31. package/dist/session-control-VGBFOH3Y.js +39 -0
  32. package/dist/session-control-VGBFOH3Y.js.map +1 -0
  33. package/package.json +8 -8
  34. package/skills/README.md +3 -0
  35. package/skills/opensteer/SKILL.md +229 -48
  36. package/dist/chunk-656MQUSM.js.map +0 -1
  37. package/dist/chunk-OIKLSFXA.js.map +0 -1
  38. package/dist/opensteer-LKX3233A.js +0 -4
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var path7 = require('path');
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 path7__default = /*#__PURE__*/_interopDefault(path7);
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, path15) {
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(`${path15} must be a finite JSON number`);
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, `${path15}[${index}]`));
76
+ return value.map((entry, index) => canonicalizeJsonValue(entry, `${path18}[${index}]`));
75
77
  }
76
78
  if (!isPlainObject(value)) {
77
- throw new TypeError(`${path15} must be a plain JSON object`);
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(`${path15}.${key} must not be undefined`);
86
+ throw new TypeError(`${path18}.${key} must not be undefined`);
85
87
  }
86
- result[key] = canonicalizeJsonValue(entry, `${path15}.${key}`);
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 (path7__default.default.isAbsolute(relativePath)) {
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 path7__default.default.join(rootPath, ...segments);
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(path7__default.default.dirname(filePath));
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(path7__default.default.dirname(filePath));
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(path7__default.default.dirname(filePath));
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(path7__default.default.dirname(lockPath));
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 = path7__default.default.join(this.rootPath, "artifacts", "manifests");
263
- this.objectsDirectory = path7__default.default.join(this.rootPath, "artifacts", "objects", "sha256");
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 path7__default.default.join(this.manifestsDirectory, `${encodePathSegment(artifactId)}.json`);
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, path15 = "$") {
584
- return validateSchemaNode(schema, value, path15);
585
+ function validateJsonSchema(schema, value, path18 = "$") {
586
+ return validateSchemaNode(schema, value, path18);
585
587
  }
586
- function validateSchemaNode(schema, value, path15) {
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: path15,
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: path15,
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, path15));
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: path15,
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, path15).length === 0
617
+ (member) => validateSchemaNode(member, value, path18).length === 0
616
618
  );
617
619
  if (!hasMatch) {
618
620
  issues.push({
619
- path: path15,
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, path15));
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: path15,
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: path15,
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: path15,
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: path15,
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: path15,
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: path15,
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: path15,
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: path15,
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: path15,
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: path15,
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: path15,
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], `${path15}[${String(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(path15, requiredKey),
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(path15, key))
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(path15, key),
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(path15, key)
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 path15 = getParsedUrl().pathname;
997
- if (!includesCaseInsensitive(path15, filters.path)) {
998
+ const path18 = getParsedUrl().pathname;
999
+ if (!includesCaseInsensitive(path18, filters.path)) {
998
1000
  return false;
999
1001
  }
1000
1002
  }
@@ -6992,9 +6994,9 @@ function compareByCreatedAtAndId(left, right) {
6992
6994
  var FilesystemRegistryStore = class {
6993
6995
  constructor(rootPath, registryRelativePath) {
6994
6996
  this.registryRelativePath = registryRelativePath;
6995
- const basePath = path7__default.default.join(rootPath, ...registryRelativePath);
6996
- this.recordsDirectory = path7__default.default.join(basePath, "records");
6997
- this.indexesDirectory = path7__default.default.join(basePath, "indexes", "by-key");
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");
6998
7000
  }
6999
7001
  recordsDirectory;
7000
7002
  indexesDirectory;
@@ -7063,7 +7065,7 @@ var FilesystemRegistryStore = class {
7063
7065
  async readRecordsFromDirectory() {
7064
7066
  const files = await listJsonFiles(this.recordsDirectory);
7065
7067
  const records = await Promise.all(
7066
- files.map((fileName) => readJsonFile(path7__default.default.join(this.recordsDirectory, fileName)))
7068
+ files.map((fileName) => readJsonFile(path10__default.default.join(this.recordsDirectory, fileName)))
7067
7069
  );
7068
7070
  records.sort(compareByCreatedAtAndId);
7069
7071
  return records;
@@ -7095,17 +7097,17 @@ var FilesystemRegistryStore = class {
7095
7097
  return record;
7096
7098
  }
7097
7099
  recordPath(id) {
7098
- return path7__default.default.join(this.recordsDirectory, `${encodePathSegment(id)}.json`);
7100
+ return path10__default.default.join(this.recordsDirectory, `${encodePathSegment(id)}.json`);
7099
7101
  }
7100
7102
  indexPath(key, version) {
7101
- return path7__default.default.join(
7103
+ return path10__default.default.join(
7102
7104
  this.indexesDirectory,
7103
7105
  encodePathSegment(key),
7104
7106
  `${encodePathSegment(version)}.json`
7105
7107
  );
7106
7108
  }
7107
7109
  writeLockPath() {
7108
- return path7__default.default.join(path7__default.default.dirname(this.recordsDirectory), ".write.lock");
7110
+ return path10__default.default.join(path10__default.default.dirname(this.recordsDirectory), ".write.lock");
7109
7111
  }
7110
7112
  };
7111
7113
  var FilesystemDescriptorRegistry = class extends FilesystemRegistryStore {
@@ -7475,7 +7477,7 @@ var SqliteSavedNetworkStore = class {
7475
7477
  directoryInitialization;
7476
7478
  databaseInitialization;
7477
7479
  constructor(rootPath) {
7478
- this.databasePath = path7__default.default.join(rootPath, "registry", "saved-network.sqlite");
7480
+ this.databasePath = path10__default.default.join(rootPath, "registry", "saved-network.sqlite");
7479
7481
  }
7480
7482
  async initialize() {
7481
7483
  await this.ensureDatabaseDirectory();
@@ -7715,7 +7717,7 @@ var SqliteSavedNetworkStore = class {
7715
7717
  }
7716
7718
  }
7717
7719
  async ensureDatabaseDirectory() {
7718
- this.directoryInitialization ??= ensureDirectory(path7__default.default.dirname(this.databasePath)).catch(
7720
+ this.directoryInitialization ??= ensureDirectory(path10__default.default.dirname(this.databasePath)).catch(
7719
7721
  (error) => {
7720
7722
  this.directoryInitialization = void 0;
7721
7723
  throw error;
@@ -8314,7 +8316,7 @@ var FilesystemObservationStoreImpl = class {
8314
8316
  constructor(rootPath, artifacts) {
8315
8317
  this.rootPath = rootPath;
8316
8318
  this.artifacts = artifacts;
8317
- this.sessionsDirectory = path7__default.default.join(this.rootPath, "observations", "sessions");
8319
+ this.sessionsDirectory = path10__default.default.join(this.rootPath, "observations", "sessions");
8318
8320
  }
8319
8321
  sessionsDirectory;
8320
8322
  redactors = /* @__PURE__ */ new Map();
@@ -8411,7 +8413,7 @@ var FilesystemObservationStoreImpl = class {
8411
8413
  ...raw.artifactIds === void 0 || raw.artifactIds.length === 0 ? {} : { artifactIds: [...raw.artifactIds] }
8412
8414
  };
8413
8415
  await writeJsonFileExclusive(
8414
- path7__default.default.join(this.sessionEventsDirectory(sessionId), eventFileName(sequence)),
8416
+ path10__default.default.join(this.sessionEventsDirectory(sessionId), eventFileName(sequence)),
8415
8417
  event
8416
8418
  );
8417
8419
  updatedAt = Math.max(updatedAt, createdAt);
@@ -8469,7 +8471,7 @@ var FilesystemObservationStoreImpl = class {
8469
8471
  }
8470
8472
  const files = await listJsonFiles(directoryPath);
8471
8473
  const events = await Promise.all(
8472
- files.map((fileName) => readJsonFile(path7__default.default.join(directoryPath, fileName)))
8474
+ files.map((fileName) => readJsonFile(path10__default.default.join(directoryPath, fileName)))
8473
8475
  );
8474
8476
  const filtered = events.filter((event) => {
8475
8477
  if (input.kind !== void 0 && event.kind !== input.kind) return false;
@@ -8496,7 +8498,7 @@ var FilesystemObservationStoreImpl = class {
8496
8498
  const files = await listJsonFiles(directoryPath);
8497
8499
  const artifacts = await Promise.all(
8498
8500
  files.map(
8499
- (fileName) => readJsonFile(path7__default.default.join(directoryPath, fileName))
8501
+ (fileName) => readJsonFile(path10__default.default.join(directoryPath, fileName))
8500
8502
  )
8501
8503
  );
8502
8504
  const filtered = artifacts.filter((artifact) => {
@@ -8559,25 +8561,25 @@ var FilesystemObservationStoreImpl = class {
8559
8561
  )).filter((value) => value !== void 0);
8560
8562
  }
8561
8563
  sessionDirectory(sessionId) {
8562
- return path7__default.default.join(this.sessionsDirectory, encodePathSegment(sessionId));
8564
+ return path10__default.default.join(this.sessionsDirectory, encodePathSegment(sessionId));
8563
8565
  }
8564
8566
  sessionManifestPath(sessionId) {
8565
- return path7__default.default.join(this.sessionDirectory(sessionId), "session.json");
8567
+ return path10__default.default.join(this.sessionDirectory(sessionId), "session.json");
8566
8568
  }
8567
8569
  sessionEventsDirectory(sessionId) {
8568
- return path7__default.default.join(this.sessionDirectory(sessionId), "events");
8570
+ return path10__default.default.join(this.sessionDirectory(sessionId), "events");
8569
8571
  }
8570
8572
  sessionArtifactsDirectory(sessionId) {
8571
- return path7__default.default.join(this.sessionDirectory(sessionId), "artifacts");
8573
+ return path10__default.default.join(this.sessionDirectory(sessionId), "artifacts");
8572
8574
  }
8573
8575
  sessionArtifactPath(sessionId, artifactId) {
8574
- return path7__default.default.join(
8576
+ return path10__default.default.join(
8575
8577
  this.sessionArtifactsDirectory(sessionId),
8576
8578
  `${encodePathSegment(artifactId)}.json`
8577
8579
  );
8578
8580
  }
8579
8581
  sessionLockPath(sessionId) {
8580
- return path7__default.default.join(this.sessionDirectory(sessionId), ".lock");
8582
+ return path10__default.default.join(this.sessionDirectory(sessionId), ".lock");
8581
8583
  }
8582
8584
  async reconcileSessionManifest(sessionId) {
8583
8585
  const session = await this.getSession(sessionId);
@@ -8605,14 +8607,14 @@ var FilesystemObservationStoreImpl = class {
8605
8607
  Promise.all(
8606
8608
  eventFiles.map(
8607
8609
  (fileName) => readJsonFile(
8608
- path7__default.default.join(this.sessionEventsDirectory(sessionId), fileName)
8610
+ path10__default.default.join(this.sessionEventsDirectory(sessionId), fileName)
8609
8611
  )
8610
8612
  )
8611
8613
  ),
8612
8614
  Promise.all(
8613
8615
  artifactFiles.map(
8614
8616
  (fileName) => readJsonFile(
8615
- path7__default.default.join(this.sessionArtifactsDirectory(sessionId), fileName)
8617
+ path10__default.default.join(this.sessionArtifactsDirectory(sessionId), fileName)
8616
8618
  )
8617
8619
  )
8618
8620
  )
@@ -8665,7 +8667,7 @@ var FilesystemTraceStore = class {
8665
8667
  constructor(rootPath, artifacts) {
8666
8668
  this.rootPath = rootPath;
8667
8669
  this.artifacts = artifacts;
8668
- this.runsDirectory = path7__default.default.join(this.rootPath, "traces", "runs");
8670
+ this.runsDirectory = path10__default.default.join(this.rootPath, "traces", "runs");
8669
8671
  }
8670
8672
  runsDirectory;
8671
8673
  async initialize() {
@@ -8742,7 +8744,7 @@ var FilesystemTraceStore = class {
8742
8744
  ...input.error === void 0 ? {} : { error: input.error }
8743
8745
  };
8744
8746
  await writeJsonFileExclusive(
8745
- path7__default.default.join(this.runEntriesDirectory(runId), sequenceFileName(sequence)),
8747
+ path10__default.default.join(this.runEntriesDirectory(runId), sequenceFileName(sequence)),
8746
8748
  entry
8747
8749
  );
8748
8750
  await writeJsonFileAtomic(this.runManifestPath(runId), {
@@ -8761,7 +8763,7 @@ var FilesystemTraceStore = class {
8761
8763
  const files = await listJsonFiles(entriesDirectory);
8762
8764
  return Promise.all(
8763
8765
  files.map(
8764
- (fileName) => readJsonFile(path7__default.default.join(entriesDirectory, fileName))
8766
+ (fileName) => readJsonFile(path10__default.default.join(entriesDirectory, fileName))
8765
8767
  )
8766
8768
  );
8767
8769
  }
@@ -8807,16 +8809,16 @@ var FilesystemTraceStore = class {
8807
8809
  return { trace, artifacts };
8808
8810
  }
8809
8811
  runDirectory(runId) {
8810
- return path7__default.default.join(this.runsDirectory, encodeURIComponent(runId));
8812
+ return path10__default.default.join(this.runsDirectory, encodeURIComponent(runId));
8811
8813
  }
8812
8814
  runEntriesDirectory(runId) {
8813
- return path7__default.default.join(this.runDirectory(runId), "entries");
8815
+ return path10__default.default.join(this.runDirectory(runId), "entries");
8814
8816
  }
8815
8817
  runManifestPath(runId) {
8816
- return path7__default.default.join(this.runDirectory(runId), "manifest.json");
8818
+ return path10__default.default.join(this.runDirectory(runId), "manifest.json");
8817
8819
  }
8818
8820
  runWriteLockPath(runId) {
8819
- return path7__default.default.join(this.runDirectory(runId), ".append.lock");
8821
+ return path10__default.default.join(this.runDirectory(runId), ".append.lock");
8820
8822
  }
8821
8823
  };
8822
8824
  function createTraceStore(rootPath, artifacts) {
@@ -8830,7 +8832,7 @@ function normalizeWorkspaceId(workspace) {
8830
8832
  return encodePathSegment(workspace);
8831
8833
  }
8832
8834
  function resolveFilesystemWorkspacePath(input) {
8833
- return path7__default.default.join(
8835
+ return path10__default.default.join(
8834
8836
  input.rootDir,
8835
8837
  ".opensteer",
8836
8838
  "workspaces",
@@ -8839,18 +8841,18 @@ function resolveFilesystemWorkspacePath(input) {
8839
8841
  }
8840
8842
  async function createFilesystemOpensteerWorkspace(options) {
8841
8843
  await ensureDirectory(options.rootPath);
8842
- const manifestPath = path7__default.default.join(options.rootPath, "workspace.json");
8843
- const browserPath = path7__default.default.join(options.rootPath, "browser");
8844
- const browserManifestPath = path7__default.default.join(browserPath, "manifest.json");
8845
- const browserUserDataDir = path7__default.default.join(browserPath, "user-data");
8846
- const livePath = path7__default.default.join(options.rootPath, "live");
8847
- const liveLocalPath = path7__default.default.join(livePath, "local.json");
8848
- const liveCloudPath = path7__default.default.join(livePath, "cloud.json");
8849
- const artifactsPath = path7__default.default.join(options.rootPath, "artifacts");
8850
- const tracesPath = path7__default.default.join(options.rootPath, "traces");
8851
- const observationsPath = path7__default.default.join(options.rootPath, "observations");
8852
- const registryPath = path7__default.default.join(options.rootPath, "registry");
8853
- const lockPath = path7__default.default.join(options.rootPath, ".lock");
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");
8854
8856
  let manifest;
8855
8857
  if (await pathExists(manifestPath)) {
8856
8858
  manifest = await readJsonFile(manifestPath);
@@ -9605,9 +9607,9 @@ var IFRAME_URL_ATTRIBUTES = /* @__PURE__ */ new Set([
9605
9607
  "poster",
9606
9608
  "ping"
9607
9609
  ]);
9608
- function buildArrayFieldPathCandidates(path15) {
9609
- const strict = path15.nodes.length ? buildPathCandidates(path15.nodes) : [];
9610
- const relaxedNodes = stripPositionClauses(path15.nodes);
9610
+ function buildArrayFieldPathCandidates(path18) {
9611
+ const strict = path18.nodes.length ? buildPathCandidates(path18.nodes) : [];
9612
+ const relaxedNodes = stripPositionClauses(path18.nodes);
9611
9613
  const relaxed = relaxedNodes.length ? buildPathCandidates(relaxedNodes) : [];
9612
9614
  return dedupeSelectors([...strict, ...relaxed]);
9613
9615
  }
@@ -10137,18 +10139,18 @@ function cloneStructuralElementAnchor(anchor) {
10137
10139
  nodes: anchor.nodes.map(clonePathNode)
10138
10140
  };
10139
10141
  }
10140
- function cloneReplayElementPath(path15) {
10142
+ function cloneReplayElementPath(path18) {
10141
10143
  return {
10142
10144
  resolution: "deterministic",
10143
- context: cloneContext(path15.context),
10144
- nodes: path15.nodes.map(clonePathNode)
10145
+ context: cloneContext(path18.context),
10146
+ nodes: path18.nodes.map(clonePathNode)
10145
10147
  };
10146
10148
  }
10147
- function cloneElementPath(path15) {
10148
- return cloneReplayElementPath(path15);
10149
+ function cloneElementPath(path18) {
10150
+ return cloneReplayElementPath(path18);
10149
10151
  }
10150
- function buildPathSelectorHint(path15) {
10151
- const nodes = path15?.nodes || [];
10152
+ function buildPathSelectorHint(path18) {
10153
+ const nodes = path18?.nodes || [];
10152
10154
  const last = nodes[nodes.length - 1];
10153
10155
  if (!last) {
10154
10156
  return "*";
@@ -10197,15 +10199,15 @@ function sanitizeStructuralElementAnchor(anchor) {
10197
10199
  nodes: sanitizeNodes(anchor.nodes)
10198
10200
  };
10199
10201
  }
10200
- function sanitizeReplayElementPath(path15) {
10202
+ function sanitizeReplayElementPath(path18) {
10201
10203
  return {
10202
10204
  resolution: "deterministic",
10203
- context: sanitizeContext(path15.context),
10204
- nodes: sanitizeNodes(path15.nodes)
10205
+ context: sanitizeContext(path18.context),
10206
+ nodes: sanitizeNodes(path18.nodes)
10205
10207
  };
10206
10208
  }
10207
- function sanitizeElementPath(path15) {
10208
- return sanitizeReplayElementPath(path15);
10209
+ function sanitizeElementPath(path18) {
10210
+ return sanitizeReplayElementPath(path18);
10209
10211
  }
10210
10212
  function buildLocalStructuralElementAnchor(index, rawTargetNode) {
10211
10213
  const targetNode = requireElementNode(index, rawTargetNode);
@@ -10328,8 +10330,8 @@ function buildTargetNotFoundMessage(domPath, diagnostics) {
10328
10330
  }
10329
10331
  return `${base} Target depth ${String(depth)}. Candidate counts: ${sample}.`;
10330
10332
  }
10331
- function buildArrayFieldCandidates(path15) {
10332
- return buildArrayFieldPathCandidates(path15);
10333
+ function buildArrayFieldCandidates(path18) {
10334
+ return buildArrayFieldPathCandidates(path18);
10333
10335
  }
10334
10336
  function firstDefinedAttribute(node, keys) {
10335
10337
  for (const key of keys) {
@@ -11865,21 +11867,21 @@ var DefaultDomRuntime = class {
11865
11867
  return match;
11866
11868
  }
11867
11869
  async resolvePathTarget(session, pageRef, rawPath, source, persist, descriptor) {
11868
- const path15 = sanitizeReplayElementPath(rawPath);
11869
- const context = await this.resolvePathContext(session, pageRef, path15.context);
11870
- const target = resolveDomPathInScope(context.index, path15.nodes, context.scope);
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);
11871
11873
  if (!target) {
11872
- throwTargetNotFound(context.index, path15.nodes, context.scope);
11874
+ throwTargetNotFound(context.index, path18.nodes, context.scope);
11873
11875
  }
11874
11876
  if (target.node.nodeRef === void 0) {
11875
11877
  throw new Error(
11876
- `resolved path "${buildPathSelectorHint(path15)}" does not point to a live element`
11878
+ `resolved path "${buildPathSelectorHint(path18)}" does not point to a live element`
11877
11879
  );
11878
11880
  }
11879
11881
  const anchor = await this.buildAnchorFromSnapshotNode(session, context.snapshot, target.node);
11880
11882
  return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
11881
11883
  ...persist === void 0 ? {} : { persist },
11882
- replayPath: path15,
11884
+ replayPath: path18,
11883
11885
  ...source === "path" || source === "descriptor" ? { selectorUsed: target.selector } : {},
11884
11886
  ...descriptor === void 0 ? {} : { descriptor }
11885
11887
  });
@@ -11900,9 +11902,9 @@ var DefaultDomRuntime = class {
11900
11902
  });
11901
11903
  }
11902
11904
  async queryAllByElementPath(session, pageRef, rawPath) {
11903
- const path15 = sanitizeReplayElementPath(rawPath);
11904
- const context = await this.resolvePathContext(session, pageRef, path15.context);
11905
- return queryAllDomPathInScope(context.index, path15.nodes, context.scope).filter(
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(
11906
11908
  (node) => node.nodeRef !== void 0
11907
11909
  ).map((node) => this.createSnapshotTarget(context.snapshot, node));
11908
11910
  }
@@ -12088,16 +12090,16 @@ var DefaultDomRuntime = class {
12088
12090
  const index = createSnapshotIndex(item.snapshot);
12089
12091
  return this.resolveFirstArrayFieldTargetInNode(index, item.node, field.path);
12090
12092
  }
12091
- resolveFirstArrayFieldTargetInNode(index, rootNode, path15) {
12092
- const normalizedPath = sanitizeElementPath(path15);
12093
+ resolveFirstArrayFieldTargetInNode(index, rootNode, path18) {
12094
+ const normalizedPath = sanitizeElementPath(path18);
12093
12095
  const selectors = buildArrayFieldCandidates(normalizedPath);
12094
12096
  if (!selectors.length) {
12095
12097
  return rootNode;
12096
12098
  }
12097
12099
  return resolveFirstWithinNodeBySelectors(index, rootNode, selectors);
12098
12100
  }
12099
- resolveUniqueArrayFieldTargetInNode(index, rootNode, path15) {
12100
- const normalizedPath = sanitizeElementPath(path15);
12101
+ resolveUniqueArrayFieldTargetInNode(index, rootNode, path18) {
12102
+ const normalizedPath = sanitizeElementPath(path18);
12101
12103
  const selectors = buildArrayFieldCandidates(normalizedPath);
12102
12104
  if (!selectors.length) {
12103
12105
  return rootNode;
@@ -12186,8 +12188,8 @@ function encodeDataPath(tokens) {
12186
12188
  }
12187
12189
  return out;
12188
12190
  }
12189
- function parseDataPath(path15) {
12190
- const input = path15.trim();
12191
+ function parseDataPath(path18) {
12192
+ const input = path18.trim();
12191
12193
  if (input.length === 0) {
12192
12194
  return [];
12193
12195
  }
@@ -12237,8 +12239,8 @@ function parseDataPath(path15) {
12237
12239
  function inflateDataPathObject(flat) {
12238
12240
  let root = {};
12239
12241
  let initialized = false;
12240
- for (const [path15, value] of Object.entries(flat)) {
12241
- const tokens = parseDataPath(path15);
12242
+ for (const [path18, value] of Object.entries(flat)) {
12243
+ const tokens = parseDataPath(path18);
12242
12244
  if (!tokens || tokens.length === 0) {
12243
12245
  continue;
12244
12246
  }
@@ -12570,8 +12572,8 @@ function buildVariantDescriptorFromCluster(descriptors) {
12570
12572
  fields: mergedFields
12571
12573
  };
12572
12574
  }
12573
- function minimizePathMatchClauses(path15, mode) {
12574
- const normalized = sanitizeElementPath(path15);
12575
+ function minimizePathMatchClauses(path18, mode) {
12576
+ const normalized = sanitizeElementPath(path18);
12575
12577
  const nodes = normalized.nodes.map((node, index) => {
12576
12578
  const isLast = index === normalized.nodes.length - 1;
12577
12579
  const attrs = node.attrs || {};
@@ -12675,8 +12677,8 @@ function seedMinimalAttrClause(attrs) {
12675
12677
  }
12676
12678
  return null;
12677
12679
  }
12678
- function relaxPathForSingleSample(path15, mode) {
12679
- const normalized = sanitizeElementPath(path15);
12680
+ function relaxPathForSingleSample(path18, mode) {
12681
+ const normalized = sanitizeElementPath(path18);
12680
12682
  const relaxedNodes = normalized.nodes.map((node, index) => {
12681
12683
  const isLast = index === normalized.nodes.length - 1;
12682
12684
  const attrs = normalizeAttrsForSingleSample(node.attrs || {});
@@ -12761,8 +12763,8 @@ function shouldKeepAttrForSingleSample(key) {
12761
12763
  }
12762
12764
  return true;
12763
12765
  }
12764
- function buildPathStructureKey(path15) {
12765
- const normalized = sanitizeElementPath(path15);
12766
+ function buildPathStructureKey(path18) {
12767
+ const normalized = sanitizeElementPath(path18);
12766
12768
  return canonicalJsonString({
12767
12769
  context: (normalized.context || []).map((hop) => ({
12768
12770
  kind: hop.kind,
@@ -12889,30 +12891,30 @@ function buildArrayItemNode(fields) {
12889
12891
  }
12890
12892
  return node;
12891
12893
  }
12892
- function insertNodeAtPath(root, path15, node) {
12893
- const tokens = parseDataPath(path15);
12894
+ function insertNodeAtPath(root, path18, node) {
12895
+ const tokens = parseDataPath(path18);
12894
12896
  if (!tokens || !tokens.length) {
12895
12897
  throw new Error(
12896
- `Invalid persisted extraction path "${path15}": expected a non-empty object path.`
12898
+ `Invalid persisted extraction path "${path18}": expected a non-empty object path.`
12897
12899
  );
12898
12900
  }
12899
12901
  if (tokens.some((token) => token.kind === "index")) {
12900
12902
  throw new Error(
12901
- `Invalid persisted extraction path "${path15}": nested array indices are not supported in cached descriptors.`
12903
+ `Invalid persisted extraction path "${path18}": nested array indices are not supported in cached descriptors.`
12902
12904
  );
12903
12905
  }
12904
12906
  let current = root;
12905
12907
  for (let index = 0; index < tokens.length; index += 1) {
12906
12908
  const token = tokens[index];
12907
12909
  if (!token || token.kind !== "prop") {
12908
- throw new Error(`Invalid persisted extraction path "${path15}": expected object segment.`);
12910
+ throw new Error(`Invalid persisted extraction path "${path18}": expected object segment.`);
12909
12911
  }
12910
12912
  const isLast = index === tokens.length - 1;
12911
12913
  if (isLast) {
12912
12914
  const existing = current[token.key];
12913
12915
  if (existing) {
12914
12916
  throw new Error(
12915
- `Conflicting persisted extraction path "${path15}" detected while building descriptor tree.`
12917
+ `Conflicting persisted extraction path "${path18}" detected while building descriptor tree.`
12916
12918
  );
12917
12919
  }
12918
12920
  current[token.key] = node;
@@ -12927,7 +12929,7 @@ function insertNodeAtPath(root, path15, node) {
12927
12929
  }
12928
12930
  if (!isPersistedObjectNode(next)) {
12929
12931
  throw new Error(
12930
- `Conflicting persisted extraction path "${path15}" detected at "${token.key}".`
12932
+ `Conflicting persisted extraction path "${path18}" detected at "${token.key}".`
12931
12933
  );
12932
12934
  }
12933
12935
  current = next;
@@ -12962,7 +12964,7 @@ function buildItemRootForArrayIndex(entries) {
12962
12964
  }
12963
12965
  const paths = entries.map(
12964
12966
  (entry) => isPersistablePathField(entry.source) ? sanitizeElementPath(entry.source.path) : null
12965
- ).filter((path15) => path15 !== null);
12967
+ ).filter((path18) => path18 !== null);
12966
12968
  if (!paths.length) {
12967
12969
  return null;
12968
12970
  }
@@ -12983,7 +12985,7 @@ function getCommonPathPrefixLength(paths) {
12983
12985
  if (!paths.length) {
12984
12986
  return 0;
12985
12987
  }
12986
- const nodeChains = paths.map((path15) => path15.nodes);
12988
+ const nodeChains = paths.map((path18) => path18.nodes);
12987
12989
  const minLength = Math.min(...nodeChains.map((nodes) => nodes.length));
12988
12990
  if (!Number.isFinite(minLength) || minLength <= 0) {
12989
12991
  return 0;
@@ -13052,30 +13054,30 @@ function mergeElementPathsByMajority(paths) {
13052
13054
  if (!paths.length) {
13053
13055
  return null;
13054
13056
  }
13055
- const normalized = paths.map((path15) => sanitizeElementPath(path15));
13057
+ const normalized = paths.map((path18) => sanitizeElementPath(path18));
13056
13058
  const contextKey = pickModeString(
13057
- normalized.map((path15) => canonicalJsonString(path15.context)),
13059
+ normalized.map((path18) => canonicalJsonString(path18.context)),
13058
13060
  1
13059
13061
  );
13060
13062
  if (!contextKey) {
13061
13063
  return null;
13062
13064
  }
13063
- const sameContext = normalized.filter((path15) => canonicalJsonString(path15.context) === contextKey);
13065
+ const sameContext = normalized.filter((path18) => canonicalJsonString(path18.context) === contextKey);
13064
13066
  if (!sameContext.length) {
13065
13067
  return null;
13066
13068
  }
13067
13069
  const targetLength = pickModeNumber(
13068
- sameContext.map((path15) => path15.nodes.length),
13070
+ sameContext.map((path18) => path18.nodes.length),
13069
13071
  1
13070
13072
  ) ?? sameContext[0]?.nodes.length ?? 0;
13071
- const aligned = sameContext.filter((path15) => path15.nodes.length === targetLength);
13073
+ const aligned = sameContext.filter((path18) => path18.nodes.length === targetLength);
13072
13074
  if (!aligned.length) {
13073
13075
  return null;
13074
13076
  }
13075
13077
  const threshold = majorityThreshold(aligned.length);
13076
13078
  const nodes = [];
13077
13079
  for (let index = 0; index < targetLength; index += 1) {
13078
- const nodesAtIndex = aligned.map((path15) => path15.nodes[index]).filter((node) => node !== void 0);
13080
+ const nodesAtIndex = aligned.map((path18) => path18.nodes[index]).filter((node) => node !== void 0);
13079
13081
  if (!nodesAtIndex.length) {
13080
13082
  return null;
13081
13083
  }
@@ -13321,8 +13323,8 @@ function clonePathContext(context) {
13321
13323
  function clonePathNodes(nodes) {
13322
13324
  return JSON.parse(JSON.stringify(nodes || []));
13323
13325
  }
13324
- function cloneElementPath2(path15) {
13325
- return JSON.parse(JSON.stringify(path15));
13326
+ function cloneElementPath2(path18) {
13327
+ return JSON.parse(JSON.stringify(path18));
13326
13328
  }
13327
13329
  function clonePersistedOpensteerExtractionNode(node) {
13328
13330
  return JSON.parse(JSON.stringify(node));
@@ -13640,8 +13642,8 @@ function collectPersistedValueNodeRefs(node) {
13640
13642
  return [
13641
13643
  {
13642
13644
  path: sanitizeElementPath(node.$path),
13643
- replacePath: (path15) => {
13644
- node.$path = sanitizeElementPath(path15);
13645
+ replacePath: (path18) => {
13646
+ node.$path = sanitizeElementPath(path18);
13645
13647
  }
13646
13648
  }
13647
13649
  ];
@@ -13655,13 +13657,13 @@ function collectPersistedValueNodeRefs(node) {
13655
13657
  }
13656
13658
  return refs;
13657
13659
  }
13658
- function hasPositionClause(path15) {
13659
- return path15.nodes.some((node) => node.match.some((clause) => clause.kind === "position"));
13660
+ function hasPositionClause(path18) {
13661
+ return path18.nodes.some((node) => node.match.some((clause) => clause.kind === "position"));
13660
13662
  }
13661
- function stripPositionClauses2(path15) {
13663
+ function stripPositionClauses2(path18) {
13662
13664
  return sanitizeElementPath({
13663
- context: path15.context,
13664
- nodes: path15.nodes.map((node) => ({
13665
+ context: path18.context,
13666
+ nodes: path18.nodes.map((node) => ({
13665
13667
  ...node,
13666
13668
  match: node.match.filter((clause) => clause.kind !== "position")
13667
13669
  }))
@@ -14071,17 +14073,57 @@ function normalizeNonEmptyString2(name, value) {
14071
14073
  function normalizeKey(value) {
14072
14074
  return String(value ?? "").trim();
14073
14075
  }
14074
- function labelForPath(path15) {
14075
- return path15.trim().length === 0 ? "$" : path15;
14076
+ function labelForPath(path18) {
14077
+ return path18.trim().length === 0 ? "$" : path18;
14076
14078
  }
14077
14079
  function sha256Hex3(value) {
14078
14080
  return crypto.createHash("sha256").update(value).digest("hex");
14079
14081
  }
14080
- util.promisify(child_process.execFile);
14081
- Math.floor(Date.now() - process.uptime() * 1e3);
14082
- ({ ...process.env});
14083
- ({
14084
- pid: process.pid});
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
+ }
14085
14127
  function isProcessRunning(pid) {
14086
14128
  try {
14087
14129
  process.kill(pid, 0);
@@ -14091,6 +14133,116 @@ function isProcessRunning(pid) {
14091
14133
  return code !== "ESRCH";
14092
14134
  }
14093
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
+ }
14094
14246
  var CHROME_SINGLETON_ARTIFACTS = [
14095
14247
  "SingletonCookie",
14096
14248
  "SingletonLock",
@@ -14101,7 +14253,7 @@ var CHROME_SINGLETON_ARTIFACTS = [
14101
14253
  async function clearChromeSingletonEntries(userDataDir) {
14102
14254
  await Promise.all(
14103
14255
  CHROME_SINGLETON_ARTIFACTS.map(
14104
- (entry) => promises.rm(path7.join(userDataDir, entry), {
14256
+ (entry) => promises.rm(path10.join(userDataDir, entry), {
14105
14257
  recursive: true,
14106
14258
  force: true
14107
14259
  }).catch(() => void 0)
@@ -14116,7 +14268,7 @@ async function sanitizeChromeProfile(userDataDir) {
14116
14268
  await Promise.all(profileDirs.map((dir) => sanitizeProfilePreferences(userDataDir, dir)));
14117
14269
  }
14118
14270
  async function sanitizeProfilePreferences(userDataDir, profileDir) {
14119
- const prefsPath = path7.join(userDataDir, profileDir, "Preferences");
14271
+ const prefsPath = path10.join(userDataDir, profileDir, "Preferences");
14120
14272
  try {
14121
14273
  const raw = await promises.readFile(prefsPath, "utf8");
14122
14274
  const prefs = JSON.parse(raw);
@@ -14128,7 +14280,7 @@ async function sanitizeProfilePreferences(userDataDir, profileDir) {
14128
14280
  profile.exited_cleanly = true;
14129
14281
  prefs.profile = profile;
14130
14282
  await promises.writeFile(prefsPath, JSON.stringify(prefs), "utf8");
14131
- await promises.rm(path7.join(userDataDir, profileDir, "Secure Preferences"), { force: true }).catch(
14283
+ await promises.rm(path10.join(userDataDir, profileDir, "Secure Preferences"), { force: true }).catch(
14132
14284
  () => void 0
14133
14285
  );
14134
14286
  } catch {
@@ -14149,9 +14301,9 @@ var BROWSER_BRANDS = [
14149
14301
  },
14150
14302
  win32: {
14151
14303
  executableCandidates: [
14152
- path7.join(WINDOWS_PROGRAM_FILES, "Google", "Chrome", "Application", "chrome.exe"),
14153
- path7.join(WINDOWS_PROGRAM_FILES_X86, "Google", "Chrome", "Application", "chrome.exe"),
14154
- path7.join("~", "AppData", "Local", "Google", "Chrome", "Application", "chrome.exe")
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")
14155
14307
  ],
14156
14308
  userDataDir: "~/AppData/Local/Google/Chrome/User Data",
14157
14309
  processNames: ["/google/chrome/application/chrome.exe"]
@@ -14181,7 +14333,7 @@ var BROWSER_BRANDS = [
14181
14333
  },
14182
14334
  win32: {
14183
14335
  executableCandidates: [
14184
- path7.join("~", "AppData", "Local", "Google", "Chrome SxS", "Application", "chrome.exe")
14336
+ path10.join("~", "AppData", "Local", "Google", "Chrome SxS", "Application", "chrome.exe")
14185
14337
  ],
14186
14338
  userDataDir: "~/AppData/Local/Google/Chrome SxS/User Data",
14187
14339
  processNames: ["/google/chrome sxs/application/chrome.exe"]
@@ -14198,9 +14350,9 @@ var BROWSER_BRANDS = [
14198
14350
  },
14199
14351
  win32: {
14200
14352
  executableCandidates: [
14201
- path7.join(WINDOWS_PROGRAM_FILES, "Chromium", "Application", "chrome.exe"),
14202
- path7.join(WINDOWS_PROGRAM_FILES_X86, "Chromium", "Application", "chrome.exe"),
14203
- path7.join("~", "AppData", "Local", "Chromium", "Application", "chrome.exe")
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")
14204
14356
  ],
14205
14357
  userDataDir: "~/AppData/Local/Chromium/User Data",
14206
14358
  processNames: ["/chromium/application/chrome.exe"]
@@ -14227,15 +14379,15 @@ var BROWSER_BRANDS = [
14227
14379
  },
14228
14380
  win32: {
14229
14381
  executableCandidates: [
14230
- path7.join(WINDOWS_PROGRAM_FILES, "BraveSoftware", "Brave-Browser", "Application", "brave.exe"),
14231
- path7.join(
14382
+ path10.join(WINDOWS_PROGRAM_FILES, "BraveSoftware", "Brave-Browser", "Application", "brave.exe"),
14383
+ path10.join(
14232
14384
  WINDOWS_PROGRAM_FILES_X86,
14233
14385
  "BraveSoftware",
14234
14386
  "Brave-Browser",
14235
14387
  "Application",
14236
14388
  "brave.exe"
14237
14389
  ),
14238
- path7.join("~", "AppData", "Local", "BraveSoftware", "Brave-Browser", "Application", "brave.exe")
14390
+ path10.join("~", "AppData", "Local", "BraveSoftware", "Brave-Browser", "Application", "brave.exe")
14239
14391
  ],
14240
14392
  userDataDir: "~/AppData/Local/BraveSoftware/Brave-Browser/User Data",
14241
14393
  processNames: ["/bravesoftware/brave-browser/application/brave.exe"]
@@ -14261,9 +14413,9 @@ var BROWSER_BRANDS = [
14261
14413
  },
14262
14414
  win32: {
14263
14415
  executableCandidates: [
14264
- path7.join(WINDOWS_PROGRAM_FILES, "Microsoft", "Edge", "Application", "msedge.exe"),
14265
- path7.join(WINDOWS_PROGRAM_FILES_X86, "Microsoft", "Edge", "Application", "msedge.exe"),
14266
- path7.join("~", "AppData", "Local", "Microsoft", "Edge", "Application", "msedge.exe")
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")
14267
14419
  ],
14268
14420
  userDataDir: "~/AppData/Local/Microsoft/Edge/User Data",
14269
14421
  processNames: ["/microsoft/edge/application/msedge.exe"]
@@ -14291,9 +14443,9 @@ var BROWSER_BRANDS = [
14291
14443
  },
14292
14444
  win32: {
14293
14445
  executableCandidates: [
14294
- path7.join(WINDOWS_PROGRAM_FILES, "Vivaldi", "Application", "vivaldi.exe"),
14295
- path7.join(WINDOWS_PROGRAM_FILES_X86, "Vivaldi", "Application", "vivaldi.exe"),
14296
- path7.join("~", "AppData", "Local", "Vivaldi", "Application", "vivaldi.exe")
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")
14297
14449
  ],
14298
14450
  userDataDir: "~/AppData/Local/Vivaldi/User Data",
14299
14451
  processNames: ["/vivaldi/application/vivaldi.exe"]
@@ -14357,35 +14509,35 @@ function detectInstalledBrowserBrands() {
14357
14509
  brandId: brand2.id,
14358
14510
  displayName: brand2.displayName,
14359
14511
  executablePath,
14360
- userDataDir: path7.resolve(expandHome(platformConfig.userDataDir))
14512
+ userDataDir: path10.resolve(expandHome(platformConfig.userDataDir))
14361
14513
  });
14362
14514
  }
14363
14515
  return installations;
14364
14516
  }
14365
14517
  function resolveBrandUserDataDir(brand2, explicitDir) {
14366
14518
  if (explicitDir !== void 0) {
14367
- return path7.resolve(expandHome(explicitDir));
14519
+ return path10.resolve(expandHome(explicitDir));
14368
14520
  }
14369
14521
  const platformConfig = resolveBrandPlatformConfig(brand2);
14370
14522
  if (!platformConfig) {
14371
14523
  throw new Error(`${brand2.displayName} is not supported on ${process.platform}.`);
14372
14524
  }
14373
- return path7.resolve(expandHome(platformConfig.userDataDir));
14525
+ return path10.resolve(expandHome(platformConfig.userDataDir));
14374
14526
  }
14375
14527
  function resolveExecutableCandidates(candidates) {
14376
- return candidates.map((candidate) => candidate ? path7.resolve(expandHome(candidate)) : null);
14528
+ return candidates.map((candidate) => candidate ? path10.resolve(expandHome(candidate)) : null);
14377
14529
  }
14378
14530
 
14379
14531
  // src/local-browser/chrome-discovery.ts
14380
14532
  function expandHome(value) {
14381
14533
  if (value === "~" || value.startsWith("~/")) {
14382
- return path7.join(os.homedir(), value.slice(1));
14534
+ return path10.join(os.homedir(), value.slice(1));
14383
14535
  }
14384
14536
  return value;
14385
14537
  }
14386
14538
  function resolveChromeUserDataDir(userDataDir) {
14387
14539
  const installation = detectLocalChromeInstallations().find(
14388
- (candidate) => fs.existsSync(path7.join(candidate.userDataDir, "Local State")) || candidate.executablePath !== null
14540
+ (candidate) => fs.existsSync(path10.join(candidate.userDataDir, "Local State")) || candidate.executablePath !== null
14389
14541
  );
14390
14542
  if (!installation) {
14391
14543
  throw new Error("Could not find a local Chrome or Chromium profile directory.");
@@ -14394,7 +14546,7 @@ function resolveChromeUserDataDir(userDataDir) {
14394
14546
  }
14395
14547
  function resolveChromeExecutablePath(executablePath) {
14396
14548
  if (executablePath !== void 0) {
14397
- const resolvedPath = path7.resolve(expandHome(executablePath));
14549
+ const resolvedPath = path10.resolve(expandHome(executablePath));
14398
14550
  if (!fs.existsSync(resolvedPath)) {
14399
14551
  throw new Error(`Chrome executable was not found at "${resolvedPath}".`);
14400
14552
  }
@@ -14418,37 +14570,37 @@ function detectLocalChromeInstallations() {
14418
14570
  "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
14419
14571
  "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"
14420
14572
  ]),
14421
- userDataDir: path7.join(os.homedir(), "Library", "Application Support", "Google", "Chrome")
14573
+ userDataDir: path10.join(os.homedir(), "Library", "Application Support", "Google", "Chrome")
14422
14574
  },
14423
14575
  {
14424
14576
  brand: "chromium",
14425
14577
  executablePath: firstExistingPath(["/Applications/Chromium.app/Contents/MacOS/Chromium"]),
14426
- userDataDir: path7.join(os.homedir(), "Library", "Application Support", "Chromium")
14578
+ userDataDir: path10.join(os.homedir(), "Library", "Application Support", "Chromium")
14427
14579
  }
14428
14580
  ];
14429
14581
  }
14430
14582
  if (process.platform === "win32") {
14431
14583
  const programFiles = process.env.PROGRAMFILES ?? "C:\\Program Files";
14432
14584
  const programFilesX86 = process.env["PROGRAMFILES(X86)"] ?? "C:\\Program Files (x86)";
14433
- const localAppData = process.env.LOCALAPPDATA ?? path7.join(os.homedir(), "AppData", "Local");
14585
+ const localAppData = process.env.LOCALAPPDATA ?? path10.join(os.homedir(), "AppData", "Local");
14434
14586
  return [
14435
14587
  {
14436
14588
  brand: "chrome",
14437
14589
  executablePath: firstExistingPath([
14438
- path7.join(programFiles, "Google", "Chrome", "Application", "chrome.exe"),
14439
- path7.join(programFilesX86, "Google", "Chrome", "Application", "chrome.exe"),
14440
- path7.join(localAppData, "Google", "Chrome", "Application", "chrome.exe")
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")
14441
14593
  ]),
14442
- userDataDir: path7.join(localAppData, "Google", "Chrome", "User Data")
14594
+ userDataDir: path10.join(localAppData, "Google", "Chrome", "User Data")
14443
14595
  },
14444
14596
  {
14445
14597
  brand: "chromium",
14446
14598
  executablePath: firstExistingPath([
14447
- path7.join(programFiles, "Chromium", "Application", "chrome.exe"),
14448
- path7.join(programFilesX86, "Chromium", "Application", "chrome.exe"),
14449
- path7.join(localAppData, "Chromium", "Application", "chrome.exe")
14599
+ path10.join(programFiles, "Chromium", "Application", "chrome.exe"),
14600
+ path10.join(programFilesX86, "Chromium", "Application", "chrome.exe"),
14601
+ path10.join(localAppData, "Chromium", "Application", "chrome.exe")
14450
14602
  ]),
14451
- userDataDir: path7.join(localAppData, "Chromium", "User Data")
14603
+ userDataDir: path10.join(localAppData, "Chromium", "User Data")
14452
14604
  }
14453
14605
  ];
14454
14606
  }
@@ -14461,7 +14613,7 @@ function detectLocalChromeInstallations() {
14461
14613
  resolveBinaryFromPath("google-chrome"),
14462
14614
  resolveBinaryFromPath("google-chrome-stable")
14463
14615
  ]),
14464
- userDataDir: path7.join(os.homedir(), ".config", "google-chrome")
14616
+ userDataDir: path10.join(os.homedir(), ".config", "google-chrome")
14465
14617
  },
14466
14618
  {
14467
14619
  brand: "chromium",
@@ -14471,7 +14623,7 @@ function detectLocalChromeInstallations() {
14471
14623
  resolveBinaryFromPath("chromium"),
14472
14624
  resolveBinaryFromPath("chromium-browser")
14473
14625
  ]),
14474
- userDataDir: path7.join(os.homedir(), ".config", "chromium")
14626
+ userDataDir: path10.join(os.homedir(), ".config", "chromium")
14475
14627
  }
14476
14628
  ];
14477
14629
  }
@@ -14483,8 +14635,8 @@ function detectLocalBrowserInstallations() {
14483
14635
  }));
14484
14636
  }
14485
14637
  function listLocalChromeProfiles(userDataDir = resolveChromeUserDataDir()) {
14486
- const resolvedUserDataDir = path7.resolve(expandHome(userDataDir));
14487
- const localStatePath = path7.join(resolvedUserDataDir, "Local State");
14638
+ const resolvedUserDataDir = path10.resolve(expandHome(userDataDir));
14639
+ const localStatePath = path10.join(resolvedUserDataDir, "Local State");
14488
14640
  if (!fs.existsSync(localStatePath)) {
14489
14641
  return [];
14490
14642
  }
@@ -14496,7 +14648,7 @@ function listLocalChromeProfiles(userDataDir = resolveChromeUserDataDir()) {
14496
14648
  }
14497
14649
  return Object.entries(infoCache).map(([directory, info]) => {
14498
14650
  const record = info && typeof info === "object" && !Array.isArray(info) ? info : {};
14499
- const name = typeof record.name === "string" && record.name.trim().length > 0 ? record.name.trim() : directory || path7.basename(directory);
14651
+ const name = typeof record.name === "string" && record.name.trim().length > 0 ? record.name.trim() : directory || path10.basename(directory);
14500
14652
  return {
14501
14653
  directory,
14502
14654
  name,
@@ -14508,7 +14660,7 @@ function listLocalChromeProfiles(userDataDir = resolveChromeUserDataDir()) {
14508
14660
  }
14509
14661
  }
14510
14662
  function readDevToolsActivePort(userDataDir) {
14511
- const devToolsPath = path7.join(userDataDir, "DevToolsActivePort");
14663
+ const devToolsPath = path10.join(userDataDir, "DevToolsActivePort");
14512
14664
  if (!fs.existsSync(devToolsPath)) {
14513
14665
  return null;
14514
14666
  }
@@ -14741,8 +14893,8 @@ function buildBrowserWebSocketUrl(httpUrl, webSocketPath) {
14741
14893
  const protocol = httpUrl.protocol === "https:" ? "wss:" : "ws:";
14742
14894
  return `${protocol}//${httpUrl.host}${normalizeWebSocketPath(webSocketPath)}`;
14743
14895
  }
14744
- function normalizeWebSocketPath(path15) {
14745
- return path15.startsWith("/") ? path15 : `/${path15}`;
14896
+ function normalizeWebSocketPath(path18) {
14897
+ return path18.startsWith("/") ? path18 : `/${path18}`;
14746
14898
  }
14747
14899
  function rewriteBrowserWebSocketHost(browserWsUrl, requestedUrl) {
14748
14900
  try {
@@ -14788,20 +14940,20 @@ var SESSION_SKIPPED_PROFILE_DIRECTORIES = /* @__PURE__ */ new Set([
14788
14940
  "Network"
14789
14941
  ]);
14790
14942
  async function createBrowserProfileSnapshot(input) {
14791
- const sourceUserDataDir = path7.resolve(expandHome(input.sourceUserDataDir));
14792
- const targetUserDataDir = path7.resolve(expandHome(input.targetUserDataDir));
14943
+ const sourceUserDataDir = path10.resolve(expandHome(input.sourceUserDataDir));
14944
+ const targetUserDataDir = path10.resolve(expandHome(input.targetUserDataDir));
14793
14945
  const profileDirectory = input.profileDirectory?.trim();
14794
14946
  const copyMode = input.copyMode;
14795
14947
  await promises.mkdir(targetUserDataDir, { recursive: true });
14796
14948
  await clearChromeSingletonEntries(targetUserDataDir);
14797
14949
  if (profileDirectory) {
14798
- const sourceProfileDir = path7.join(sourceUserDataDir, profileDirectory);
14950
+ const sourceProfileDir = path10.join(sourceUserDataDir, profileDirectory);
14799
14951
  if (!fs.existsSync(sourceProfileDir)) {
14800
14952
  throw new Error(
14801
14953
  `Chrome profile "${profileDirectory}" was not found in "${sourceUserDataDir}".`
14802
14954
  );
14803
14955
  }
14804
- await promises.cp(sourceProfileDir, path7.join(targetUserDataDir, profileDirectory), {
14956
+ await promises.cp(sourceProfileDir, path10.join(targetUserDataDir, profileDirectory), {
14805
14957
  recursive: true,
14806
14958
  filter: (candidate) => shouldCopyEntry({
14807
14959
  candidatePath: candidate,
@@ -14825,8 +14977,8 @@ async function copyRootLevelEntries(input) {
14825
14977
  if (CHROME_SINGLETON_ENTRIES.has(entry) || entry === input.selectedProfileDirectory) {
14826
14978
  continue;
14827
14979
  }
14828
- const sourcePath = path7.join(input.sourceUserDataDir, entry);
14829
- const targetPath = path7.join(input.targetUserDataDir, entry);
14980
+ const sourcePath = path10.join(input.sourceUserDataDir, entry);
14981
+ const targetPath = path10.join(input.targetUserDataDir, entry);
14830
14982
  const entryStat = await promises.stat(sourcePath).catch(() => null);
14831
14983
  if (!entryStat) {
14832
14984
  continue;
@@ -14858,7 +15010,7 @@ async function copyRootLevelEntries(input) {
14858
15010
  }
14859
15011
  }
14860
15012
  function isProfileDirectory(userDataDir, entry) {
14861
- return fs.existsSync(path7.join(userDataDir, entry, "Preferences"));
15013
+ return fs.existsSync(path10.join(userDataDir, entry, "Preferences"));
14862
15014
  }
14863
15015
  function shouldCopyEntry(input) {
14864
15016
  const entryName = input.candidatePath.split("/").at(-1)?.split("\\").at(-1) ?? input.candidatePath;
@@ -14868,7 +15020,7 @@ function shouldCopyEntry(input) {
14868
15020
  if (input.copyMode !== "session") {
14869
15021
  return true;
14870
15022
  }
14871
- const relativePath = path7.relative(input.rootPath, input.candidatePath);
15023
+ const relativePath = path10.relative(input.rootPath, input.candidatePath);
14872
15024
  if (relativePath.length === 0) {
14873
15025
  return true;
14874
15026
  }
@@ -15350,7 +15502,7 @@ function pickStealthProfilePreset(overrides) {
15350
15502
  var OPENSTEER_LIVE_SESSION_LAYOUT = "opensteer-session";
15351
15503
  var OPENSTEER_LIVE_SESSION_VERSION = 1;
15352
15504
  function resolveLiveSessionRecordPath(rootPath, provider) {
15353
- return path7__default.default.join(rootPath, "live", provider === "local" ? "local.json" : "cloud.json");
15505
+ return path10__default.default.join(rootPath, "live", provider === "local" ? "local.json" : "cloud.json");
15354
15506
  }
15355
15507
  function resolveLocalSessionRecordPath(rootPath) {
15356
15508
  return resolveLiveSessionRecordPath(rootPath, "local");
@@ -15392,6 +15544,446 @@ function isPersistedCloudSessionRecord(value) {
15392
15544
  function isPersistedLocalBrowserSessionRecord(value) {
15393
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;
15394
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
+ }
15925
+ }
15926
+ function delay(ms) {
15927
+ return new Promise((resolve4) => {
15928
+ setTimeout(resolve4, ms);
15929
+ });
15930
+ }
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)}`;
15938
+ }
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
+ };
15956
+ }
15957
+ async function writeLocalViewSessionManifest(manifest) {
15958
+ await ensureDirectory(resolveLocalViewSessionsDir());
15959
+ await writeJsonFileAtomic(resolveLocalViewSessionManifestPath(manifest.sessionId), manifest);
15960
+ }
15961
+ async function deleteLocalViewSessionManifest(sessionId) {
15962
+ await promises.rm(resolveLocalViewSessionManifestPath(sessionId), { force: true }).catch(() => void 0);
15963
+ }
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);
15986
+ }
15395
15987
 
15396
15988
  // ../runtime-core/src/internal/engine-selection.ts
15397
15989
  var OPENSTEER_ENGINE_NAMES = ["playwright", "abp"];
@@ -15510,8 +16102,8 @@ var OpensteerBrowserManager = class {
15510
16102
  ...options.browser === void 0 ? {} : { browser: options.browser },
15511
16103
  ...this.contextOptions === void 0 ? {} : { context: this.contextOptions }
15512
16104
  });
15513
- this.rootPath = options.rootPath ?? (this.workspace === void 0 ? path7__default.default.join(os.tmpdir(), `${TEMPORARY_WORKSPACE_PREFIX}${crypto.randomUUID()}`) : resolveFilesystemWorkspacePath({
15514
- rootDir: path7__default.default.resolve(options.rootDir ?? process.cwd()),
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()),
15515
16107
  workspace: this.workspace
15516
16108
  }));
15517
16109
  this.cleanupRootOnDisconnect = this.workspace === void 0;
@@ -15572,7 +16164,7 @@ var OpensteerBrowserManager = class {
15572
16164
  userDataDir: "browser/user-data",
15573
16165
  bootstrap: {
15574
16166
  kind: "cloneLocalProfile",
15575
- sourceUserDataDir: path7__default.default.resolve(input.sourceUserDataDir),
16167
+ sourceUserDataDir: path10__default.default.resolve(input.sourceUserDataDir),
15576
16168
  ...input.sourceProfileDirectory === void 0 ? {} : { sourceProfileDirectory: input.sourceProfileDirectory }
15577
16169
  }
15578
16170
  };
@@ -15645,6 +16237,12 @@ var OpensteerBrowserManager = class {
15645
16237
  `workspace "${this.workspace}" already has a live ${live.engine} browser. Close it before reopening with engine "abp".`
15646
16238
  );
15647
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
+ });
15648
16246
  return this.createAdoptedAbpEngine(live);
15649
16247
  }
15650
16248
  await this.ensurePersistentBrowserManifest(workspace);
@@ -15677,9 +16275,17 @@ var OpensteerBrowserManager = class {
15677
16275
  ...launch?.browserExecutablePath === void 0 ? {} : { executablePath: launch.browserExecutablePath }
15678
16276
  };
15679
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
+ });
15680
16285
  try {
15681
16286
  return await this.createAdoptedAbpEngine(liveRecord);
15682
16287
  } catch (error) {
16288
+ await this.unregisterLocalViewSessionForRecord(workspace.rootPath, persistedLiveRecord);
15683
16289
  await terminateProcess(launched.process.pid ?? 0).catch(() => void 0);
15684
16290
  await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
15685
16291
  throw error;
@@ -15699,23 +16305,45 @@ var OpensteerBrowserManager = class {
15699
16305
  });
15700
16306
  }
15701
16307
  async createTemporaryEngine() {
15702
- const userDataDir = await promises.mkdtemp(path7__default.default.join(os.tmpdir(), "opensteer-temporary-browser-"));
16308
+ const userDataDir = await promises.mkdtemp(path10__default.default.join(os.tmpdir(), "opensteer-temporary-browser-"));
15703
16309
  await clearChromeSingletonEntries(userDataDir);
15704
16310
  const launched = await launchOwnedBrowser({
15705
16311
  userDataDir,
15706
16312
  ...this.launchOptions === void 0 ? {} : { launch: this.launchOptions },
15707
16313
  ...this.contextOptions?.viewport === void 0 ? {} : { viewport: this.contextOptions.viewport }
15708
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
+ });
15709
16333
  try {
15710
16334
  return await this.createAttachedEngine({
15711
16335
  endpoint: launched.endpoint,
15712
16336
  freshTab: false,
15713
16337
  onDispose: async () => {
16338
+ await bestEffortUnregisterLocalViewSession(localViewManifest?.sessionId);
16339
+ await clearPersistedSessionRecord(this.rootPath, "local").catch(() => void 0);
15714
16340
  await terminateProcess(launched.pid).catch(() => void 0);
15715
16341
  await promises.rm(userDataDir, { recursive: true, force: true }).catch(() => void 0);
15716
16342
  }
15717
16343
  });
15718
16344
  } catch (error) {
16345
+ await bestEffortUnregisterLocalViewSession(localViewManifest?.sessionId);
16346
+ await clearPersistedSessionRecord(this.rootPath, "local").catch(() => void 0);
15719
16347
  await terminateProcess(launched.pid).catch(() => void 0);
15720
16348
  await promises.rm(userDataDir, { recursive: true, force: true }).catch(() => void 0);
15721
16349
  throw error;
@@ -15743,6 +16371,12 @@ var OpensteerBrowserManager = class {
15743
16371
  if (live.endpoint === void 0) {
15744
16372
  throw new Error("workspace live browser record is missing a DevTools endpoint.");
15745
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
+ });
15746
16380
  return this.createAttachedEngine({
15747
16381
  endpoint: live.endpoint,
15748
16382
  freshTab: false,
@@ -15765,6 +16399,13 @@ var OpensteerBrowserManager = class {
15765
16399
  userDataDir: workspace.browserUserDataDir
15766
16400
  };
15767
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
+ });
15768
16409
  try {
15769
16410
  return await this.createAttachedEngine({
15770
16411
  endpoint: launched.endpoint,
@@ -15772,6 +16413,7 @@ var OpensteerBrowserManager = class {
15772
16413
  onDispose: async () => void 0
15773
16414
  });
15774
16415
  } catch (error) {
16416
+ await this.unregisterLocalViewSessionForRecord(workspace.rootPath, persistedLiveRecord);
15775
16417
  await terminateProcess(launched.pid).catch(() => void 0);
15776
16418
  await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
15777
16419
  throw error;
@@ -15922,6 +16564,10 @@ var OpensteerBrowserManager = class {
15922
16564
  await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
15923
16565
  return;
15924
16566
  }
16567
+ await this.unregisterLocalViewSessionForRecord(
16568
+ workspace.rootPath,
16569
+ toPersistedLocalBrowserSessionRecord(this.workspace, live)
16570
+ );
15925
16571
  if (live.engine === "playwright") {
15926
16572
  if (live.endpoint !== void 0) {
15927
16573
  await requestBrowserClose(live.endpoint).catch(() => void 0);
@@ -15948,6 +16594,15 @@ var OpensteerBrowserManager = class {
15948
16594
  throw new Error(`browser.${method}() requires a persistent workspace browser.`);
15949
16595
  }
15950
16596
  }
16597
+ async unregisterLocalViewSessionForRecord(rootPath, record) {
16598
+ await bestEffortUnregisterLocalViewSession(
16599
+ buildLocalViewSessionId({
16600
+ rootPath,
16601
+ pid: record.pid,
16602
+ startedAt: record.startedAt
16603
+ })
16604
+ );
16605
+ }
15951
16606
  };
15952
16607
  function normalizeWorkspace(workspace) {
15953
16608
  const normalized = workspace?.trim();
@@ -16113,7 +16768,7 @@ async function waitForDevToolsEndpoint(input) {
16113
16768
  if (exitCode !== null) {
16114
16769
  throw new Error(formatChromeLaunchError(input.stderrLines));
16115
16770
  }
16116
- await sleep(DEVTOOLS_POLL_INTERVAL_MS);
16771
+ await sleep2(DEVTOOLS_POLL_INTERVAL_MS);
16117
16772
  }
16118
16773
  throw new Error(formatChromeLaunchError(input.stderrLines));
16119
16774
  }
@@ -16261,12 +16916,12 @@ async function waitForProcessExit(pid, timeoutMs) {
16261
16916
  if (!isProcessRunning(pid)) {
16262
16917
  return true;
16263
16918
  }
16264
- await sleep(50);
16919
+ await sleep2(50);
16265
16920
  }
16266
16921
  return !isProcessRunning(pid);
16267
16922
  }
16268
16923
  function resolveAbpSessionDir(workspace) {
16269
- return path7__default.default.join(workspace.livePath, "abp-session");
16924
+ return path10__default.default.join(workspace.livePath, "abp-session");
16270
16925
  }
16271
16926
  async function allocateEphemeralPort() {
16272
16927
  const { allocatePort } = await loadAbpModule();
@@ -16323,14 +16978,14 @@ function resolveStealthProfile(input) {
16323
16978
  function isStealthProfile(input) {
16324
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;
16325
16980
  }
16326
- async function sleep(ms) {
16981
+ async function sleep2(ms) {
16327
16982
  await new Promise((resolve4) => setTimeout(resolve4, ms));
16328
16983
  }
16329
16984
  var ENV_FILENAMES = [".env", ".env.local"];
16330
16985
  var OPENSTEER_ENV_PREFIX = "OPENSTEER_";
16331
16986
  var opensteerEnvironmentCache = /* @__PURE__ */ new Map();
16332
16987
  function resolveOpensteerEnvironment(cwd = process.cwd(), baseEnv = process.env) {
16333
- const resolvedCwd = path7__default.default.resolve(cwd);
16988
+ const resolvedCwd = path10__default.default.resolve(cwd);
16334
16989
  const signature = buildEnvironmentSignature(baseEnv, isOpensteerEnvironmentKey);
16335
16990
  const cached = opensteerEnvironmentCache.get(resolvedCwd);
16336
16991
  if (cached && cached.signature === signature) {
@@ -16345,10 +17000,10 @@ function resolveOpensteerEnvironment(cwd = process.cwd(), baseEnv = process.env)
16345
17000
  }
16346
17001
  function collectDirectories(cwd) {
16347
17002
  const directories = [];
16348
- let current = path7__default.default.resolve(cwd);
17003
+ let current = path10__default.default.resolve(cwd);
16349
17004
  for (; ; ) {
16350
17005
  directories.unshift(current);
16351
- const parent = path7__default.default.dirname(current);
17006
+ const parent = path10__default.default.dirname(current);
16352
17007
  if (parent === current) {
16353
17008
  return directories;
16354
17009
  }
@@ -16391,7 +17046,7 @@ function resolveEnvironmentFiles(cwd, baseEnv, predicate) {
16391
17046
  const directories = collectDirectories(cwd);
16392
17047
  for (const directory of directories) {
16393
17048
  for (const filename of ENV_FILENAMES) {
16394
- const filePath = path7__default.default.join(directory, filename);
17049
+ const filePath = path10__default.default.join(directory, filename);
16395
17050
  if (!fs.existsSync(filePath)) {
16396
17051
  continue;
16397
17052
  }
@@ -16470,17 +17125,17 @@ async function readBrowserCookies(input = {}) {
16470
17125
  const brand2 = resolveRequestedBrand(input);
16471
17126
  const userDataDir = resolveBrandUserDataDir(brand2, input.userDataDir);
16472
17127
  const profileDirectory = input.profileDirectory ?? "Default";
16473
- const cookiesPath = path7.join(userDataDir, profileDirectory, "Cookies");
17128
+ const cookiesPath = path10.join(userDataDir, profileDirectory, "Cookies");
16474
17129
  if (!fs.existsSync(cookiesPath)) {
16475
17130
  throw new Error(
16476
17131
  `Cookies database not found at "${cookiesPath}". Verify the browser brand, user-data-dir, and profile-directory are correct.`
16477
17132
  );
16478
17133
  }
16479
- const tempDir = await promises.mkdtemp(path7.join(os.tmpdir(), "opensteer-cookies-"));
17134
+ const tempDir = await promises.mkdtemp(path10.join(os.tmpdir(), "opensteer-cookies-"));
16480
17135
  try {
16481
17136
  await copyCookiesDatabase(cookiesPath, tempDir);
16482
17137
  const decryptionKey = await resolveDecryptionKey(brand2.id, userDataDir);
16483
- const rows = queryAllCookies(path7.join(tempDir, "Cookies"));
17138
+ const rows = queryAllCookies(path10.join(tempDir, "Cookies"));
16484
17139
  const cookies = decryptCookieRows(rows, decryptionKey);
16485
17140
  return {
16486
17141
  cookies,
@@ -16506,11 +17161,11 @@ function resolveRequestedBrand(input) {
16506
17161
  return installed.brand;
16507
17162
  }
16508
17163
  async function copyCookiesDatabase(cookiesPath, destDir) {
16509
- await promises.copyFile(cookiesPath, path7.join(destDir, "Cookies"));
17164
+ await promises.copyFile(cookiesPath, path10.join(destDir, "Cookies"));
16510
17165
  for (const suffix of ["-wal", "-journal", "-shm"]) {
16511
17166
  const src = cookiesPath + suffix;
16512
17167
  if (fs.existsSync(src)) {
16513
- await promises.copyFile(src, path7.join(destDir, "Cookies" + suffix)).catch(() => void 0);
17168
+ await promises.copyFile(src, path10.join(destDir, "Cookies" + suffix)).catch(() => void 0);
16514
17169
  }
16515
17170
  }
16516
17171
  }
@@ -16587,7 +17242,7 @@ async function resolveKeychainPassword(brandId) {
16587
17242
  }
16588
17243
  }
16589
17244
  async function resolveWindowsMasterKey(userDataDir) {
16590
- const localStatePath = path7.join(userDataDir, "Local State");
17245
+ const localStatePath = path10.join(userDataDir, "Local State");
16591
17246
  let localState;
16592
17247
  try {
16593
17248
  localState = JSON.parse(await promises.readFile(localStatePath, "utf8"));
@@ -16788,14 +17443,14 @@ function toPortableBrowserProfileCookieRecord(cookie) {
16788
17443
  if (!name || !domain) {
16789
17444
  return null;
16790
17445
  }
16791
- const path15 = typeof cookie.path === "string" && cookie.path.trim().length > 0 ? cookie.path : "/";
17446
+ const path18 = typeof cookie.path === "string" && cookie.path.trim().length > 0 ? cookie.path : "/";
16792
17447
  const expiresAt = typeof cookie.expires === "number" && Number.isFinite(cookie.expires) && cookie.expires > 0 ? Math.floor(cookie.expires * 1e3) : null;
16793
17448
  const sameSite = normalizeSameSite(cookie.sameSite);
16794
17449
  return {
16795
17450
  name,
16796
17451
  value: cookie.value,
16797
17452
  domain,
16798
- path: path15,
17453
+ path: path18,
16799
17454
  secure: cookie.secure,
16800
17455
  httpOnly: cookie.httpOnly,
16801
17456
  ...sameSite === void 0 ? {} : { sameSite },
@@ -16864,7 +17519,7 @@ async function waitForBrowserProfileImport(client, importId) {
16864
17519
  if (current.status === "failed") {
16865
17520
  throw new Error(current.error ?? "Browser profile sync failed.");
16866
17521
  }
16867
- await sleep2(DEFAULT_POLL_INTERVAL_MS);
17522
+ await sleep3(DEFAULT_POLL_INTERVAL_MS);
16868
17523
  }
16869
17524
  throw new Error(`Timed out waiting for browser profile sync "${importId}" to finish.`);
16870
17525
  }
@@ -16873,7 +17528,7 @@ function normalizePlatform(platform) {
16873
17528
  if (platform === "win32") return "windows";
16874
17529
  return platform;
16875
17530
  }
16876
- async function sleep2(ms) {
17531
+ async function sleep3(ms) {
16877
17532
  await new Promise((resolve4) => setTimeout(resolve4, ms));
16878
17533
  }
16879
17534
 
@@ -17071,7 +17726,7 @@ var OpensteerCloudClient = class {
17071
17726
  `Unexpected cloud session status "${String(session.status)}" while waiting for close.`
17072
17727
  );
17073
17728
  }
17074
- await delay(CLOUD_CLOSE_POLL_INTERVAL_MS);
17729
+ await delay2(CLOUD_CLOSE_POLL_INTERVAL_MS);
17075
17730
  }
17076
17731
  throw new Error(`Timed out waiting for cloud session ${sessionId} to close.`);
17077
17732
  }
@@ -17083,7 +17738,7 @@ function createRequestSignal(options) {
17083
17738
  }
17084
17739
  return AbortSignal.any([options.signal, timeoutSignal]);
17085
17740
  }
17086
- function delay(ms) {
17741
+ function delay2(ms) {
17087
17742
  return new Promise((resolve4) => {
17088
17743
  setTimeout(resolve4, ms);
17089
17744
  });
@@ -17133,7 +17788,7 @@ function resolveCloudConfig(input = {}) {
17133
17788
 
17134
17789
  // ../runtime-core/package.json
17135
17790
  var package_default = {
17136
- version: "0.2.0"};
17791
+ version: "0.2.1"};
17137
17792
 
17138
17793
  // ../runtime-core/src/version.ts
17139
17794
  var OPENSTEER_RUNTIME_CORE_VERSION = package_default.version;
@@ -17889,11 +18544,11 @@ var NetworkHistory = class {
17889
18544
  var MATCHED_TLS_BINARY_NAMES = ["curl-impersonate-chrome", "curl_chrome"];
17890
18545
  async function executeMatchedTlsTransportRequest(input) {
17891
18546
  const binary = await resolveMatchedTlsBinary();
17892
- const workingDirectory = await promises.mkdtemp(path7__default.default.join(os.tmpdir(), "opensteer-matched-tls-"));
17893
- const headersPath = path7__default.default.join(workingDirectory, "headers.txt");
17894
- const bodyPath = path7__default.default.join(workingDirectory, "body.bin");
17895
- const cookiesPath = path7__default.default.join(workingDirectory, "cookies.txt");
17896
- const requestBodyPath = path7__default.default.join(workingDirectory, "request-body.bin");
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");
17897
18552
  try {
17898
18553
  await promises.writeFile(cookiesPath, toNetscapeCookieJar(input.cookies ?? []), "utf8");
17899
18554
  if (input.request.body !== void 0) {
@@ -17950,10 +18605,10 @@ async function executeMatchedTlsTransportRequest(input) {
17950
18605
  }
17951
18606
  }
17952
18607
  async function resolveMatchedTlsBinary() {
17953
- const pathEntries = (process.env.PATH ?? "").split(path7__default.default.delimiter).filter((entry) => entry.length > 0);
18608
+ const pathEntries = (process.env.PATH ?? "").split(path10__default.default.delimiter).filter((entry) => entry.length > 0);
17954
18609
  for (const directory of pathEntries) {
17955
18610
  for (const name of MATCHED_TLS_BINARY_NAMES) {
17956
- const candidate = path7__default.default.join(directory, name);
18611
+ const candidate = path10__default.default.join(directory, name);
17957
18612
  if (await isExecutable(candidate)) {
17958
18613
  return candidate;
17959
18614
  }
@@ -17961,7 +18616,7 @@ async function resolveMatchedTlsBinary() {
17961
18616
  const files = await readDirSafe(directory);
17962
18617
  const discovered = files.find((file) => file.startsWith("curl_chrome"));
17963
18618
  if (discovered !== void 0) {
17964
- const candidate = path7__default.default.join(directory, discovered);
18619
+ const candidate = path10__default.default.join(directory, discovered);
17965
18620
  if (await isExecutable(candidate)) {
17966
18621
  return candidate;
17967
18622
  }
@@ -20415,11 +21070,11 @@ var SandboxClock = class {
20415
21070
  performanceNow() {
20416
21071
  return this.mode === "manual" ? this.manualNow - this.startedAt : (globalThis.performance?.now() ?? 0) - this.performanceStartedAt;
20417
21072
  }
20418
- setTimeout(callback, delay3 = 0, ...args) {
20419
- return this.registerTimer(false, callback, delay3, args);
21073
+ setTimeout(callback, delay4 = 0, ...args) {
21074
+ return this.registerTimer(false, callback, delay4, args);
20420
21075
  }
20421
- setInterval(callback, delay3 = 0, ...args) {
20422
- return this.registerTimer(true, callback, delay3, args);
21076
+ setInterval(callback, delay4 = 0, ...args) {
21077
+ return this.registerTimer(true, callback, delay4, args);
20423
21078
  }
20424
21079
  clearTimeout(timerId) {
20425
21080
  this.clearTimer(timerId);
@@ -20440,9 +21095,9 @@ var SandboxClock = class {
20440
21095
  this.clearTimer(timerId);
20441
21096
  }
20442
21097
  }
20443
- registerTimer(repeat, callback, delay3, args) {
21098
+ registerTimer(repeat, callback, delay4, args) {
20444
21099
  const timerId = this.nextTimerId++;
20445
- const normalizedDelay = Math.max(0, delay3);
21100
+ const normalizedDelay = Math.max(0, delay4);
20446
21101
  const record = {
20447
21102
  callback,
20448
21103
  args,
@@ -20606,7 +21261,7 @@ async function pollTask(apiKey, taskId, signal) {
20606
21261
  const deadline = Date.now() + 12e4;
20607
21262
  while (Date.now() < deadline) {
20608
21263
  signal?.throwIfAborted?.();
20609
- await sleep3(3e3, signal);
21264
+ await sleep4(3e3, signal);
20610
21265
  const response = await fetch(CAPSOLVER_GET_TASK_RESULT_URL, {
20611
21266
  method: "POST",
20612
21267
  headers: {
@@ -20650,7 +21305,7 @@ function extractCaptchaToken(solution) {
20650
21305
  function readString(value) {
20651
21306
  return typeof value === "string" && value.length > 0 ? value : void 0;
20652
21307
  }
20653
- function sleep3(ms, signal) {
21308
+ function sleep4(ms, signal) {
20654
21309
  return new Promise((resolve4, reject) => {
20655
21310
  const timeout = setTimeout(resolve4, ms);
20656
21311
  const abort = () => {
@@ -20704,7 +21359,7 @@ async function pollTask2(apiKey, taskId, signal) {
20704
21359
  const deadline = Date.now() + 12e4;
20705
21360
  while (Date.now() < deadline) {
20706
21361
  signal?.throwIfAborted?.();
20707
- await sleep4(5e3, signal);
21362
+ await sleep5(5e3, signal);
20708
21363
  const response = await fetch(TWO_CAPTCHA_GET_TASK_RESULT_URL, {
20709
21364
  method: "POST",
20710
21365
  headers: {
@@ -20748,7 +21403,7 @@ function extractCaptchaToken2(solution) {
20748
21403
  function readString2(value) {
20749
21404
  return typeof value === "string" && value.length > 0 ? value : void 0;
20750
21405
  }
20751
- function sleep4(ms, signal) {
21406
+ function sleep5(ms, signal) {
20752
21407
  return new Promise((resolve4, reject) => {
20753
21408
  const timeout = setTimeout(resolve4, ms);
20754
21409
  const abort = () => {
@@ -20985,7 +21640,7 @@ var OpensteerSessionRuntime = class {
20985
21640
  this.workspace = normalizeNamespace2(options.name);
20986
21641
  this.workspaceName = options.workspaceName?.trim() === void 0 || options.workspaceName?.trim().length === 0 ? void 0 : options.workspaceName.trim();
20987
21642
  this.root = options.workspace;
20988
- this.rootPath = options.workspace?.rootPath ?? options.rootPath ?? path7__default.default.resolve(process.cwd(), ".opensteer", "temporary", crypto.randomUUID());
21643
+ this.rootPath = options.workspace?.rootPath ?? options.rootPath ?? path10__default.default.resolve(process.cwd(), ".opensteer", "temporary", crypto.randomUUID());
20989
21644
  this.injectedEngine = options.engine;
20990
21645
  this.engineFactory = options.engineFactory;
20991
21646
  this.policy = options.policy ?? defaultPolicy();
@@ -26774,8 +27429,8 @@ var CloudSessionProxy = class {
26774
27429
  this.workspace = options.workspace;
26775
27430
  this.policy = options.policy ?? defaultPolicy();
26776
27431
  this.observability = options.observability;
26777
- this.rootPath = options.rootPath ?? (this.workspace === void 0 ? path7__default.default.join(os.tmpdir(), `${TEMPORARY_CLOUD_WORKSPACE_PREFIX}${crypto.randomUUID()}`) : resolveFilesystemWorkspacePath({
26778
- rootDir: path7__default.default.resolve(options.rootDir ?? process.cwd()),
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()),
26779
27434
  workspace: this.workspace
26780
27435
  }));
26781
27436
  this.cleanupRootOnClose = options.cleanupRootOnClose ?? this.workspace === void 0;
@@ -27197,8 +27852,8 @@ function isLoopbackBaseUrl(baseUrl) {
27197
27852
  var OpensteerRuntime = class extends OpensteerSessionRuntime {
27198
27853
  constructor(options = {}) {
27199
27854
  const publicWorkspace = normalizeWorkspace2(options.workspace);
27200
- const rootPath = options.rootPath ?? (publicWorkspace === void 0 ? path7__default.default.resolve(options.rootDir ?? process.cwd(), ".opensteer", "temporary", crypto.randomUUID()) : resolveFilesystemWorkspacePath({
27201
- rootDir: path7__default.default.resolve(options.rootDir ?? process.cwd()),
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()),
27202
27857
  workspace: publicWorkspace
27203
27858
  }));
27204
27859
  const cleanupRootOnClose = options.cleanupRootOnClose ?? publicWorkspace === void 0;
@@ -27232,7 +27887,7 @@ var OpensteerRuntime = class extends OpensteerSessionRuntime {
27232
27887
  };
27233
27888
  var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
27234
27889
  constructor(options) {
27235
- const rootPath = options.rootPath ?? path7__default.default.resolve(options.rootDir ?? process.cwd());
27890
+ const rootPath = options.rootPath ?? path10__default.default.resolve(options.rootDir ?? process.cwd());
27236
27891
  const cleanupRootOnClose = options.cleanupRootOnClose ?? false;
27237
27892
  const engineName = options.engineName ?? DEFAULT_OPENSTEER_ENGINE;
27238
27893
  assertSupportedEngineOptions({
@@ -27522,7 +28177,7 @@ var Opensteer = class {
27522
28177
  if (Date.now() >= timeoutAt) {
27523
28178
  throw new Error("waitForNetwork timed out");
27524
28179
  }
27525
- await delay2(pollInterval);
28180
+ await delay3(pollInterval);
27526
28181
  }
27527
28182
  }
27528
28183
  async waitForResponse(input) {
@@ -27551,7 +28206,7 @@ var Opensteer = class {
27551
28206
  if (Date.now() >= timeoutAt) {
27552
28207
  throw new Error("waitForPage timed out");
27553
28208
  }
27554
- await delay2(pollIntervalMs);
28209
+ await delay3(pollIntervalMs);
27555
28210
  }
27556
28211
  }
27557
28212
  async snapshot(mode = "action") {
@@ -27703,7 +28358,7 @@ function decodeBody(response) {
27703
28358
  }
27704
28359
  return Uint8Array.from(Buffer.from(response.body.data, "base64"));
27705
28360
  }
27706
- function delay2(ms) {
28361
+ function delay3(ms) {
27707
28362
  return new Promise((resolve4) => setTimeout(resolve4, ms));
27708
28363
  }
27709
28364