opensteer 0.9.7 → 0.9.8

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 (34) hide show
  1. package/README.md +2 -2
  2. package/dist/{chunk-R33BXCMQ.js → chunk-BPGXP3RF.js} +245 -21
  3. package/dist/chunk-BPGXP3RF.js.map +1 -0
  4. package/dist/{chunk-PJXN7HED.js → chunk-EXXRLPLI.js} +46 -35
  5. package/dist/chunk-EXXRLPLI.js.map +1 -0
  6. package/dist/{chunk-U4BUCIZ4.js → chunk-GKYBP3KD.js} +4 -4
  7. package/dist/chunk-GKYBP3KD.js.map +1 -0
  8. package/dist/{chunk-3OHKIPBD.js → chunk-LFWP5RXF.js} +189 -53
  9. package/dist/chunk-LFWP5RXF.js.map +1 -0
  10. package/dist/{chunk-52UNH5UW.js → chunk-SOJEWKSW.js} +5 -5
  11. package/dist/{chunk-52UNH5UW.js.map → chunk-SOJEWKSW.js.map} +1 -1
  12. package/dist/cli/bin.cjs +570 -119
  13. package/dist/cli/bin.cjs.map +1 -1
  14. package/dist/cli/bin.js +106 -28
  15. package/dist/cli/bin.js.map +1 -1
  16. package/dist/index.cjs +211 -72
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +10 -1
  19. package/dist/index.d.ts +10 -1
  20. package/dist/index.js +4 -4
  21. package/dist/local-view/serve-entry.cjs +288 -50
  22. package/dist/local-view/serve-entry.cjs.map +1 -1
  23. package/dist/local-view/serve-entry.js +2 -2
  24. package/dist/opensteer-XLPY343Y.js +6 -0
  25. package/dist/{opensteer-CY2QUJEG.js.map → opensteer-XLPY343Y.js.map} +1 -1
  26. package/dist/{session-control-FIP6ZJLH.js → session-control-FVKKD45R.js} +4 -4
  27. package/dist/{session-control-FIP6ZJLH.js.map → session-control-FVKKD45R.js.map} +1 -1
  28. package/package.json +7 -7
  29. package/skills/recorder/SKILL.md +2 -2
  30. package/dist/chunk-3OHKIPBD.js.map +0 -1
  31. package/dist/chunk-PJXN7HED.js.map +0 -1
  32. package/dist/chunk-R33BXCMQ.js.map +0 -1
  33. package/dist/chunk-U4BUCIZ4.js.map +0 -1
  34. package/dist/opensteer-CY2QUJEG.js +0 -6
@@ -1,5 +1,5 @@
1
- import { objectSchema, stringSchema, literalSchema, JSON_SCHEMA_DRAFT_2020_12, integerSchema, enumSchema, oneOfSchema, numberSchema, arraySchema, recordSchema, defineSchema, opensteerCapabilitySetSchema, opensteerErrorSchema, OpensteerProtocolError, resolveFilesystemWorkspacePath, createFilesystemOpensteerWorkspace, DEFAULT_OPENSTEER_ENGINE, createOpensteerError, assertSupportedEngineOptions, normalizeObservabilityConfig, manifestToExternalBinaryLocation, normalizeObservationContext, OpensteerBrowserManager, isOpensteerProtocolError, toOpensteerError } from './chunk-PJXN7HED.js';
2
- import { canonicalJsonString, toCanonicalJsonValue, readPersistedCloudSessionRecord, writePersistedSessionRecord, clearPersistedSessionRecord, resolveBrandUserDataDir, sha256Hex, getBrowserBrand, detectInstalledBrowserBrands, __require } from './chunk-U4BUCIZ4.js';
1
+ import { objectSchema, stringSchema, literalSchema, JSON_SCHEMA_DRAFT_2020_12, integerSchema, enumSchema, oneOfSchema, numberSchema, arraySchema, recordSchema, defineSchema, opensteerCapabilitySetSchema, opensteerErrorSchema, OpensteerProtocolError, resolveFilesystemWorkspacePath, createFilesystemOpensteerWorkspace, DEFAULT_OPENSTEER_ENGINE, createOpensteerError, assertSupportedEngineOptions, normalizeObservabilityConfig, manifestToExternalBinaryLocation, OpensteerBrowserManager, isOpensteerProtocolError, normalizeObservationContext, toOpensteerError } from './chunk-EXXRLPLI.js';
2
+ import { canonicalJsonString, toCanonicalJsonValue, readPersistedCloudSessionRecord, writePersistedSessionRecord, clearPersistedSessionRecord, resolveBrandUserDataDir, getBrowserBrand, detectInstalledBrowserBrands, __require, normalizeNonEmptyString, sha256Hex, readPersistedLocalBrowserSessionRecord } from './chunk-GKYBP3KD.js';
3
3
  import { selectAll } from 'css-select';
