opensteer 0.8.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1787,12 +1787,6 @@ var opensteerRegistryProvenanceSchema = objectSchema(
1787
1787
  required: ["source"]
1788
1788
  }
1789
1789
  );
1790
- var opensteerRequestPlanLifecycleSchema = enumSchema(
1791
- ["draft", "active", "deprecated", "retired"],
1792
- {
1793
- title: "OpensteerRequestPlanLifecycle"
1794
- }
1795
- );
1796
1790
  var opensteerRequestPlanFreshnessSchema = objectSchema(
1797
1791
  {
1798
1792
  lastValidatedAt: integerSchema({ minimum: 0 }),
@@ -1815,23 +1809,12 @@ var opensteerRequestPlanRecordSchema = objectSchema(
1815
1809
  uniqueItems: true
1816
1810
  }),
1817
1811
  provenance: opensteerRegistryProvenanceSchema,
1818
- lifecycle: opensteerRequestPlanLifecycleSchema,
1819
1812
  freshness: opensteerRequestPlanFreshnessSchema,
1820
1813
  payload: opensteerRequestPlanPayloadSchema
1821
1814
  },
1822
1815
  {
1823
1816
  title: "OpensteerRequestPlanRecord",
1824
- required: [
1825
- "id",
1826
- "key",
1827
- "version",
1828
- "createdAt",
1829
- "updatedAt",
1830
- "contentHash",
1831
- "tags",
1832
- "lifecycle",
1833
- "payload"
1834
- ]
1817
+ required: ["id", "key", "version", "createdAt", "updatedAt", "contentHash", "tags", "payload"]
1835
1818
  }
1836
1819
  );
1837
1820
  var jsonValueSchema = defineSchema({
@@ -2274,7 +2257,6 @@ var opensteerWriteRequestPlanInputSchema = objectSchema(
2274
2257
  uniqueItems: true
2275
2258
  }),
2276
2259
  provenance: opensteerRegistryProvenanceSchema,
2277
- lifecycle: opensteerRequestPlanLifecycleSchema,
2278
2260
  freshness: opensteerRequestPlanFreshnessSchema,
2279
2261
  payload: opensteerRequestPlanPayloadSchema
2280
2262
  },
@@ -2515,7 +2497,7 @@ var opensteerInferRequestPlanInputSchema = objectSchema(
2515
2497
  recordId: stringSchema({ minLength: 1 }),
2516
2498
  key: stringSchema({ minLength: 1 }),
2517
2499
  version: stringSchema({ minLength: 1 }),
2518
- lifecycle: opensteerRequestPlanLifecycleSchema
2500
+ transport: transportKindSchema
2519
2501
  },
2520
2502
  {
2521
2503
  title: "OpensteerInferRequestPlanInput",
@@ -7129,9 +7111,7 @@ var FilesystemRegistryStore = class {
7129
7111
  if (input.version !== void 0) {
7130
7112
  return this.resolveIndexedRecord(key, normalizeNonEmptyString("version", input.version));
7131
7113
  }
7132
- const matches = (await this.readAllRecords()).filter(
7133
- (record) => this.isActive(record) && record.key === key
7134
- );
7114
+ const matches = (await this.readAllRecords()).filter((record) => record.key === key);
7135
7115
  matches.sort(compareByCreatedAtAndId);
7136
7116
  return matches[0];
7137
7117
  }
@@ -7254,8 +7234,10 @@ var FilesystemDescriptorRegistry = class extends FilesystemRegistryStore {
7254
7234
  };
7255
7235
  return this.writeRecord(record);
7256
7236
  }
7257
- isActive(_record) {
7258
- return true;
7237
+ async list(input = {}) {
7238
+ const key = input.key === void 0 ? void 0 : normalizeNonEmptyString("key", input.key);
7239
+ const records = await this.readAllRecords();
7240
+ return key === void 0 ? records : records.filter((record) => record.key === key);
7259
7241
  }
7260
7242
  };