4
4
  import { createHash, randomUUID, pbkdf2Sync, createDecipheriv } from 'crypto';
5
5
  import { existsSync, readFileSync } from 'fs';
@@ -7,7 +7,7 @@ import path2, { join } from 'path';
7
7
  import { promisify } from 'util';
8
8
  import { gzip as gzip$1 } from 'zlib';
9
9
  import { execFile as execFile$1, spawn } from 'child_process';
10
- import { rm, mkdtemp, copyFile, writeFile, readFile } from 'fs/promises';
10
+ import { rm, mkdtemp, copyFile, readFile, writeFile } from 'fs/promises';
11
11
  import { tmpdir } from 'os';
12
12
  import { AsyncLocalStorage } from 'async_hooks';
13
13
  import sharp from 'sharp';
@@ -857,6 +857,9 @@ var pageInfoSchema = objectSchema(
857
857
  {
858
858
  pageRef: pageRefSchema,
859
859
  sessionRef: sessionRefSchema,
860
+ targetId: stringSchema({
861
+ description: "Underlying browser target identifier when available."
862
+ }),
860
863
  openerPageRef: pageRefSchema,
861
864
  url: stringSchema({
862
865
  description: "Current main-frame URL."
@@ -4953,7 +4956,9 @@ function resolveExtractedValueInContext(normalizedValue, options) {
4953
4956
  function stripPositionClauses(nodes) {
4954
4957
  return (nodes || []).map((node) => ({
4955
4958
  ...node,
4956
- match: (node.match || []).filter((clause) => clause.kind !== "position" && clause.kind !== "text")
4959
+ match: (node.match || []).filter(
4960
+ (clause) => clause.kind !== "position" && clause.kind !== "text"
4961
+ )
4957
4962
  }));
4958
4963
  }
4959
4964
  function dedupeSelectors(selectors) {
@@ -7223,7 +7228,9 @@ var DefaultDomRuntime = class {
7223
7228
  `Unable to resolve structural anchor "${buildPathSelectorHint(anchor)}" in the current session`
7224
7229
  );
7225
7230
  }
7226
- const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node, { enableTextMatch: true });
7231
+ const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node, {
7232
+ enableTextMatch: true
7233
+ });
7227
7234
  return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
7228
7235
  ...persist === void 0 ? {} : { persist },
7229
7236
  ...replayPath === void 0 ? {} : { replayPath }
@@ -9189,7 +9196,7 @@ function normalizeTemplateField(value) {
9189
9196
  "Extraction field descriptors must specify exactly one of c/element, selector, or source."
9190
9197
  );
9191
9198
  }
9192
- const attribute = raw.attr !== void 0 ? normalizeNonEmptyString("attr", raw.attr) : raw.attribute === void 0 ? void 0 : normalizeNonEmptyString("attribute", raw.attribute);
9199
+ const attribute = raw.attr !== void 0 ? normalizeNonEmptyString2("attr", raw.attr) : raw.attribute === void 0 ? void 0 : normalizeNonEmptyString2("attribute", raw.attribute);
9193
9200
  if (hasSource) {
9194
9201
  if (raw.source !== "current_url") {
9195
9202
  throw new Error(`Unsupported extraction source "${String(raw.source)}".`);
@@ -9200,7 +9207,7 @@ function normalizeTemplateField(value) {
9200
9207
  }
9201
9208
  if (hasSelector) {
9202
9209
  return {
9203
- selector: normalizeNonEmptyString("selector", raw.selector),
9210
+ selector: normalizeNonEmptyString2("selector", raw.selector),
9204
9211
  ...attribute === void 0 ? {} : { attribute }
9205
9212
  };
9206
9213
  }
@@ -9408,7 +9415,7 @@ var MemoryOpensteerExtractionDescriptorStore = class {
9408
9415
  return record;
9409
9416
  }
9410
9417
  };
9411
- function normalizeNonEmptyString(name, value) {
9418
+ function normalizeNonEmptyString2(name, value) {
9412
9419
  const normalized = String(value ?? "").trim();
9413
9420
  if (normalized.length === 0) {
9414
9421
  throw new Error(`${name} must not be empty`);
@@ -10219,11 +10226,11 @@ function delay(ms) {
10219
10226
  function wrapCloudFetchError(error, input) {
10220
10227
  if (!(error instanceof Error)) {
10221
10228
  return new Error(
10222
- `Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check OPENSTEER_BASE_URL and network reachability from this environment.`
10229
+ `Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check the configured Opensteer cloud base URL and network reachability from this environment.`
10223
10230
  );
10224
10231
  }
10225
10232
  const wrapped = new Error(
10226
- `Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check OPENSTEER_BASE_URL and network reachability from this environment.`,
10233
+ `Failed to reach Opensteer cloud endpoint ${input.method} ${input.url}. Check the configured Opensteer cloud base URL and network reachability from this environment.`,
10227
10234
  {
10228
10235
  cause: error
10229
10236
  }
@@ -10263,6 +10270,7 @@ function asCloudErrorPayload(value) {
10263
10270
  }
10264
10271
 
10265
10272
  // src/cloud/config.ts
10273
+ var DEFAULT_OPENSTEER_CLOUD_BASE_URL = "https://api.opensteer.com";
10266
10274
  function resolveCloudConfig(input = {}) {
10267
10275
  const provider = resolveOpensteerProvider({
10268
10276
  ...input.provider === void 0 ? {} : { provider: input.provider },
@@ -10272,30 +10280,34 @@ function resolveCloudConfig(input = {}) {
10272
10280
  return void 0;
10273
10281
  }
10274
10282
  const cloudProvider = input.provider?.mode === "cloud" ? input.provider : void 0;
10275
- const apiKey = cloudProvider?.apiKey ?? input.environment?.OPENSTEER_API_KEY;
10276
- if (!apiKey || apiKey.trim().length === 0) {
10283
+ const apiKey = normalizeOptionalCloudConfigValue(cloudProvider?.apiKey) ?? normalizeOptionalCloudConfigValue(input.environment?.OPENSTEER_API_KEY);
10284
+ if (apiKey === void 0) {
10277
10285
  throw new Error("provider=cloud requires OPENSTEER_API_KEY or provider.apiKey.");
10278
10286
  }
10279
- const baseUrl = cloudProvider?.baseUrl ?? input.environment?.OPENSTEER_BASE_URL;
10280
- if (!baseUrl || baseUrl.trim().length === 0) {
10281
- throw new Error("provider=cloud requires OPENSTEER_BASE_URL or provider.baseUrl.");
10282
- }
10283
- const appBaseUrl = cloudProvider?.appBaseUrl ?? input.environment?.OPENSTEER_CLOUD_APP_BASE_URL;
10287
+ const baseUrl = normalizeOptionalCloudConfigValue(cloudProvider?.baseUrl) ?? normalizeOptionalCloudConfigValue(input.environment?.OPENSTEER_BASE_URL) ?? DEFAULT_OPENSTEER_CLOUD_BASE_URL;
10288
+ const appBaseUrl = normalizeOptionalCloudConfigValue(cloudProvider?.appBaseUrl) ?? normalizeOptionalCloudConfigValue(input.environment?.OPENSTEER_CLOUD_APP_BASE_URL);
10284
10289
  return {
10285
- apiKey: apiKey.trim(),
10286
- baseUrl: baseUrl.trim().replace(/\/+$/, ""),
10287
- ...appBaseUrl === void 0 || appBaseUrl.trim().length === 0 ? {} : { appBaseUrl: appBaseUrl.trim().replace(/\/+$/, "") },
10290
+ apiKey,
10291
+ baseUrl,
10292
+ ...appBaseUrl === void 0 ? {} : { appBaseUrl },
10288
10293
  ...cloudProvider?.browserProfile === void 0 ? {} : { browserProfile: cloudProvider.browserProfile }
10289
10294
  };
10290
10295
  }
10291
10296
  function requireCloudAppBaseUrl(cloudConfig) {
10292
- const appBaseUrl = cloudConfig.appBaseUrl;
10293
- if (!appBaseUrl || appBaseUrl.trim().length === 0) {
10297
+ const appBaseUrl = normalizeOptionalCloudConfigValue(cloudConfig.appBaseUrl);
10298
+ if (appBaseUrl === void 0) {
10294
10299
  throw new Error(
10295
10300
  'record with provider=cloud requires OPENSTEER_CLOUD_APP_BASE_URL or "--cloud-app-base-url".'
10296
10301
  );
10297
10302
  }
10298
- return appBaseUrl.trim().replace(/\/+$/, "");
10303
+ return appBaseUrl;
10304
+ }
10305
+ function normalizeOptionalCloudConfigValue(value) {
10306
+ if (typeof value !== "string") {
10307
+ return void 0;
10308
+ }
10309
+ const normalized = value.trim().replace(/\/+$/, "");
10310
+ return normalized.length === 0 ? void 0 : normalized;
10299
10311
  }
10300
10312
 
10301
10313
  // ../runtime-core/src/sdk/semantic-dispatch.ts
@@ -10436,7 +10448,7 @@ async function dispatchSemanticOperation(runtime, operation, input, options = {}
10436
10448
 
10437
10449
  // ../runtime-core/package.json
10438
10450
  var package_default = {
10439
- version: "0.2.6"};
10451
+ version: "0.2.7"};
10440
10452
 
10441
10453
  // ../runtime-core/src/version.ts
10442
10454
  var OPENSTEER_RUNTIME_CORE_VERSION = package_default.version;
@@ -14507,7 +14519,10 @@ var OpensteerSessionRuntime = class {
14507
14519
  sessionRef;
14508
14520
  pageRef;
14509
14521
  runId;
14510
- observations;
14522
+ observationSessions = /* @__PURE__ */ new Map();
14523
+ openingObservationSessions = /* @__PURE__ */ new Map();
14524
+ openedObservationSessions = /* @__PURE__ */ new Set();
14525
+ observationSessionStorage = new AsyncLocalStorage();
14511
14526
  operationEventStorage = new AsyncLocalStorage();
14512
14527
  pendingOperationEventCaptures = [];
14513
14528
  ownsEngine = false;
@@ -14559,18 +14574,26 @@ var OpensteerSessionRuntime = class {
14559
14574
  }
14560
14575
  async setObservabilityConfig(input) {
14561
14576
  this.observationConfig = normalizeObservabilityConfig(input);
14562
- const observationSessionId = this.resolveObservationSessionId();
14563
- if (observationSessionId === void 0) {
14564
- return this.observationConfig;
14565
- }
14566
- const sink = this.injectedObservationSink ?? (await this.ensureRoot()).observations;
14567
- this.observations = await sink.openSession({
14568
- sessionId: observationSessionId,
14569
- openedAt: Date.now(),
14570
- config: this.observationConfig
14571
- });
14577
+ await this.ensureConfiguredObservationSession();
14572
14578
  return this.observationConfig;
14573
14579
  }
14580
+ async withObservationSessionId(sessionId, task) {
14581
+ return await this.observationSessionStorage.run(
14582
+ {
14583
+ mode: "session",
14584
+ sessionId: normalizeNonEmptyString("sessionId", sessionId)
14585
+ },
14586
+ task
14587
+ );
14588
+ }
14589
+ async withoutObservationSession(task) {
14590
+ return await this.observationSessionStorage.run(
14591
+ {
14592
+ mode: "disabled"
14593
+ },
14594
+ task
14595
+ );
14596
+ }
14574
14597
  async open(input = {}, options = {}) {
14575
14598
  assertValidSemanticOperationInput("session.open", input);
14576
14599
  if (input.workspace !== void 0 && normalizeNamespace2(input.workspace) !== this.workspace) {
@@ -18014,7 +18037,7 @@ var OpensteerSessionRuntime = class {
18014
18037
  }
18015
18038
  async resetRuntimeState(options) {
18016
18039
  const engine = this.engine;
18017
- const observations = this.observations;
18040
+ const observationSessions = [...this.openedObservationSessions];
18018
18041
  this.networkHistory.clear();
18019
18042
  this.sessionRef = void 0;
18020
18043
  this.pageRef = void 0;
@@ -18023,9 +18046,15 @@ var OpensteerSessionRuntime = class {
18023
18046
  this.computer = void 0;
18024
18047
  this.extractionDescriptors = void 0;
18025
18048
  this.engine = void 0;
18026
- this.observations = void 0;
18049
+ this.observationSessions.clear();
18050
+ this.openingObservationSessions.clear();
18051
+ this.openedObservationSessions.clear();
18027
18052
  this.pendingOperationEventCaptures.length = 0;
18028
- await observations?.close("runtime_reset").catch(() => void 0);
18053
+ await Promise.allSettled(
18054
+ observationSessions.map(
18055
+ (observationSession) => observationSession.close("runtime_reset").catch(() => void 0)
18056
+ )
18057
+ );
18029
18058
  if (options.disposeEngine && this.ownsEngine && engine?.dispose) {
18030
18059
  await engine.dispose();
18031
18060
  }
@@ -18035,23 +18064,64 @@ var OpensteerSessionRuntime = class {
18035
18064
  if (this.observationConfig.profile === "off") {
18036
18065
  return void 0;
18037
18066
  }
18038
- if (this.observations !== void 0) {
18039
- return this.observations;
18067
+ const observationSessionId = this.resolveObservationSessionId();
18068
+ if (observationSessionId === void 0) {
18069
+ return void 0;
18070
+ }
18071
+ const existingObservationSession = this.observationSessions.get(observationSessionId);
18072
+ if (existingObservationSession !== void 0) {
18073
+ return existingObservationSession;
18074
+ }
18075
+ const openingObservationSession = this.openingObservationSessions.get(observationSessionId);
18076
+ if (openingObservationSession !== void 0) {
18077
+ return await openingObservationSession;
18078
+ }
18079
+ const openObservationSessionTask = this.openObservationSession(observationSessionId).finally(
18080
+ () => {
18081
+ this.openingObservationSessions.delete(observationSessionId);
18082
+ }
18083
+ );
18084
+ this.openingObservationSessions.set(observationSessionId, openObservationSessionTask);
18085
+ return await openObservationSessionTask;
18086
+ }
18087
+ async ensureConfiguredObservationSession() {
18088
+ if (this.observationConfig.profile === "off") {
18089
+ return void 0;
18040
18090
  }
18041
18091
  const observationSessionId = this.resolveObservationSessionId();
18042
18092
  if (observationSessionId === void 0) {
18043
18093
  return void 0;
18044
18094
  }
18095
+ const hadObservationSession = this.observationSessions.has(observationSessionId) || this.openingObservationSessions.has(observationSessionId);
18096
+ const observationSession = await this.ensureObservationSession();
18097
+ if (observationSession !== void 0 && hadObservationSession) {
18098
+ await observationSession.configure?.({
18099
+ config: this.observationConfig,
18100
+ updatedAt: Date.now()
18101
+ });
18102
+ }
18103
+ return observationSession;
18104
+ }
18105
+ resolveObservationSessionId() {
18106
+ const scopedSession = this.observationSessionStorage.getStore();
18107
+ if (scopedSession?.mode === "session") {
18108
+ return scopedSession.sessionId;
18109
+ }
18110
+ if (scopedSession?.mode === "disabled") {
18111
+ return void 0;
18112
+ }
18113
+ return this.observationSessionId ?? this.sessionRef;
18114
+ }
18115
+ async openObservationSession(sessionId) {
18045
18116
  const sink = this.injectedObservationSink ?? (await this.ensureRoot()).observations;
18046
- this.observations = await sink.openSession({
18047
- sessionId: observationSessionId,
18117
+ const observationSession = await sink.openSession({
18118
+ sessionId,
18048
18119
  openedAt: Date.now(),
18049
18120
  config: this.observationConfig
18050
18121
  });
18051
- return this.observations;
18052
- }
18053
- resolveObservationSessionId() {
18054
- return this.observationSessionId ?? this.sessionRef;
18122
+ this.observationSessions.set(sessionId, observationSession);
18123
+ this.openedObservationSessions.add(observationSession);
18124
+ return observationSession;
18055
18125
  }
18056
18126
  runWithOperationTimeout(operation, callback, options = {}) {
18057
18127
  const timeoutPolicy = options.timeoutMs === void 0 ? this.policy.timeout : {
@@ -21315,26 +21385,35 @@ function renderOpensteerBootstrap(replayTarget) {
21315
21385
  `const opensteer = new Opensteer({`,
21316
21386
  ` provider: {`,
21317
21387
  ` mode: "cloud",`,
21318
- ` baseUrl: requireEnv(${JSON.stringify(replayTarget.baseUrlEnvVar ?? "OPENSTEER_BASE_URL")}),`,
21319
21388
  ` apiKey: requireEnv(${JSON.stringify(replayTarget.apiKeyEnvVar ?? "OPENSTEER_API_KEY")}),`,
21389
+ ...renderCloudBaseUrl(replayTarget),
21320
21390
  ...renderCloudBrowserProfile(replayTarget),
21321
21391
  ` },`,
21322
21392
  `});`
21323
21393
  ];
21324
21394
  }
21325
21395
  function renderRequireEnvHelper(replayTarget) {
21326
- const baseUrlEnvVar = replayTarget.baseUrlEnvVar ?? "OPENSTEER_BASE_URL";
21327
21396
  const apiKeyEnvVar = replayTarget.apiKeyEnvVar ?? "OPENSTEER_API_KEY";
21397
+ const requiredEnvVars = [
21398
+ ...replayTarget.baseUrlEnvVar === void 0 ? [] : [replayTarget.baseUrlEnvVar],
21399
+ apiKeyEnvVar
21400
+ ];
21328
21401
  return [
21329
21402
  `function requireEnv(name: string): string {`,
21330
21403
  ` const value = process.env[name];`,
21331
21404
  ` if (typeof value === "string" && value.trim().length > 0) {`,
21332
21405
  ` return value;`,
21333
21406
  ` }`,
21334
- ` throw new Error(\`Missing environment variable \${name}. Set ${baseUrlEnvVar} and ${apiKeyEnvVar} before replaying this recording.\`);`,
21407
+ ` throw new Error(\`Missing environment variable \${name}. Set ${requiredEnvVars.join(" and ")} before replaying this recording.\`);`,
21335
21408
  `}`
21336
21409
  ].join("\n");
21337
21410
  }
21411
+ function renderCloudBaseUrl(replayTarget) {
21412
+ if (replayTarget.baseUrlEnvVar === void 0) {
21413
+ return [];
21414
+ }
21415
+ return [` baseUrl: requireEnv(${JSON.stringify(replayTarget.baseUrlEnvVar)}),`];
21416
+ }
21338
21417
  function renderCloudBrowserProfile(replayTarget) {
21339
21418
  if (replayTarget.browserProfileId === void 0) {
21340
21419
  return [];
@@ -22495,7 +22574,29 @@ function isLoopbackBaseUrl(baseUrl) {
22495
22574
  }
22496
22575
  return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "::1" || url.hostname === "[::1]";
22497
22576
  }
22498
- var OpensteerRuntime = class extends OpensteerSessionRuntime {
22577
+ var LocalActivePageHintRuntime = class extends OpensteerSessionRuntime {
22578
+ async completeWithLocalActivePageHint(operation) {
22579
+ const output = await operation();
22580
+ await persistLocalActivePageHint(this, this.rootPath);
22581
+ return output;
22582
+ }
22583
+ async open(input = {}, options = {}) {
22584
+ return this.completeWithLocalActivePageHint(() => super.open(input, options));
22585
+ }
22586
+ async newPage(input = {}, options = {}) {
22587
+ return this.completeWithLocalActivePageHint(() => super.newPage(input, options));
22588
+ }
22589
+ async activatePage(input, options = {}) {
22590
+ return this.completeWithLocalActivePageHint(() => super.activatePage(input, options));
22591
+ }
22592
+ async closePage(input = {}, options = {}) {
22593
+ return this.completeWithLocalActivePageHint(() => super.closePage(input, options));
22594
+ }
22595
+ async goto(input, options = {}) {
22596
+ return this.completeWithLocalActivePageHint(() => super.goto(input, options));
22597
+ }
22598
+ };
22599
+ var OpensteerRuntime = class extends LocalActivePageHintRuntime {
22499
22600
  constructor(options = {}) {
22500
22601
  const publicWorkspace = normalizeWorkspace(options.workspace);
22501
22602
  const rootPath = options.rootPath ?? (publicWorkspace === void 0 ? path2.resolve(options.rootDir ?? process.cwd(), ".opensteer", "temporary", randomUUID()) : resolveFilesystemWorkspacePath({
@@ -22533,6 +22634,41 @@ var OpensteerRuntime = class extends OpensteerSessionRuntime {
22533
22634
  );
22534
22635
  }
22535
22636
  };
22637
+ async function persistLocalActivePageHint(runtime, rootPath) {
22638
+ try {
22639
+ await syncPersistedLocalActivePageHint(runtime, rootPath);
22640
+ } catch {
22641
+ }
22642
+ }
22643
+ async function syncPersistedLocalActivePageHint(runtime, rootPath) {
22644
+ const record = await readPersistedLocalBrowserSessionRecord(rootPath);
22645
+ if (!record) {
22646
+ return;
22647
+ }
22648
+ const sessionInfo = await runtime.info();
22649
+ const activePageRef = sessionInfo.activePageRef;
22650
+ let activePageUrl;
22651
+ let activePageTitle;
22652
+ if (activePageRef !== void 0) {
22653
+ const pages = await runtime.listPages();
22654
+ const activePage = pages.pages.find((page) => page.pageRef === activePageRef);
22655
+ activePageUrl = activePage?.url;
22656
+ activePageTitle = activePage?.title;
22657
+ }
22658
+ const {
22659
+ activePageRef: _previousActivePageRef,
22660
+ activePageUrl: _previousActivePageUrl,
22661
+ activePageTitle: _previousActivePageTitle,
22662
+ ...restRecord
22663
+ } = record;
22664
+ await writePersistedSessionRecord(rootPath, {
22665
+ ...restRecord,
22666
+ updatedAt: Date.now(),
22667
+ ...activePageRef === void 0 ? {} : { activePageRef },
22668
+ ...activePageUrl === void 0 ? {} : { activePageUrl },
22669
+ ...activePageTitle === void 0 ? {} : { activePageTitle }
22670
+ });
22671
+ }
22536
22672
  function buildSharedRuntimeOptions(input) {
22537
22673
  const ownership = resolveOwnership(input.browser);
22538
22674
  const engineFactory = input.engineFactory ?? ((factoryOptions) => new OpensteerBrowserManager({
@@ -22624,6 +22760,6 @@ function createOpensteerSemanticRuntime(input = {}) {
22624
22760
  });
22625
22761
  }
22626
22762
 
22627
- export { CloudSessionProxy, DEFERRED_MATCH_ATTR_KEYS, ElementPathError, FlowRecorderCollector, MATCH_ATTRIBUTE_PRIORITY, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL, OpensteerCloudClient, STABLE_PRIMARY_ATTR_KEYS, assertProviderSupportsEngine, buildArrayFieldPathCandidates, buildDomDescriptorKey, buildDomDescriptorPayload, buildDomDescriptorVersion, buildPathCandidates, buildPathSelectorHint, buildSegmentSelector, cloneElementPath, cloneReplayElementPath, cloneStructuralElementAnchor, createDomDescriptorStore, createDomRuntime, createOpensteerExtractionDescriptorStore, createOpensteerSemanticRuntime, defaultFallbackPolicy, defaultPolicy, defaultRetryPolicy, defaultSettlePolicy, defaultTimeoutPolicy, delayWithSignal, dispatchSemanticOperation, generateReplayScript, hashDomDescriptorPersist, isBrowserCoreError, isCurrentUrlField, isValidCssAttributeKey, loadEnvironment, normalizeExtractedValue, normalizeOpensteerProviderMode, parseDomDescriptorRecord, parseExtractionDescriptorRecord, requireCloudAppBaseUrl, resolveCloudConfig, resolveDomActionBridge, resolveExtractedValueInContext, resolveOpensteerEnvironment, resolveOpensteerProvider, resolveOpensteerRuntimeConfig, runWithPolicyTimeout, sanitizeElementPath, sanitizeReplayElementPath, sanitizeStructuralElementAnchor, settleWithPolicy, shouldKeepAttributeForPath };
22628
- //# sourceMappingURL=chunk-3OHKIPBD.js.map
22629
- //# sourceMappingURL=chunk-3OHKIPBD.js.map
22763
+ export { CloudSessionProxy, DEFAULT_OPENSTEER_CLOUD_BASE_URL, DEFERRED_MATCH_ATTR_KEYS, ElementPathError, FlowRecorderCollector, MATCH_ATTRIBUTE_PRIORITY, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL, OpensteerCloudClient, STABLE_PRIMARY_ATTR_KEYS, assertProviderSupportsEngine, buildArrayFieldPathCandidates, buildDomDescriptorKey, buildDomDescriptorPayload, buildDomDescriptorVersion, buildPathCandidates, buildPathSelectorHint, buildSegmentSelector, cloneElementPath, cloneReplayElementPath, cloneStructuralElementAnchor, createDomDescriptorStore, createDomRuntime, createOpensteerExtractionDescriptorStore, createOpensteerSemanticRuntime, defaultFallbackPolicy, defaultPolicy, defaultRetryPolicy, defaultSettlePolicy, defaultTimeoutPolicy, delayWithSignal, dispatchSemanticOperation, generateReplayScript, hashDomDescriptorPersist, isBrowserCoreError, isCurrentUrlField, isValidCssAttributeKey, loadEnvironment, normalizeExtractedValue, normalizeOpensteerProviderMode, parseDomDescriptorRecord, parseExtractionDescriptorRecord, requireCloudAppBaseUrl, resolveCloudConfig, resolveDomActionBridge, resolveExtractedValueInContext, resolveOpensteerEnvironment, resolveOpensteerProvider, resolveOpensteerRuntimeConfig, runWithPolicyTimeout, sanitizeElementPath, sanitizeReplayElementPath, sanitizeStructuralElementAnchor, settleWithPolicy, shouldKeepAttributeForPath };
22764
+ //# sourceMappingURL=chunk-LFWP5RXF.js.map
22765
+ //# sourceMappingURL=chunk-LFWP5RXF.js.map