7261
7243
  var FilesystemRequestPlanRegistry = class extends FilesystemRegistryStore {
@@ -7285,7 +7267,6 @@ var FilesystemRequestPlanRegistry = class extends FilesystemRegistryStore {
7285
7267
  tags: normalizeTags(input.tags),
7286
7268
  ...provenance === void 0 ? {} : { provenance },
7287
7269
  payload,
7288
- lifecycle: input.lifecycle ?? "active",
7289
7270
  ...freshness === void 0 ? {} : { freshness }
7290
7271
  };
7291
7272
  return this.writeRecord(record);
@@ -7295,7 +7276,7 @@ var FilesystemRequestPlanRegistry = class extends FilesystemRegistryStore {
7295
7276
  const records = await this.readAllRecords();
7296
7277
  return key === void 0 ? records : records.filter((record) => record.key === key);
7297
7278
  }
7298
- async updateMetadata(input) {
7279
+ async updateFreshness(input) {
7299
7280
  const id = normalizeNonEmptyString("id", input.id);
7300
7281
  return withFilesystemLock(this.writeLockPath(), async () => {
7301
7282
  const existing = await this.getById(id);
@@ -7313,16 +7294,12 @@ var FilesystemRequestPlanRegistry = class extends FilesystemRegistryStore {
7313
7294
  const nextRecord = {
7314
7295
  ...existing,
7315
7296
  updatedAt: nextUpdatedAt,
7316
- lifecycle: input.lifecycle ?? existing.lifecycle,
7317
7297
  ...nextFreshness === void 0 ? {} : { freshness: nextFreshness }
7318
7298
  };
7319
7299
  await writeJsonFileAtomic(this.recordPath(id), nextRecord);
7320
7300
  return nextRecord;
7321
7301
  });
7322
7302
  }
7323
- isActive(record) {
7324
- return record.lifecycle === "active";
7325
- }
7326
7303
  };
7327
7304
  var FilesystemAuthRecipeRegistry = class extends FilesystemRegistryStore {
7328
7305
  constructor(rootPath) {
@@ -7358,9 +7335,6 @@ var FilesystemAuthRecipeRegistry = class extends FilesystemRegistryStore {
7358
7335
  const records = await this.readAllRecords();
7359
7336
  return key === void 0 ? records : records.filter((record) => record.key === key);
7360
7337
  }
7361
- isActive(_record) {
7362
- return true;
7363
- }
7364
7338
  };
7365
7339
  var FilesystemRecipeRegistry = class extends FilesystemRegistryStore {
7366
7340
  constructor(rootPath) {
@@ -7396,9 +7370,6 @@ var FilesystemRecipeRegistry = class extends FilesystemRegistryStore {
7396
7370
  const records = await this.readAllRecords();
7397
7371
  return key === void 0 ? records : records.filter((record) => record.key === key);
7398
7372
  }
7399
- isActive(_record) {
7400
- return true;
7401
- }
7402
7373
  };
7403
7374
  var FilesystemInteractionTraceRegistry = class extends FilesystemRegistryStore {
7404
7375
  constructor(rootPath) {
@@ -7434,9 +7405,6 @@ var FilesystemInteractionTraceRegistry = class extends FilesystemRegistryStore {
7434
7405
  const records = await this.readAllRecords();
7435
7406
  return key === void 0 ? records : records.filter((record) => record.key === key);
7436
7407
  }
7437
- isActive(_record) {
7438
- return true;
7439
- }
7440
7408
  };
7441
7409
  var FilesystemReverseCaseRegistry = class extends FilesystemRegistryStore {
7442
7410
  constructor(rootPath) {
@@ -7500,9 +7468,6 @@ var FilesystemReverseCaseRegistry = class extends FilesystemRegistryStore {
7500
7468
  return nextRecord;
7501
7469
  });
7502
7470
  }
7503
- isActive(_record) {
7504
- return true;
7505
- }
7506
7471
  };
7507
7472
  var FilesystemReversePackageRegistry = class extends FilesystemRegistryStore {
7508
7473
  constructor(rootPath) {
@@ -7538,9 +7503,6 @@ var FilesystemReversePackageRegistry = class extends FilesystemRegistryStore {
7538
7503
  const records = await this.readAllRecords();
7539
7504
  return key === void 0 ? records : records.filter((record) => record.key === key);
7540
7505
  }
7541
- isActive(_record) {
7542
- return true;
7543
- }
7544
7506
  };
7545
7507
  var FilesystemReverseReportRegistry = class extends FilesystemRegistryStore {
7546
7508
  constructor(rootPath) {
@@ -7576,9 +7538,6 @@ var FilesystemReverseReportRegistry = class extends FilesystemRegistryStore {
7576
7538
  const records = await this.readAllRecords();
7577
7539
  return key === void 0 ? records : records.filter((record) => record.key === key);
7578
7540
  }
7579
- isActive(_record) {
7580
- return true;
7581
- }
7582
7541
  };
7583
7542
  function createDescriptorRegistry(rootPath) {
7584
7543
  return new FilesystemDescriptorRegistry(rootPath);
@@ -8318,8 +8277,8 @@ async function createFilesystemOpensteerWorkspace(options) {
8318
8277
  const browserManifestPath = path6__default.default.join(browserPath, "manifest.json");
8319
8278
  const browserUserDataDir = path6__default.default.join(browserPath, "user-data");
8320
8279
  const livePath = path6__default.default.join(options.rootPath, "live");
8321
- const liveSessionPath = path6__default.default.join(livePath, "session.json");
8322
- const liveBrowserPath = path6__default.default.join(livePath, "browser.json");
8280
+ const liveLocalPath = path6__default.default.join(livePath, "local.json");
8281
+ const liveCloudPath = path6__default.default.join(livePath, "cloud.json");
8323
8282
  const artifactsPath = path6__default.default.join(options.rootPath, "artifacts");
8324
8283
  const tracesPath = path6__default.default.join(options.rootPath, "traces");
8325
8284
  const registryPath = path6__default.default.join(options.rootPath, "registry");
@@ -8394,8 +8353,8 @@ async function createFilesystemOpensteerWorkspace(options) {
8394
8353
  browserManifestPath,
8395
8354
  browserUserDataDir,
8396
8355
  livePath,
8397
- liveSessionPath,
8398
- liveBrowserPath,
8356
+ liveLocalPath,
8357
+ liveCloudPath,
8399
8358
  artifactsPath,
8400
8359
  tracesPath,
8401
8360
  registryPath,
@@ -8651,6 +8610,16 @@ function abortError2() {
8651
8610
  return error;
8652
8611
  }
8653
8612
 
8613
+ // ../runtime-core/src/runtimes/dom/errors.ts
8614
+ var ElementPathError = class extends Error {
8615
+ code;
8616
+ constructor(code, message) {
8617
+ super(message);
8618
+ this.name = "ElementPathError";
8619
+ this.code = code;
8620
+ }
8621
+ };
8622
+
8654
8623
  // ../runtime-core/src/runtimes/dom/match-policy.ts
8655
8624
  var ATTRIBUTE_DENY_KEYS = /* @__PURE__ */ new Set([
8656
8625
  "style",
@@ -9214,16 +9183,6 @@ function readDescriptorToken(value, index) {
9214
9183
  nextIndex: cursor
9215
9184
  };
9216
9185
  }
9217
-
9218
- // ../runtime-core/src/runtimes/dom/errors.ts
9219
- var ElementPathError = class extends Error {
9220
- code;
9221
- constructor(code, message) {
9222
- super(message);
9223
- this.name = "ElementPathError";
9224
- this.code = code;
9225
- }
9226
- };
9227
9186
  var selectorAdapter = {
9228
9187
  isTag(node) {
9229
9188
  return node.kind === "element" && node.source.nodeType === 1;
@@ -9988,24 +9947,31 @@ function collectChildrenInScope(index, node, scopeHostNodeRef) {
9988
9947
  function getShadowScopeNodeRef(index, node) {
9989
9948
  return findContainingShadowHostNode(index, node)?.nodeRef;
9990
9949
  }
9950
+
9951
+ // ../runtime-core/src/runtimes/dom/descriptors.ts
9991
9952
  function createDomDescriptorStore(options) {
9992
- const namespace = normalizeNamespace(options.namespace);
9953
+ const namespace = normalizeDomDescriptorNamespace(options.namespace);
9993
9954
  if (options.root) {
9994
9955
  return new FilesystemDomDescriptorStore(options.root.registry.descriptors, namespace);
9995
9956
  }
9996
9957
  return new MemoryDomDescriptorStore(namespace);
9997
9958
  }
9998
- function descriptionKey(namespace, method, description) {
9999
- return `dom:${namespace}:${method}:${sha256Hex2(description.trim())}`;
9959
+ function hashDomDescriptorDescription(description) {
9960
+ return sha256Hex2(description.trim());
10000
9961
  }
10001
- function normalizeNamespace(namespace) {
9962
+ function buildDomDescriptorKey(options) {
9963
+ return `dom:${normalizeDomDescriptorNamespace(options.namespace)}:${options.method}:${hashDomDescriptorDescription(
9964
+ options.description
9965
+ )}`;
9966
+ }
9967
+ function normalizeDomDescriptorNamespace(namespace) {
10002
9968
  const normalized = String(namespace || "default").trim();
10003
9969
  return normalized.length === 0 ? "default" : normalized;
10004
9970
  }
10005
9971
  function sha256Hex2(value) {
10006
9972
  return crypto.createHash("sha256").update(value).digest("hex");
10007
9973
  }
10008
- function buildPayload(input) {
9974
+ function buildDomDescriptorPayload(input) {
10009
9975
  return {
10010
9976
  kind: "dom-target",
10011
9977
  method: input.method,
@@ -10014,6 +9980,9 @@ function buildPayload(input) {
10014
9980
  ...input.sourceUrl === void 0 ? {} : { sourceUrl: input.sourceUrl }
10015
9981
  };
10016
9982
  }
9983
+ function buildDomDescriptorVersion(payload) {
9984
+ return sha256Hex2(canonicalJsonString(payload));
9985
+ }
10017
9986
  function parseDomDescriptorRecord(record) {
10018
9987
  const payload = record.payload;
10019
9988
  if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
@@ -10055,7 +10024,11 @@ var FilesystemDomDescriptorStore = class {
10055
10024
  }
10056
10025
  async read(input) {
10057
10026
  const record = await this.registry.resolve({
10058
- key: descriptionKey(this.namespace, input.method, input.description)
10027
+ key: buildDomDescriptorKey({
10028
+ namespace: this.namespace,
10029
+ method: input.method,
10030
+ description: input.description
10031
+ })
10059
10032
  });
10060
10033
  if (!record) {
10061
10034
  return void 0;
@@ -10063,9 +10036,13 @@ var FilesystemDomDescriptorStore = class {
10063
10036
  return parseDomDescriptorRecord(record);
10064
10037
  }
10065
10038
  async write(input) {
10066
- const payload = buildPayload(input);
10067
- const key = descriptionKey(this.namespace, input.method, input.description);
10068
- const version = sha256Hex2(canonicalJsonString(payload));
10039
+ const payload = buildDomDescriptorPayload(input);
10040
+ const key = buildDomDescriptorKey({
10041
+ namespace: this.namespace,
10042
+ method: input.method,
10043
+ description: input.description
10044
+ });
10045
+ const version = buildDomDescriptorVersion(payload);
10069
10046
  const existing = await this.registry.resolve({ key, version });
10070
10047
  if (existing) {
10071
10048
  const parsed2 = parseDomDescriptorRecord(existing);
@@ -10103,12 +10080,22 @@ var MemoryDomDescriptorStore = class {
10103
10080
  latestByKey = /* @__PURE__ */ new Map();
10104
10081
  recordsByKey = /* @__PURE__ */ new Map();
10105
10082
  async read(input) {
10106
- return this.latestByKey.get(descriptionKey(this.namespace, input.method, input.description));
10083
+ return this.latestByKey.get(
10084
+ buildDomDescriptorKey({
10085
+ namespace: this.namespace,
10086
+ method: input.method,
10087
+ description: input.description
10088
+ })
10089
+ );
10107
10090
  }
10108
10091
  async write(input) {
10109
- const payload = buildPayload(input);
10110
- const key = descriptionKey(this.namespace, input.method, input.description);
10111
- const version = sha256Hex2(canonicalJsonString(payload));
10092
+ const payload = buildDomDescriptorPayload(input);
10093
+ const key = buildDomDescriptorKey({
10094
+ namespace: this.namespace,
10095
+ method: input.method,
10096
+ description: input.description
10097
+ });
10098
+ const version = buildDomDescriptorVersion(payload);
10112
10099
  const existing = this.recordsByKey.get(key)?.get(version);
10113
10100
  if (existing) {
10114
10101
  return existing;
@@ -10751,7 +10738,7 @@ var DefaultDomRuntime = class {
10751
10738
  bridge;
10752
10739
  constructor(options) {
10753
10740
  this.engine = options.engine;
10754
- this.descriptors = createDomDescriptorStore({
10741
+ this.descriptors = options.descriptorStore ?? createDomDescriptorStore({
10755
10742
  ...options.root === void 0 ? {} : { root: options.root },
10756
10743
  ...options.namespace === void 0 ? {} : { namespace: options.namespace }
10757
10744
  });
@@ -12805,110 +12792,48 @@ function pickStealthProfilePreset(overrides) {
12805
12792
  }
12806
12793
  var OPENSTEER_LIVE_SESSION_LAYOUT = "opensteer-session";
12807
12794
  var OPENSTEER_LIVE_SESSION_VERSION = 1;
12808
- var LEGACY_CLOUD_SESSION_LAYOUT = "opensteer-cloud-session";
12809
- var LEGACY_CLOUD_SESSION_VERSION = 1;
12810
- function resolveLiveSessionRecordPath(rootPath) {
12811
- return path6__default.default.join(rootPath, "live", "session.json");
12795
+ function resolveLiveSessionRecordPath(rootPath, provider) {
12796
+ return path6__default.default.join(rootPath, "live", provider === "local" ? "local.json" : "cloud.json");
12812
12797
  }
12813
- function resolveLegacyLiveBrowserRecordPath(rootPath) {
12814
- return path6__default.default.join(rootPath, "live", "browser.json");
12798
+ function resolveLocalSessionRecordPath(rootPath) {
12799
+ return resolveLiveSessionRecordPath(rootPath, "local");
12815
12800
  }
12816
- function resolveLegacyCloudSessionRecordPath(rootPath) {
12817
- return path6__default.default.join(rootPath, "live", "cloud-session.json");
12801
+ function resolveCloudSessionRecordPath(rootPath) {
12802
+ return resolveLiveSessionRecordPath(rootPath, "cloud");
12818
12803
  }
12819
- async function readPersistedSessionRecord(rootPath) {
12820
- const sessionPath = resolveLiveSessionRecordPath(rootPath);
12821
- if (await pathExists(sessionPath)) {
12822
- const parsed = await readJsonFile(sessionPath);
12823
- if (isPersistedLocalBrowserSessionRecord(parsed)) {
12824
- return parsed;
12825
- }
12826
- if (isPersistedCloudSessionRecord(parsed)) {
12827
- return parsed;
12828
- }
12804
+ async function readPersistedSessionRecord(rootPath, provider) {
12805
+ const sessionPath = resolveLiveSessionRecordPath(rootPath, provider);
12806
+ if (!await pathExists(sessionPath)) {
12807
+ return void 0;
12829
12808
  }
12830
- const legacyCloudPath = resolveLegacyCloudSessionRecordPath(rootPath);
12831
- if (await pathExists(legacyCloudPath)) {
12832
- const parsed = await readJsonFile(legacyCloudPath);
12833
- if (isLegacyCloudSessionRecord(parsed)) {
12834
- return {
12835
- layout: OPENSTEER_LIVE_SESSION_LAYOUT,
12836
- version: OPENSTEER_LIVE_SESSION_VERSION,
12837
- provider: "cloud",
12838
- mode: "cloud",
12839
- ...parsed.workspace === void 0 ? {} : { workspace: parsed.workspace },
12840
- sessionId: parsed.sessionId,
12841
- baseUrl: parsed.baseUrl,
12842
- startedAt: parsed.startedAt,
12843
- updatedAt: parsed.updatedAt
12844
- };
12845
- }
12809
+ const parsed = await readJsonFile(sessionPath);
12810
+ if (provider === "local" && isPersistedLocalBrowserSessionRecord(parsed)) {
12811
+ return parsed;
12846
12812
  }
12847
- const legacyBrowserPath = resolveLegacyLiveBrowserRecordPath(rootPath);
12848
- if (await pathExists(legacyBrowserPath)) {
12849
- const parsed = await readJsonFile(legacyBrowserPath);
12850
- if (isLegacyLocalBrowserSessionRecord(parsed)) {
12851
- return {
12852
- layout: OPENSTEER_LIVE_SESSION_LAYOUT,
12853
- version: OPENSTEER_LIVE_SESSION_VERSION,
12854
- provider: "local",
12855
- mode: "browser",
12856
- engine: parsed.engine ?? "playwright",
12857
- ...parsed.endpoint === void 0 ? {} : { endpoint: parsed.endpoint },
12858
- ...parsed.baseUrl === void 0 ? {} : { baseUrl: parsed.baseUrl },
12859
- ...parsed.remoteDebuggingUrl === void 0 ? {} : { remoteDebuggingUrl: parsed.remoteDebuggingUrl },
12860
- ...parsed.sessionDir === void 0 ? {} : { sessionDir: parsed.sessionDir },
12861
- pid: parsed.pid,
12862
- startedAt: parsed.startedAt,
12863
- updatedAt: parsed.startedAt,
12864
- ...parsed.executablePath === void 0 ? {} : { executablePath: parsed.executablePath },
12865
- userDataDir: parsed.userDataDir
12866
- };
12867
- }
12813
+ if (provider === "cloud" && isPersistedCloudSessionRecord(parsed)) {
12814
+ return parsed;
12868
12815
  }
12869
12816
  return void 0;
12870
12817
  }
12871
12818
  async function readPersistedCloudSessionRecord(rootPath) {
12872
- const record = await readPersistedSessionRecord(rootPath);
12819
+ const record = await readPersistedSessionRecord(rootPath, "cloud");
12873
12820
  return record?.provider === "cloud" ? record : void 0;
12874
12821
  }
12875
12822
  async function readPersistedLocalBrowserSessionRecord(rootPath) {
12876
- const record = await readPersistedSessionRecord(rootPath);
12823
+ const record = await readPersistedSessionRecord(rootPath, "local");
12877
12824
  return record?.provider === "local" ? record : void 0;
12878
12825
  }
12879
- async function hasPersistedCloudSession(rootPath) {
12880
- return await readPersistedCloudSessionRecord(rootPath) !== void 0;
12881
- }
12882
12826
  async function writePersistedSessionRecord(rootPath, record) {
12883
- await writeJsonFileAtomic(resolveLiveSessionRecordPath(rootPath), record);
12884
- await clearLegacySessionRecordPaths(rootPath);
12827
+ await writeJsonFileAtomic(resolveLiveSessionRecordPath(rootPath, record.provider), record);
12885
12828
  }
12886
- async function clearPersistedSessionRecord(rootPath) {
12887
- await Promise.all([
12888
- removeIfPresent(resolveLiveSessionRecordPath(rootPath)),
12889
- clearLegacySessionRecordPaths(rootPath)
12890
- ]);
12829
+ async function clearPersistedSessionRecord(rootPath, provider) {
12830
+ await promises.rm(resolveLiveSessionRecordPath(rootPath, provider), { force: true });
12891
12831
  }
12892
12832
  function isPersistedCloudSessionRecord(value) {
12893
- return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "cloud" && value.mode === "cloud" && typeof value.sessionId === "string" && value.sessionId.length > 0 && typeof value.baseUrl === "string" && value.baseUrl.length > 0 && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt);
12833
+ return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "cloud" && typeof value.sessionId === "string" && value.sessionId.length > 0 && typeof value.baseUrl === "string" && value.baseUrl.length > 0 && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt);
12894
12834
  }
12895
12835
  function isPersistedLocalBrowserSessionRecord(value) {
12896
- return value.layout === OPENSTEER_LIVE_SESSION_LAYOUT && value.version === OPENSTEER_LIVE_SESSION_VERSION && value.provider === "local" && value.mode === "browser" && (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;
12897
- }
12898
- function isLegacyCloudSessionRecord(value) {
12899
- return value.layout === LEGACY_CLOUD_SESSION_LAYOUT && value.version === LEGACY_CLOUD_SESSION_VERSION && value.mode === "cloud" && typeof value.sessionId === "string" && value.sessionId.length > 0 && typeof value.baseUrl === "string" && value.baseUrl.length > 0 && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt);
12900
- }
12901
- function isLegacyLocalBrowserSessionRecord(value) {
12902
- return value.mode === "persistent" && typeof value.pid === "number" && Number.isFinite(value.pid) && typeof value.startedAt === "number" && Number.isFinite(value.startedAt) && typeof value.userDataDir === "string" && value.userDataDir.length > 0;
12903
- }
12904
- async function clearLegacySessionRecordPaths(rootPath) {
12905
- await Promise.all([
12906
- removeIfPresent(resolveLegacyLiveBrowserRecordPath(rootPath)),
12907
- removeIfPresent(resolveLegacyCloudSessionRecordPath(rootPath))
12908
- ]);
12909
- }
12910
- async function removeIfPresent(filePath) {
12911
- await promises.rm(filePath, { force: true }).catch(() => void 0);
12836
+ 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;
12912
12837
  }
12913
12838
 
12914
12839
  // ../runtime-core/src/internal/engine-selection.ts
@@ -13114,7 +13039,7 @@ var OpensteerBrowserManager = class {
13114
13039
  await this.closePersistentBrowser(workspace);
13115
13040
  await promises.rm(resolveAbpSessionDir(workspace), { recursive: true, force: true });
13116
13041
  await promises.rm(workspace.browserPath, { recursive: true, force: true });
13117
- await clearPersistedSessionRecord(workspace.rootPath);
13042
+ await clearPersistedSessionRecord(workspace.rootPath, "local");
13118
13043
  await ensureDirectory(workspace.browserUserDataDir);
13119
13044
  });
13120
13045
  }
@@ -13125,7 +13050,7 @@ var OpensteerBrowserManager = class {
13125
13050
  await this.closePersistentBrowser(workspace);
13126
13051
  await promises.rm(resolveAbpSessionDir(workspace), { recursive: true, force: true });
13127
13052
  await promises.rm(workspace.browserPath, { recursive: true, force: true });
13128
- await clearPersistedSessionRecord(workspace.rootPath);
13053
+ await clearPersistedSessionRecord(workspace.rootPath, "local");
13129
13054
  });
13130
13055
  }
13131
13056
  async close() {
@@ -13208,7 +13133,7 @@ var OpensteerBrowserManager = class {
13208
13133
  return await this.createAdoptedAbpEngine(liveRecord);
13209
13134
  } catch (error) {
13210
13135
  await terminateProcess(launched.process.pid ?? 0).catch(() => void 0);
13211
- await clearPersistedSessionRecord(workspace.rootPath).catch(() => void 0);
13136
+ await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
13212
13137
  throw error;
13213
13138
  }
13214
13139
  });
@@ -13300,7 +13225,7 @@ var OpensteerBrowserManager = class {
13300
13225
  });
13301
13226
  } catch (error) {
13302
13227
  await terminateProcess(launched.pid).catch(() => void 0);
13303
- await clearPersistedSessionRecord(workspace.rootPath).catch(() => void 0);
13228
+ await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
13304
13229
  throw error;
13305
13230
  }
13306
13231
  });
@@ -13406,7 +13331,7 @@ var OpensteerBrowserManager = class {
13406
13331
  return void 0;
13407
13332
  }
13408
13333
  if (!isProcessRunning(live.pid)) {
13409
- await clearPersistedSessionRecord(workspace.rootPath).catch(() => void 0);
13334
+ await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
13410
13335
  return void 0;
13411
13336
  }
13412
13337
  if (live.engine === "playwright") {
@@ -13446,7 +13371,7 @@ var OpensteerBrowserManager = class {
13446
13371
  async closePersistentBrowser(workspace) {
13447
13372
  const live = await this.readStoredLiveBrowser(workspace);
13448
13373
  if (!live) {
13449
- await clearPersistedSessionRecord(workspace.rootPath).catch(() => void 0);
13374
+ await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
13450
13375
  return;
13451
13376
  }
13452
13377
  if (live.engine === "playwright") {
@@ -13454,15 +13379,15 @@ var OpensteerBrowserManager = class {
13454
13379
  await requestBrowserClose(live.endpoint).catch(() => void 0);
13455
13380
  }
13456
13381
  if (await waitForProcessExit(live.pid, BROWSER_CLOSE_TIMEOUT_MS)) {
13457
- await clearPersistedSessionRecord(workspace.rootPath).catch(() => void 0);
13382
+ await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
13458
13383
  return;
13459
13384
  }
13460
13385
  await terminateProcess(live.pid).catch(() => void 0);
13461
- await clearPersistedSessionRecord(workspace.rootPath).catch(() => void 0);
13386
+ await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
13462
13387
  return;
13463
13388
  }
13464
13389
  await terminateProcess(live.pid).catch(() => void 0);
13465
- await clearPersistedSessionRecord(workspace.rootPath).catch(() => void 0);
13390
+ await clearPersistedSessionRecord(workspace.rootPath, "local").catch(() => void 0);
13466
13391
  }
13467
13392
  async writeLivePersistentBrowser(workspace, live) {
13468
13393
  await writePersistedSessionRecord(
@@ -13485,7 +13410,6 @@ function toPersistedLocalBrowserSessionRecord(workspace, live) {
13485
13410
  layout: "opensteer-session",
13486
13411
  version: 1,
13487
13412
  provider: "local",
13488
- mode: "browser",
13489
13413
  ...workspace === void 0 ? {} : { workspace },
13490
13414
  engine: live.engine,
13491
13415
  ...live.endpoint === void 0 ? {} : { endpoint: live.endpoint },
@@ -15073,7 +14997,7 @@ function inferRequestPlanFromNetworkRecord(record, input, options = {}) {
15073
14997
  const body = inferRequestPlanBody(record.record.requestBody, requestContentType);
15074
14998
  const payload = normalizeRequestPlanPayload({
15075
14999
  transport: {
15076
- kind: "context-http"
15000
+ kind: input.transport ?? "context-http"
15077
15001
  },
15078
15002
  endpoint: {
15079
15003
  method: record.record.method,
@@ -15093,7 +15017,6 @@ function inferRequestPlanFromNetworkRecord(record, input, options = {}) {
15093
15017
  return {
15094
15018
  key: input.key,
15095
15019
  version: input.version,
15096
- lifecycle: input.lifecycle ?? "draft",
15097
15020
  provenance: {
15098
15021
  source: record.source === "saved" ? "saved-network-record" : "live-network-record",
15099
15022
  sourceId: record.recordId,
@@ -19422,7 +19345,7 @@ async function replayOpensteerExtractionPayload(options) {
19422
19345
  return extractPersistedObjectNode(options.pageRef, options.dom, options.payload);
19423
19346
  }
19424
19347
  function createOpensteerExtractionDescriptorStore(options) {
19425
- const namespace = normalizeNamespace2(options.namespace);
19348
+ const namespace = normalizeNamespace(options.namespace);
19426
19349
  if (options.root) {
19427
19350
  return new FilesystemOpensteerExtractionDescriptorStore(
19428
19351
  options.root.registry.descriptors,
@@ -19919,11 +19842,11 @@ function normalizeSchemaField(value) {
19919
19842
  ...attribute === void 0 ? {} : { attribute }
19920
19843
  };
19921
19844
  }
19922
- function normalizeNamespace2(namespace) {
19845
+ function normalizeNamespace(namespace) {
19923
19846
  const normalized = String(namespace ?? "default").trim();
19924
19847
  return normalized.length === 0 ? "default" : normalized;
19925
19848
  }
19926
- function descriptionKey2(namespace, description) {
19849
+ function descriptionKey(namespace, description) {
19927
19850
  return `extract:${namespace}:${sha256Hex3(description.trim())}`;
19928
19851
  }
19929
19852
  function parseExtractionDescriptorRecord(record) {
@@ -20026,7 +19949,7 @@ var FilesystemOpensteerExtractionDescriptorStore = class {
20026
19949
  }
20027
19950
  async read(input) {
20028
19951
  const record = await this.registry.resolve({
20029
- key: descriptionKey2(this.namespace, input.description)
19952
+ key: descriptionKey(this.namespace, input.description)
20030
19953
  });
20031
19954
  return record === void 0 ? void 0 : parseExtractionDescriptorRecord(record);
20032
19955
  }
@@ -20038,7 +19961,7 @@ var FilesystemOpensteerExtractionDescriptorStore = class {
20038
19961
  ...input.schemaHash === void 0 ? {} : { schemaHash: input.schemaHash },
20039
19962
  ...input.sourceUrl === void 0 ? {} : { sourceUrl: input.sourceUrl }
20040
19963
  };
20041
- const key = descriptionKey2(this.namespace, input.description);
19964
+ const key = descriptionKey(this.namespace, input.description);
20042
19965
  const version = sha256Hex3(canonicalJsonString(payload));
20043
19966
  const existing = await this.registry.resolve({ key, version });
20044
19967
  if (existing) {
@@ -20077,7 +20000,7 @@ var MemoryOpensteerExtractionDescriptorStore = class {
20077
20000
  latestByKey = /* @__PURE__ */ new Map();
20078
20001
  recordsByKey = /* @__PURE__ */ new Map();
20079
20002
  async read(input) {
20080
- return this.latestByKey.get(descriptionKey2(this.namespace, input.description));
20003
+ return this.latestByKey.get(descriptionKey(this.namespace, input.description));
20081
20004
  }
20082
20005
  async write(input) {
20083
20006
  const payload = {
@@ -20087,7 +20010,7 @@ var MemoryOpensteerExtractionDescriptorStore = class {
20087
20010
  ...input.schemaHash === void 0 ? {} : { schemaHash: input.schemaHash },
20088
20011
  ...input.sourceUrl === void 0 ? {} : { sourceUrl: input.sourceUrl }
20089
20012
  };
20090
- const key = descriptionKey2(this.namespace, input.description);
20013
+ const key = descriptionKey(this.namespace, input.description);
20091
20014
  const version = sha256Hex3(canonicalJsonString(payload));
20092
20015
  const existing = this.recordsByKey.get(key)?.get(version);
20093
20016
  if (existing) {
@@ -20131,6 +20054,7 @@ var OPENSTEER_INTERACTIVE_ATTR = "data-opensteer-interactive";
20131
20054
  var OPENSTEER_HIDDEN_ATTR = "data-opensteer-hidden";
20132
20055
  var OPENSTEER_SCROLLABLE_ATTR = "data-opensteer-scrollable";
20133
20056
  var OPENSTEER_NODE_ID_ATTR = "data-os-node-id";
20057
+ var OPENSTEER_SPARSE_COUNTER_ATTR = "data-os-c";
20134
20058
  var OPENSTEER_BOUNDARY_ATTR = "data-os-boundary";
20135
20059
  var OPENSTEER_UNAVAILABLE_ATTR = "data-os-unavailable";
20136
20060
  var OPENSTEER_IFRAME_BOUNDARY_TAG = "os-iframe-root";
@@ -20635,7 +20559,82 @@ var VOID_TAGS2 = /* @__PURE__ */ new Set([
20635
20559
  ]);
20636
20560
 
20637
20561
  // ../runtime-core/src/sdk/snapshot/compiler.ts
20562
+ async function assignSparseCountersToLiveDom(engine, pageRef) {
20563
+ try {
20564
+ await engine.evaluatePage({
20565
+ pageRef,
20566
+ script: `(() => {
20567
+ let counter = 1;
20568
+ const walk = (root) => {
20569
+ for (const child of root.children) {
20570
+ child.setAttribute('data-os-c', String(counter++));
20571
+ walk(child);
20572
+ if (child.shadowRoot) walk(child.shadowRoot);
20573
+ }
20574
+ };
20575
+ walk(document);
20576
+ })()`
20577
+ });
20578
+ return true;
20579
+ } catch {
20580
+ return false;
20581
+ }
20582
+ }
20583
+ async function syncDenseCountersToLiveDom(engine, pageRef, sparseToDirectMapping) {
20584
+ const mappingObj = Object.fromEntries(sparseToDirectMapping);
20585
+ await engine.evaluatePage({
20586
+ pageRef,
20587
+ script: `((mapping) => {
20588
+ const walk = (root) => {
20589
+ for (const child of root.children) {
20590
+ child.removeAttribute('c');
20591
+ const sparse = child.getAttribute('data-os-c');
20592
+ if (sparse !== null) {
20593
+ const dense = mapping[sparse];
20594
+ if (dense !== undefined) {
20595
+ child.setAttribute('c', String(dense));
20596
+ }
20597
+ child.removeAttribute('data-os-c');
20598
+ }
20599
+ walk(child);
20600
+ if (child.shadowRoot) walk(child.shadowRoot);
20601
+ }
20602
+ };
20603
+ walk(document);
20604
+ })`,
20605
+ args: [mappingObj]
20606
+ });
20607
+ }
20608
+ function renumberCountersDensely(cleanedHtml, counterRecords) {
20609
+ const $ = cheerio__namespace.load(cleanedHtml, { xmlMode: false });
20610
+ const newRecords = /* @__PURE__ */ new Map();
20611
+ const sparseToDirectMapping = /* @__PURE__ */ new Map();
20612
+ let nextDense = 1;
20613
+ $("[c]").each(function renumberElement() {
20614
+ const el = $(this);
20615
+ const oldC = Number.parseInt(String(el.attr("c") || ""), 10);
20616
+ if (!Number.isFinite(oldC)) {
20617
+ return;
20618
+ }
20619
+ const record = counterRecords.get(oldC);
20620
+ if (!record) {
20621
+ return;
20622
+ }
20623
+ const denseC = nextDense++;
20624
+ el.attr("c", String(denseC));
20625
+ newRecords.set(denseC, { ...record, element: denseC });
20626
+ if (record.sparseCounter !== void 0) {
20627
+ sparseToDirectMapping.set(record.sparseCounter, denseC);
20628
+ }
20629
+ });
20630
+ return {
20631
+ html: $.html(),
20632
+ counterRecords: newRecords,
20633
+ sparseToDirectMapping
20634
+ };
20635
+ }
20638
20636
  async function compileOpensteerSnapshot(options) {
20637
+ const liveCountersEnabled = await assignSparseCountersToLiveDom(options.engine, options.pageRef);
20639
20638
  const pageInfo = await options.engine.getPageInfo({ pageRef: options.pageRef });
20640
20639
  const mainSnapshot = await getMainDocumentSnapshot(options.engine, options.pageRef);
20641
20640
  const snapshotsByDocumentRef = await collectDocumentSnapshots(options.engine, mainSnapshot);
@@ -20654,13 +20653,24 @@ async function compileOpensteerSnapshot(options) {
20654
20653
  const compiledHtml = assignCounters(rawHtml, renderedNodes);
20655
20654
  const cleanedHtml = options.mode === "extraction" ? cleanForExtraction(compiledHtml.html) : cleanForAction(compiledHtml.html);
20656
20655
  const filtered = retainVisibleCounterRecords(cleanedHtml, compiledHtml.counterRecords);
20656
+ const dense = renumberCountersDensely(cleanedHtml, filtered);
20657
+ if (liveCountersEnabled && dense.sparseToDirectMapping.size > 0) {
20658
+ try {
20659
+ await syncDenseCountersToLiveDom(
20660
+ options.engine,
20661
+ options.pageRef,
20662
+ dense.sparseToDirectMapping
20663
+ );
20664
+ } catch {
20665
+ }
20666
+ }
20657
20667
  return {
20658
20668
  url: pageInfo.url,
20659
20669
  title: pageInfo.title,
20660
20670
  mode: options.mode,
20661
- html: cleanedHtml,
20662
- counters: [...filtered.values()].map(toPublicCounterRecord),
20663
- counterRecords: filtered
20671
+ html: dense.html,
20672
+ counters: [...dense.counterRecords.values()].map(toPublicCounterRecord),
20673
+ counterRecords: dense.counterRecords
20664
20674
  };
20665
20675
  }
20666
20676
  async function getMainDocumentSnapshot(engine, pageRef) {
@@ -20889,6 +20899,9 @@ function assignCounters(rawHtml, renderedNodes) {
20889
20899
  if (!rendered) {
20890
20900
  return;
20891
20901
  }
20902
+ const rawSparseCounter = el.attr(OPENSTEER_SPARSE_COUNTER_ATTR);
20903
+ el.removeAttr(OPENSTEER_SPARSE_COUNTER_ATTR);
20904
+ const sparseCounter = rawSparseCounter ? Number.parseInt(rawSparseCounter, 10) : void 0;
20892
20905
  const counter = nextCounter++;
20893
20906
  el.attr("c", String(counter));
20894
20907
  counterRecords.set(counter, {
@@ -20906,7 +20919,8 @@ function assignCounters(rawHtml, renderedNodes) {
20906
20919
  shadowDepth: rendered.shadowDepth,
20907
20920
  interactive: rendered.interactive,
20908
20921
  locator: rendered.locator,
20909
- anchor: rendered.anchor
20922
+ anchor: rendered.anchor,
20923
+ ...sparseCounter !== void 0 && Number.isFinite(sparseCounter) ? { sparseCounter } : {}
20910
20924
  });
20911
20925
  });
20912
20926
  return {
@@ -22274,6 +22288,8 @@ var OpensteerSessionRuntime = class {
22274
22288
  injectedEngine;
22275
22289
  engineFactory;
22276
22290
  policy;
22291
+ injectedDescriptorStore;
22292
+ registryOverrides;
22277
22293
  cleanupRootOnClose;
22278
22294
  sessionInfoBase;
22279
22295
  root;
@@ -22291,13 +22307,15 @@ var OpensteerSessionRuntime = class {
22291
22307
  recipeCache = /* @__PURE__ */ new Map();
22292
22308
  ownsEngine = false;
22293
22309
  constructor(options) {
22294
- this.workspace = normalizeNamespace3(options.name);
22310
+ this.workspace = normalizeNamespace2(options.name);
22295
22311
  this.workspaceName = options.workspaceName?.trim() === void 0 || options.workspaceName?.trim().length === 0 ? void 0 : options.workspaceName.trim();
22296
22312
  this.root = options.workspace;
22297
22313
  this.rootPath = options.workspace?.rootPath ?? options.rootPath ?? path6__default.default.resolve(process.cwd(), ".opensteer", "temporary", crypto.randomUUID());
22298
22314
  this.injectedEngine = options.engine;
22299
22315
  this.engineFactory = options.engineFactory;
22300
22316
  this.policy = options.policy ?? defaultPolicy();
22317
+ this.injectedDescriptorStore = options.descriptorStore;
22318
+ this.registryOverrides = options.registryOverrides;
22301
22319
  this.cleanupRootOnClose = options.cleanupRootOnClose ?? options.workspace === void 0;
22302
22320
  this.sessionInfoBase = options.sessionInfo ?? {};
22303
22321
  if (this.injectedEngine === void 0 && this.engineFactory === void 0) {
@@ -22333,7 +22351,7 @@ var OpensteerSessionRuntime = class {
22333
22351
  }
22334
22352
  async open(input = {}, options = {}) {
22335
22353
  assertValidSemanticOperationInput("session.open", input);
22336
- if (input.workspace !== void 0 && normalizeNamespace3(input.workspace) !== this.workspace) {
22354
+ if (input.workspace !== void 0 && normalizeNamespace2(input.workspace) !== this.workspace) {
22337
22355
  throw new Error(
22338
22356
  `session.open requested workspace "${input.workspace}" but runtime is bound to "${this.workspace}"`
22339
22357
  );
@@ -24749,8 +24767,7 @@ var OpensteerSessionRuntime = class {
24749
24767
  const inferred = inferRequestPlanFromNetworkRecord(record, {
24750
24768
  recordId: candidate.recordId,
24751
24769
  key: input.key,
24752
- version: input.version,
24753
- lifecycle: "draft"
24770
+ version: input.version
24754
24771
  });
24755
24772
  const defaultHeaders = inferred.payload.endpoint.defaultHeaders === void 0 ? void 0 : stripManagedRequestHeaders(
24756
24773
  inferred.payload.endpoint.defaultHeaders,
@@ -25378,8 +25395,7 @@ var OpensteerSessionRuntime = class {
25378
25395
  recordId: input.recordId,
25379
25396
  id: record.id,
25380
25397
  key: record.key,
25381
- version: record.version,
25382
- lifecycle: record.lifecycle
25398
+ version: record.version
25383
25399
  }
25384
25400
  });
25385
25401
  return record;
@@ -25420,8 +25436,7 @@ var OpensteerSessionRuntime = class {
25420
25436
  data: {
25421
25437
  id: record.id,
25422
25438
  key: record.key,
25423
- version: record.version,
25424
- lifecycle: record.lifecycle
25439
+ version: record.version
25425
25440
  }
25426
25441
  });
25427
25442
  return record;
@@ -25467,8 +25482,7 @@ var OpensteerSessionRuntime = class {
25467
25482
  data: {
25468
25483
  id: record.id,
25469
25484
  key: record.key,
25470
- version: record.version,
25471
- lifecycle: record.lifecycle
25485
+ version: record.version
25472
25486
  }
25473
25487
  });
25474
25488
  return record;
@@ -26339,18 +26353,12 @@ var OpensteerSessionRuntime = class {
26339
26353
  }
26340
26354
  if (target.kind === "element") {
26341
26355
  const counter = this.latestSnapshot?.counterRecords.get(target.element);
26342
- if (!counter) {
26343
- throw new Error(`no counter ${String(target.element)} is available in the latest snapshot`);
26344
- }
26356
+ const elementTarget = counter ? { kind: "live", locator: counter.locator, anchor: counter.anchor } : { kind: "selector", selector: `[c="${String(target.element)}"]` };
26345
26357
  const resolved2 = await timeout.runStep(
26346
26358
  () => this.requireDom().resolveTarget({
26347
26359
  pageRef,
26348
26360
  method,
26349
- target: {
26350
- kind: "live",
26351
- locator: counter.locator,
26352
- anchor: counter.anchor
26353
- }
26361
+ target: elementTarget
26354
26362
  })
26355
26363
  );
26356
26364
  const stablePath2 = resolved2.replayPath ?? await timeout.runStep(
@@ -27593,7 +27601,7 @@ var OpensteerSessionRuntime = class {
27593
27601
  }
27594
27602
  async touchRequestPlanFreshness(plan) {
27595
27603
  const freshness = touchFreshness(plan.freshness);
27596
- await this.requireRoot().registry.requestPlans.updateMetadata({
27604
+ await this.requireRoot().registry.requestPlans.updateFreshness({
27597
27605
  id: plan.id,
27598
27606
  ...freshness === void 0 ? {} : { freshness }
27599
27607
  });
@@ -28262,21 +28270,40 @@ var OpensteerSessionRuntime = class {
28262
28270
  };
28263
28271
  }
28264
28272
  const counter = this.latestSnapshot?.counterRecords.get(target.element);
28265
- if (!counter) {
28266
- throw new Error(`no counter ${String(target.element)} is available in the latest snapshot`);
28273
+ if (counter) {
28274
+ return {
28275
+ kind: "live",
28276
+ locator: counter.locator,
28277
+ anchor: counter.anchor
28278
+ };
28267
28279
  }
28268
28280
  return {
28269
- kind: "live",
28270
- locator: counter.locator,
28271
- anchor: counter.anchor
28281
+ kind: "selector",
28282
+ selector: `[c="${String(target.element)}"]`
28272
28283
  };
28273
28284
  }
28274
28285
  async ensureRoot() {
28275
- this.root ??= await createFilesystemOpensteerWorkspace({
28276
- rootPath: this.rootPath,
28277
- ...this.workspaceName === void 0 ? {} : { workspace: this.workspaceName },
28278
- scope: this.workspaceName === void 0 ? "temporary" : "workspace"
28279
- });
28286
+ if (!this.root) {
28287
+ const workspace = await createFilesystemOpensteerWorkspace({
28288
+ rootPath: this.rootPath,
28289
+ ...this.workspaceName === void 0 ? {} : { workspace: this.workspaceName },
28290
+ scope: this.workspaceName === void 0 ? "temporary" : "workspace"
28291
+ });
28292
+ if (this.registryOverrides) {
28293
+ const overrides = this.registryOverrides;
28294
+ this.root = {
28295
+ ...workspace,
28296
+ registry: {
28297
+ ...workspace.registry,
28298
+ ...overrides.requestPlans === void 0 ? {} : { requestPlans: overrides.requestPlans },
28299
+ ...overrides.authRecipes === void 0 ? {} : { authRecipes: overrides.authRecipes },
28300
+ ...overrides.recipes === void 0 ? {} : { recipes: overrides.recipes }
28301
+ }
28302
+ };
28303
+ } else {
28304
+ this.root = workspace;
28305
+ }
28306
+ }
28280
28307
  return this.root;
28281
28308
  }
28282
28309
  async ensureEngine(overrides = {}) {
@@ -28302,6 +28329,7 @@ var OpensteerSessionRuntime = class {
28302
28329
  engine,
28303
28330
  root,
28304
28331
  namespace: this.workspace,
28332
+ ...this.injectedDescriptorStore === void 0 ? {} : { descriptorStore: this.injectedDescriptorStore },
28305
28333
  policy: this.policy
28306
28334
  });
28307
28335
  this.computer = createComputerUseRuntime({
@@ -28888,7 +28916,6 @@ function buildMinimizedRequestPlan(input) {
28888
28916
  sourceId: input.record.recordId,
28889
28917
  ...input.record.source === "saved" && input.record.savedAt !== void 0 ? { capturedAt: input.record.savedAt } : {}
28890
28918
  },
28891
- lifecycle: "draft",
28892
28919
  payload: normalizeRequestPlanPayload({
28893
28920
  transport: {
28894
28921
  kind: input.transport
@@ -31043,7 +31070,7 @@ function directionToDelta(direction, amount) {
31043
31070
  return { x: amount, y: 0 };
31044
31071
  }
31045
31072
  }
31046
- function normalizeNamespace3(value) {
31073
+ function normalizeNamespace2(value) {
31047
31074
  const normalized = String(value ?? "default").trim();
31048
31075
  return normalized.length === 0 ? "default" : normalized;
31049
31076
  }
@@ -31104,19 +31131,22 @@ var OpensteerRuntime = class extends OpensteerSessionRuntime {
31104
31131
  ...options.browser === void 0 ? {} : { browser: options.browser },
31105
31132
  ...options.context === void 0 ? {} : { context: options.context }
31106
31133
  });
31107
- super(buildSharedRuntimeOptions({
31108
- name: publicWorkspace ?? "default",
31109
- rootPath,
31110
- ...publicWorkspace === void 0 ? {} : { workspaceName: publicWorkspace },
31111
- ...options.browser === void 0 ? {} : { browser: options.browser },
31112
- ...options.launch === void 0 ? {} : { launch: options.launch },
31113
- ...options.context === void 0 ? {} : { context: options.context },
31114
- engineName,
31115
- ...options.engine === void 0 ? {} : { engine: options.engine },
31116
- ...options.engineFactory === void 0 ? {} : { engineFactory: options.engineFactory },
31117
- ...options.policy === void 0 ? {} : { policy: options.policy },
31118
- cleanupRootOnClose
31119
- }));
31134
+ super(
31135
+ buildSharedRuntimeOptions({
31136
+ name: publicWorkspace ?? "default",
31137
+ rootPath,
31138
+ ...publicWorkspace === void 0 ? {} : { workspaceName: publicWorkspace },
31139
+ ...options.browser === void 0 ? {} : { browser: options.browser },
31140
+ ...options.launch === void 0 ? {} : { launch: options.launch },
31141
+ ...options.context === void 0 ? {} : { context: options.context },
31142
+ engineName,
31143
+ ...options.engine === void 0 ? {} : { engine: options.engine },
31144
+ ...options.engineFactory === void 0 ? {} : { engineFactory: options.engineFactory },
31145
+ ...options.policy === void 0 ? {} : { policy: options.policy },
31146
+ ...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
31147
+ cleanupRootOnClose
31148
+ })
31149
+ );
31120
31150
  }
31121
31151
  };
31122
31152
  var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
@@ -31129,18 +31159,21 @@ var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
31129
31159
  ...options.browser === void 0 ? {} : { browser: options.browser },
31130
31160
  ...options.context === void 0 ? {} : { context: options.context }
31131
31161
  });
31132
- super(buildSharedRuntimeOptions({
31133
- name: options.name,
31134
- rootPath,
31135
- ...options.browser === void 0 ? {} : { browser: options.browser },
31136
- ...options.launch === void 0 ? {} : { launch: options.launch },
31137
- ...options.context === void 0 ? {} : { context: options.context },
31138
- engineName,
31139
- ...options.engine === void 0 ? {} : { engine: options.engine },
31140
- ...options.engineFactory === void 0 ? {} : { engineFactory: options.engineFactory },
31141
- ...options.policy === void 0 ? {} : { policy: options.policy },
31142
- cleanupRootOnClose
31143
- }));
31162
+ super(
31163
+ buildSharedRuntimeOptions({
31164
+ name: options.name,
31165
+ rootPath,
31166
+ ...options.browser === void 0 ? {} : { browser: options.browser },
31167
+ ...options.launch === void 0 ? {} : { launch: options.launch },
31168
+ ...options.context === void 0 ? {} : { context: options.context },
31169
+ engineName,
31170
+ ...options.engine === void 0 ? {} : { engine: options.engine },
31171
+ ...options.engineFactory === void 0 ? {} : { engineFactory: options.engineFactory },
31172
+ ...options.policy === void 0 ? {} : { policy: options.policy },
31173
+ ...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
31174
+ cleanupRootOnClose
31175
+ })
31176
+ );
31144
31177
  }
31145
31178
  };
31146
31179
  function buildSharedRuntimeOptions(input) {
@@ -31160,6 +31193,7 @@ function buildSharedRuntimeOptions(input) {
31160
31193
  ...input.engine === void 0 ? {} : { engine: input.engine },
31161
31194
  ...input.engine === void 0 ? { engineFactory } : {},
31162
31195
  ...input.policy === void 0 ? {} : { policy: input.policy },
31196
+ ...input.descriptorStore === void 0 ? {} : { descriptorStore: input.descriptorStore },
31163
31197
  cleanupRootOnClose: input.cleanupRootOnClose,
31164
31198
  sessionInfo: {
31165
31199
  provider: {
@@ -31183,45 +31217,44 @@ function resolveOwnership(browser) {
31183
31217
  return typeof browser === "object" && browser.mode === "attach" ? "attached" : "owned";
31184
31218
  }
31185
31219
 
31186
- // src/mode/config.ts
31187
- var OPENSTEER_EXECUTION_MODES = ["local", "cloud"];
31188
- function assertExecutionModeSupportsEngine(mode, engine) {
31220
+ // src/provider/config.ts
31221
+ var OPENSTEER_PROVIDER_KINDS = ["local", "cloud"];
31222
+ function assertProviderSupportsEngine(provider, engine) {
31189
31223
  if (engine !== "abp") {
31190
31224
  return;
31191
31225
  }
31192
- if (mode === "cloud") {
31226
+ if (provider === "cloud") {
31193
31227
  throw new Error(
31194
- "ABP is not supported in cloud mode. Cloud mode currently requires Playwright."
31228
+ "ABP is not supported for provider=cloud. Cloud provider currently requires Playwright."
31195
31229
  );
31196
31230
  }
31197
31231
  }
31198
- function normalizeOpensteerExecutionMode(value, source = "OPENSTEER_MODE") {
31232
+ function normalizeOpensteerProviderKind(value, source = "OPENSTEER_PROVIDER") {
31199
31233
  const normalized = value.trim().toLowerCase();
31200
- if (normalized === OPENSTEER_EXECUTION_MODES[0] || normalized === OPENSTEER_EXECUTION_MODES[1]) {
31234
+ if (normalized === OPENSTEER_PROVIDER_KINDS[0] || normalized === OPENSTEER_PROVIDER_KINDS[1]) {
31201
31235
  return normalized;
31202
31236
  }
31203
31237
  throw new Error(
31204
- `${source} must be one of ${OPENSTEER_EXECUTION_MODES.join(", ")}; received "${value}".`
31238
+ `${source} must be one of ${OPENSTEER_PROVIDER_KINDS.join(", ")}; received "${value}".`
31205
31239
  );
31206
31240
  }
31207
- function resolveOpensteerExecutionMode(input = {}) {
31208
- const explicitFlags = [input.local, input.cloud].filter(Boolean).length;
31209
- if (explicitFlags > 1) {
31210
- throw new Error("Choose exactly one execution mode: local or cloud.");
31211
- }
31212
- if (input.explicit) {
31213
- return input.explicit;
31214
- }
31215
- if (input.local) {
31216
- return "local";
31217
- }
31218
- if (input.cloud) {
31219
- return "cloud";
31241
+ function resolveOpensteerProvider(input = {}) {
31242
+ if (input.provider) {
31243
+ return {
31244
+ kind: input.provider.kind,
31245
+ source: "explicit"
31246
+ };
31220
31247
  }
31221
- if (input.environment !== void 0 && input.environment.trim().length > 0) {
31222
- return normalizeOpensteerExecutionMode(input.environment);
31248
+ if (input.environmentProvider !== void 0 && input.environmentProvider.trim().length > 0) {
31249
+ return {
31250
+ kind: normalizeOpensteerProviderKind(input.environmentProvider),
31251
+ source: "env"
31252
+ };
31223
31253
  }
31224
- return "local";
31254
+ return {
31255
+ kind: "local",
31256
+ source: "default"
31257
+ };
31225
31258
  }
31226
31259
  var execFile2 = util.promisify(child_process.execFile);
31227
31260
  var DEFAULT_CAPTURE_TIMEOUT_MS = 3e4;
@@ -31803,15 +31836,12 @@ var OpensteerCloudClient = class {
31803
31836
  return await response.json();
31804
31837
  }
31805
31838
  async issueAccess(sessionId, capabilities) {
31806
- const response = await this.request(
31807
- `/v1/sessions/${encodeURIComponent(sessionId)}/access`,
31808
- {
31809
- method: "POST",
31810
- body: {
31811
- capabilities
31812
- }
31839
+ const response = await this.request(`/v1/sessions/${encodeURIComponent(sessionId)}/access`, {
31840
+ method: "POST",
31841
+ body: {
31842
+ capabilities
31813
31843
  }
31814
- );
31844
+ });
31815
31845
  return await response.json();
31816
31846
  }
31817
31847
  async closeSession(sessionId) {
@@ -31869,6 +31899,34 @@ var OpensteerCloudClient = class {
31869
31899
  async syncBrowserProfileCookies(input) {
31870
31900
  return syncBrowserProfileCookies(this, input);
31871
31901
  }
31902
+ async importSelectorCache(entries) {
31903
+ const response = await this.request("/selector-cache/import", {
31904
+ method: "POST",
31905
+ body: { entries }
31906
+ });
31907
+ return await response.json();
31908
+ }
31909
+ async importRequestPlans(entries) {
31910
+ const response = await this.request("/registry/request-plans/import", {
31911
+ method: "POST",
31912
+ body: { entries }
31913
+ });
31914
+ return await response.json();
31915
+ }
31916
+ async importRecipes(entries) {
31917
+ const response = await this.request("/registry/recipes/import", {
31918
+ method: "POST",
31919
+ body: { entries }
31920
+ });
31921
+ return await response.json();
31922
+ }
31923
+ async importAuthRecipes(entries) {
31924
+ const response = await this.request("/registry/auth-recipes/import", {
31925
+ method: "POST",
31926
+ body: { entries }
31927
+ });
31928
+ return await response.json();
31929
+ }
31872
31930
  buildAuthorizationHeader() {
31873
31931
  return `Bearer ${this.config.apiKey}`;
31874
31932
  }
@@ -31939,22 +31997,26 @@ function wrapCloudFetchError(error, input) {
31939
31997
 
31940
31998
  // src/cloud/config.ts
31941
31999
  function resolveCloudConfig(input = {}) {
31942
- const mode = resolveOpensteerExecutionMode({
31943
- ...input.mode === void 0 ? {} : { explicit: input.mode },
31944
- ...input.enabled === void 0 ? {} : { cloud: input.enabled },
31945
- ...process.env.OPENSTEER_MODE === void 0 ? {} : { environment: process.env.OPENSTEER_MODE }
32000
+ const provider = resolveOpensteerProvider({
32001
+ ...input.provider === void 0 ? {} : { provider: input.provider },
32002
+ ...input.environmentProvider === void 0 ? {} : { environmentProvider: input.environmentProvider }
31946
32003
  });
31947
- if (mode !== "cloud") {
32004
+ if (provider.kind !== "cloud") {
31948
32005
  return void 0;
31949
32006
  }
31950
- const apiKey = input.apiKey ?? process.env.OPENSTEER_API_KEY;
32007
+ const cloudProvider = input.provider?.kind === "cloud" ? input.provider : void 0;
32008
+ const apiKey = cloudProvider?.apiKey ?? process.env.OPENSTEER_API_KEY;
31951
32009
  if (!apiKey || apiKey.trim().length === 0) {
31952
- throw new Error("Cloud mode requires OPENSTEER_API_KEY or cloud.apiKey.");
32010
+ throw new Error("provider=cloud requires OPENSTEER_API_KEY or provider.apiKey.");
32011
+ }
32012
+ const baseUrl = cloudProvider?.baseUrl ?? process.env.OPENSTEER_BASE_URL;
32013
+ if (!baseUrl || baseUrl.trim().length === 0) {
32014
+ throw new Error("provider=cloud requires OPENSTEER_BASE_URL or provider.baseUrl.");
31953
32015
  }
31954
32016
  return {
31955
32017
  apiKey: apiKey.trim(),
31956
- baseUrl: (input.baseUrl ?? process.env.OPENSTEER_BASE_URL ?? "https://api.opensteer.dev").trim().replace(/\/+$/, ""),
31957
- ...input.browserProfile === void 0 ? {} : { browserProfile: input.browserProfile }
32018
+ baseUrl: baseUrl.trim().replace(/\/+$/, ""),
32019
+ ...cloudProvider?.browserProfile === void 0 ? {} : { browserProfile: cloudProvider.browserProfile }
31958
32020
  };
31959
32021
  }
31960
32022
  var OpensteerSemanticRestError = class extends Error {
@@ -32177,9 +32239,7 @@ var OpensteerCloudAutomationClient = class {
32177
32239
  if (registration.kind === "route") {
32178
32240
  await this.route(registration.input);
32179
32241
  } else {
32180
- await this.interceptScript(
32181
- registration.input
32182
- );
32242
+ await this.interceptScript(registration.input);
32183
32243
  }
32184
32244
  }
32185
32245
  }
@@ -32378,6 +32438,116 @@ function asRecord(value) {
32378
32438
  return value;
32379
32439
  }
32380
32440
 
32441
+ // src/cloud/registry-sync.ts
32442
+ var REGISTRY_SYNC_MAX_PAYLOAD_BYTES = 15e5;
32443
+ var REGISTRY_SYNC_MAX_ENTRIES_PER_BATCH = 100;
32444
+ async function syncLocalRegistryToCloud(client, workspace, store) {
32445
+ const [descriptors, requestPlans, recipes, authRecipes] = await Promise.all([
32446
+ store.registry.descriptors.list(),
32447
+ store.registry.requestPlans.list(),
32448
+ store.registry.recipes.list(),
32449
+ store.registry.authRecipes.list()
32450
+ ]);
32451
+ const selectorEntries = descriptors.flatMap((record) => {
32452
+ const entry = toSelectorCacheImportEntry(workspace, record);
32453
+ return entry === void 0 ? [] : [entry];
32454
+ });
32455
+ await Promise.all([
32456
+ importInBatches(selectorEntries, (entries) => client.importSelectorCache(entries)),
32457
+ importInBatches(
32458
+ requestPlans.map((record) => toRequestPlanImportEntry(workspace, record)),
32459
+ (entries) => client.importRequestPlans(entries)
32460
+ ),
32461
+ importInBatches(
32462
+ recipes.map((record) => toRegistryImportEntry(workspace, record)),
32463
+ (entries) => client.importRecipes(entries)
32464
+ ),
32465
+ importInBatches(
32466
+ authRecipes.map((record) => toRegistryImportEntry(workspace, record)),
32467
+ (entries) => client.importAuthRecipes(entries)
32468
+ )
32469
+ ]);
32470
+ }
32471
+ function toSelectorCacheImportEntry(workspace, record) {
32472
+ const descriptor = parseDomDescriptorRecord(record);
32473
+ if (descriptor === void 0) {
32474
+ return void 0;
32475
+ }
32476
+ return {
32477
+ workspace,
32478
+ method: descriptor.payload.method,
32479
+ descriptionHash: hashDomDescriptorDescription(descriptor.payload.description),
32480
+ description: descriptor.payload.description,
32481
+ path: descriptor.payload.path,
32482
+ createdAt: descriptor.createdAt,
32483
+ updatedAt: descriptor.updatedAt
32484
+ };
32485
+ }
32486
+ function toRegistryImportEntry(workspace, record) {
32487
+ return {
32488
+ workspace,
32489
+ recordId: record.id,
32490
+ key: record.key,
32491
+ version: record.version,
32492
+ contentHash: record.contentHash,
32493
+ tags: record.tags,
32494
+ ...record.provenance === void 0 ? {} : { provenance: record.provenance },
32495
+ payload: record.payload,
32496
+ createdAt: record.createdAt,
32497
+ updatedAt: record.updatedAt
32498
+ };
32499
+ }
32500
+ function toRequestPlanImportEntry(workspace, record) {
32501
+ return {
32502
+ workspace,
32503
+ recordId: record.id,
32504
+ key: record.key,
32505
+ version: record.version,
32506
+ contentHash: record.contentHash,
32507
+ tags: record.tags,
32508
+ ...record.provenance === void 0 ? {} : { provenance: record.provenance },
32509
+ payload: record.payload,
32510
+ ...record.freshness === void 0 ? {} : { freshness: record.freshness },
32511
+ createdAt: record.createdAt,
32512
+ updatedAt: record.updatedAt
32513
+ };
32514
+ }
32515
+ async function importInBatches(entries, importBatch) {
32516
+ if (entries.length === 0) {
32517
+ return;
32518
+ }
32519
+ for (const batch of chunkEntries(entries)) {
32520
+ await importBatch(batch);
32521
+ }
32522
+ }
32523
+ function chunkEntries(entries) {
32524
+ const batches = [];
32525
+ let currentBatch = [];
32526
+ for (const entry of entries) {
32527
+ if (payloadByteLength([entry]) > REGISTRY_SYNC_MAX_PAYLOAD_BYTES) {
32528
+ continue;
32529
+ }
32530
+ if (currentBatch.length === 0) {
32531
+ currentBatch = [entry];
32532
+ continue;
32533
+ }
32534
+ const nextBatch = [...currentBatch, entry];
32535
+ if (nextBatch.length > REGISTRY_SYNC_MAX_ENTRIES_PER_BATCH || payloadByteLength(nextBatch) > REGISTRY_SYNC_MAX_PAYLOAD_BYTES) {
32536
+ batches.push(currentBatch);
32537
+ currentBatch = [entry];
32538
+ continue;
32539
+ }
32540
+ currentBatch = nextBatch;
32541
+ }
32542
+ if (currentBatch.length > 0) {
32543
+ batches.push(currentBatch);
32544
+ }
32545
+ return batches;
32546
+ }
32547
+ function payloadByteLength(entries) {
32548
+ return Buffer.byteLength(JSON.stringify({ entries }), "utf8");
32549
+ }
32550
+
32381
32551
  // src/cloud/session-proxy.ts
32382
32552
  var TEMPORARY_CLOUD_WORKSPACE_PREFIX = "opensteer-cloud-workspace-";
32383
32553
  var CloudSessionProxy = class {
@@ -32682,7 +32852,6 @@ var CloudSessionProxy = class {
32682
32852
  layout: "opensteer-session",
32683
32853
  version: 1,
32684
32854
  provider: "cloud",
32685
- mode: "cloud",
32686
32855
  ...this.workspace === void 0 ? {} : { workspace: this.workspace },
32687
32856
  sessionId: this.sessionId,
32688
32857
  baseUrl: this.sessionBaseUrl,
@@ -32729,9 +32898,11 @@ var CloudSessionProxy = class {
32729
32898
  assertSupportedCloudBrowserMode(input.browser);
32730
32899
  const persisted = await this.loadPersistedSession();
32731
32900
  if (persisted !== void 0 && await this.isReusableCloudSession(persisted.sessionId)) {
32901
+ await this.syncRegistryToCloud();
32732
32902
  this.bindClient(persisted);
32733
32903
  return;
32734
32904
  }
32905
+ await this.syncRegistryToCloud();
32735
32906
  const session = await this.cloud.createSession({
32736
32907
  ...this.workspace === void 0 ? {} : { name: this.workspace },
32737
32908
  ...input.launch === void 0 ? {} : { browser: input.launch },
@@ -32742,7 +32913,6 @@ var CloudSessionProxy = class {
32742
32913
  layout: "opensteer-session",
32743
32914
  version: 1,
32744
32915
  provider: "cloud",
32745
- mode: "cloud",
32746
32916
  ...this.workspace === void 0 ? {} : { workspace: this.workspace },
32747
32917
  sessionId: session.sessionId,
32748
32918
  baseUrl: session.baseUrl,
@@ -32752,6 +32922,16 @@ var CloudSessionProxy = class {
32752
32922
  await this.writePersistedSession(record);
32753
32923
  this.bindClient(record);
32754
32924
  }
32925
+ async syncRegistryToCloud() {
32926
+ if (this.workspace === void 0) {
32927
+ return;
32928
+ }
32929
+ try {
32930
+ const workspaceStore = await this.ensureWorkspaceStore();
32931
+ await syncLocalRegistryToCloud(this.cloud, this.workspace, workspaceStore);
32932
+ } catch {
32933
+ }
32934
+ }
32755
32935
  bindClient(record) {
32756
32936
  this.sessionId = record.sessionId;
32757
32937
  this.sessionBaseUrl = record.baseUrl;
@@ -32781,7 +32961,7 @@ var CloudSessionProxy = class {
32781
32961
  await writePersistedSessionRecord(workspace.rootPath, record);
32782
32962
  }
32783
32963
  async clearPersistedSession() {
32784
- await clearPersistedSessionRecord(this.rootPath).catch(() => void 0);
32964
+ await clearPersistedSessionRecord(this.rootPath, "cloud").catch(() => void 0);
32785
32965
  }
32786
32966
  async isReusableCloudSession(sessionId) {
32787
32967
  try {
@@ -32824,49 +33004,30 @@ function isMissingCloudSessionError(error) {
32824
33004
 
32825
33005
  // src/sdk/runtime-resolution.ts
32826
33006
  function resolveOpensteerRuntimeConfig(input = {}) {
32827
- if (input.provider?.kind === "cloud") {
32828
- return {
32829
- mode: "cloud",
32830
- cloud: resolveCloudConfig({
32831
- enabled: true,
32832
- ...input.provider,
32833
- mode: "cloud"
32834
- })
32835
- };
32836
- }
32837
- if (input.provider?.kind === "local") {
32838
- return {
32839
- mode: "local"
32840
- };
32841
- }
32842
- const mode = resolveOpensteerExecutionMode({
32843
- ...input.mode === void 0 ? {} : { explicit: input.mode },
32844
- cloud: input.cloud !== void 0 && input.cloud !== false,
32845
- ...input.environmentMode === void 0 ? {} : { environment: input.environmentMode }
33007
+ const provider = resolveOpensteerProvider({
33008
+ ...input.provider === void 0 ? {} : { provider: input.provider },
33009
+ ...input.environmentProvider === void 0 ? {} : { environmentProvider: input.environmentProvider }
32846
33010
  });
32847
- if (mode === "cloud") {
33011
+ if (provider.kind === "cloud") {
32848
33012
  return {
32849
- mode,
33013
+ provider,
32850
33014
  cloud: resolveCloudConfig({
32851
- enabled: true,
32852
- ...typeof input.cloud === "object" ? input.cloud : {},
32853
- mode
33015
+ ...input.provider === void 0 ? {} : { provider: input.provider },
33016
+ ...input.environmentProvider === void 0 ? {} : { environmentProvider: input.environmentProvider }
32854
33017
  })
32855
33018
  };
32856
33019
  }
32857
- return { mode };
33020
+ return { provider };
32858
33021
  }
32859
33022
  function createOpensteerSemanticRuntime(input = {}) {
32860
33023
  const runtimeOptions = input.runtimeOptions ?? {};
32861
33024
  const engine = input.engine ?? runtimeOptions.engineName ?? DEFAULT_OPENSTEER_ENGINE;
32862
33025
  const config = resolveOpensteerRuntimeConfig({
32863
- ...input.cloud === void 0 ? {} : { cloud: input.cloud },
32864
33026
  ...input.provider === void 0 ? {} : { provider: input.provider },
32865
- ...input.mode === void 0 ? {} : { mode: input.mode },
32866
- ...process.env.OPENSTEER_MODE === void 0 ? {} : { environmentMode: process.env.OPENSTEER_MODE }
33027
+ ...process.env.OPENSTEER_PROVIDER === void 0 ? {} : { environmentProvider: process.env.OPENSTEER_PROVIDER }
32867
33028
  });
32868
- assertExecutionModeSupportsEngine(config.mode, engine);
32869
- if (config.mode === "cloud") {
33029
+ assertProviderSupportsEngine(config.provider.kind, engine);
33030
+ if (config.provider.kind === "cloud") {
32870
33031
  return new CloudSessionProxy(new OpensteerCloudClient(config.cloud), {
32871
33032
  ...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
32872
33033
  ...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
@@ -32886,41 +33047,37 @@ var Opensteer = class {
32886
33047
  browserManager;
32887
33048
  browser;
32888
33049
  constructor(options = {}) {
33050
+ const { provider, engineName, ...runtimeOptions } = options;
32889
33051
  const runtimeConfig = resolveOpensteerRuntimeConfig({
32890
- ...options.cloud === void 0 ? {} : { cloud: options.cloud },
32891
- ...options.provider === void 0 ? {} : { provider: options.provider },
32892
- ...process.env.OPENSTEER_MODE === void 0 ? {} : { environmentMode: process.env.OPENSTEER_MODE }
33052
+ ...provider === void 0 ? {} : { provider },
33053
+ ...process.env.OPENSTEER_PROVIDER === void 0 ? {} : { environmentProvider: process.env.OPENSTEER_PROVIDER }
32893
33054
  });
32894
- if (runtimeConfig.mode === "cloud") {
33055
+ if (runtimeConfig.provider.kind === "cloud") {
32895
33056
  this.browserManager = void 0;
32896
33057
  this.runtime = createOpensteerSemanticRuntime({
32897
- mode: runtimeConfig.mode,
32898
- ...options.cloud === void 0 ? {} : { cloud: options.cloud },
32899
- ...options.provider === void 0 ? {} : { provider: options.provider },
32900
- ...options.engineName === void 0 ? {} : { engine: options.engineName },
33058
+ ...provider === void 0 ? {} : { provider },
33059
+ ...engineName === void 0 ? {} : { engine: engineName },
32901
33060
  runtimeOptions: {
32902
- ...options
33061
+ ...runtimeOptions
32903
33062
  }
32904
33063
  });
32905
33064
  this.browser = createUnsupportedBrowserController();
32906
33065
  return;
32907
33066
  }
32908
33067
  this.browserManager = new OpensteerBrowserManager({
32909
- ...options.rootDir === void 0 ? {} : { rootDir: options.rootDir },
32910
- ...options.rootPath === void 0 ? {} : { rootPath: options.rootPath },
32911
- ...options.workspace === void 0 ? {} : { workspace: options.workspace },
32912
- ...options.engineName === void 0 ? {} : { engineName: options.engineName },
32913
- ...options.browser === void 0 ? {} : { browser: options.browser },
32914
- ...options.launch === void 0 ? {} : { launch: options.launch },
32915
- ...options.context === void 0 ? {} : { context: options.context }
33068
+ ...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
33069
+ ...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
33070
+ ...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
33071
+ ...engineName === void 0 ? {} : { engineName },
33072
+ ...runtimeOptions.browser === void 0 ? {} : { browser: runtimeOptions.browser },
33073
+ ...runtimeOptions.launch === void 0 ? {} : { launch: runtimeOptions.launch },
33074
+ ...runtimeOptions.context === void 0 ? {} : { context: runtimeOptions.context }
32916
33075
  });
32917
33076
  this.runtime = createOpensteerSemanticRuntime({
32918
- mode: runtimeConfig.mode,
32919
- ...options.cloud === void 0 ? {} : { cloud: options.cloud },
32920
- ...options.provider === void 0 ? {} : { provider: options.provider },
32921
- ...options.engineName === void 0 ? {} : { engine: options.engineName },
33077
+ ...provider === void 0 ? {} : { provider },
33078
+ ...engineName === void 0 ? {} : { engine: engineName },
32922
33079
  runtimeOptions: {
32923
- ...options,
33080
+ ...runtimeOptions,
32924
33081
  rootPath: this.browserManager.rootPath,
32925
33082
  cleanupRootOnClose: this.browserManager.cleanupRootOnDisconnect
32926
33083
  }
@@ -32969,10 +33126,6 @@ var Opensteer = class {
32969
33126
  } : input;
32970
33127
  return this.runtime.addInitScript(normalized);
32971
33128
  }
32972
- async snapshot(input = {}) {
32973
- const mode = typeof input === "string" ? input : input.mode;
32974
- return this.runtime.snapshot(mode === void 0 ? {} : { mode });
32975
- }
32976
33129
  async click(input) {
32977
33130
  const normalized = normalizeTargetOptions(input);
32978
33131
  return this.runtime.click(normalized);
@@ -33052,6 +33205,9 @@ var Opensteer = class {
33052
33205
  await delay2(pollIntervalMs);
33053
33206
  }
33054
33207
  }
33208
+ async snapshot(input = {}) {
33209
+ return this.runtime.snapshot(typeof input === "string" ? { mode: input } : input);
33210
+ }
33055
33211
  async saveNetwork(input) {
33056
33212
  return this.runtime.saveNetwork(input);
33057
33213
  }
@@ -33273,6 +33429,7 @@ exports.OpensteerCloudClient = OpensteerCloudClient;
33273
33429
  exports.OpensteerRuntime = OpensteerRuntime;
33274
33430
  exports.OpensteerSessionRuntime = OpensteerSessionRuntime2;
33275
33431
  exports.STABLE_PRIMARY_ATTR_KEYS = STABLE_PRIMARY_ATTR_KEYS;
33432
+ exports.assertProviderSupportsEngine = assertProviderSupportsEngine;
33276
33433
  exports.buildArrayFieldPathCandidates = buildArrayFieldPathCandidates;
33277
33434
  exports.buildPathCandidates = buildPathCandidates;
33278
33435
  exports.buildPathSelectorHint = buildPathSelectorHint;
@@ -33292,26 +33449,26 @@ exports.defaultTimeoutPolicy = defaultTimeoutPolicy;
33292
33449
  exports.delayWithSignal = delayWithSignal;
33293
33450
  exports.discoverLocalCdpBrowsers = discoverLocalCdpBrowsers;
33294
33451
  exports.dispatchSemanticOperation = dispatchSemanticOperation;
33295
- exports.hasPersistedCloudSession = hasPersistedCloudSession;
33296
33452
  exports.inspectCdpEndpoint = inspectCdpEndpoint;
33297
33453
  exports.isCurrentUrlField = isCurrentUrlField;
33298
33454
  exports.isValidCssAttributeKey = isValidCssAttributeKey;
33299
33455
  exports.listLocalChromeProfiles = listLocalChromeProfiles;
33300
33456
  exports.normalizeExtractedValue = normalizeExtractedValue;
33301
33457
  exports.normalizeOpensteerEngineName = normalizeOpensteerEngineName;
33302
- exports.normalizeOpensteerExecutionMode = normalizeOpensteerExecutionMode;
33458
+ exports.normalizeOpensteerProviderKind = normalizeOpensteerProviderKind;
33303
33459
  exports.normalizeWorkspaceId = normalizeWorkspaceId;
33304
33460
  exports.readPersistedCloudSessionRecord = readPersistedCloudSessionRecord;
33305
33461
  exports.readPersistedLocalBrowserSessionRecord = readPersistedLocalBrowserSessionRecord;
33306
33462
  exports.readPersistedSessionRecord = readPersistedSessionRecord;
33307
33463
  exports.resolveCloudConfig = resolveCloudConfig;
33308
- exports.resolveCloudSessionRecordPath = resolveLiveSessionRecordPath;
33464
+ exports.resolveCloudSessionRecordPath = resolveCloudSessionRecordPath;
33309
33465
  exports.resolveDomActionBridge = resolveDomActionBridge;
33310
33466
  exports.resolveExtractedValueInContext = resolveExtractedValueInContext;
33311
33467
  exports.resolveFilesystemWorkspacePath = resolveFilesystemWorkspacePath;
33312
33468
  exports.resolveLiveSessionRecordPath = resolveLiveSessionRecordPath;
33469
+ exports.resolveLocalSessionRecordPath = resolveLocalSessionRecordPath;
33313
33470
  exports.resolveOpensteerEngineName = resolveOpensteerEngineName;
33314
- exports.resolveOpensteerExecutionMode = resolveOpensteerExecutionMode;
33471
+ exports.resolveOpensteerProvider = resolveOpensteerProvider;
33315
33472
  exports.resolveOpensteerRuntimeConfig = resolveOpensteerRuntimeConfig;
33316
33473
  exports.runWithPolicyTimeout = runWithPolicyTimeout;
33317
33474
  exports.sanitizeElementPath = sanitizeElementPath;