opensteer 0.8.6 → 0.8.7

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.
@@ -1439,13 +1439,9 @@ var networkRecordSchema = objectSchema(
1439
1439
  ]
1440
1440
  }
1441
1441
  );
1442
- var networkQuerySourceSchema = enumSchema(["live", "saved"], {
1443
- title: "NetworkQuerySource"
1444
- });
1445
1442
  var networkQueryRecordSchema = objectSchema(
1446
1443
  {
1447
1444
  recordId: stringSchema({ minLength: 1 }),
1448
- source: networkQuerySourceSchema,
1449
1445
  actionId: stringSchema({ minLength: 1 }),
1450
1446
  tags: arraySchema(stringSchema({ minLength: 1 }), {
1451
1447
  uniqueItems: true
@@ -1455,7 +1451,7 @@ var networkQueryRecordSchema = objectSchema(
1455
1451
  },
1456
1452
  {
1457
1453
  title: "NetworkQueryRecord",
1458
- required: ["recordId", "source", "record"]
1454
+ required: ["recordId", "record"]
1459
1455
  }
1460
1456
  );
1461
1457
  arraySchema(headerEntrySchema, {
@@ -2151,9 +2147,6 @@ var opensteerRecipeRecordSchema = objectSchema(
2151
2147
  var opensteerAuthRecipeRecordSchema = opensteerRecipeRecordSchema;
2152
2148
  var opensteerNetworkQueryInputSchema = objectSchema(
2153
2149
  {
2154
- source: enumSchema(["live", "saved"], {
2155
- title: "OpensteerNetworkQuerySource"
2156
- }),
2157
2150
  pageRef: pageRefSchema,
2158
2151
  recordId: stringSchema({ minLength: 1 }),
2159
2152
  requestId: stringSchema({ minLength: 1 }),
@@ -2181,7 +2174,7 @@ var opensteerNetworkQueryOutputSchema = objectSchema(
2181
2174
  required: ["records"]
2182
2175
  }
2183
2176
  );
2184
- var opensteerNetworkSaveInputSchema = objectSchema(
2177
+ var opensteerNetworkTagInputSchema = objectSchema(
2185
2178
  {
2186
2179
  pageRef: pageRefSchema,
2187
2180
  recordId: stringSchema({ minLength: 1 }),
@@ -2196,17 +2189,17 @@ var opensteerNetworkSaveInputSchema = objectSchema(
2196
2189
  resourceType: networkResourceTypeSchema
2197
2190
  },
2198
2191
  {
2199
- title: "OpensteerNetworkSaveInput",
2192
+ title: "OpensteerNetworkTagInput",
2200
2193
  required: ["tag"]
2201
2194
  }
2202
2195
  );
2203
- var opensteerNetworkSaveOutputSchema = objectSchema(
2196
+ var opensteerNetworkTagOutputSchema = objectSchema(
2204
2197
  {
2205
- savedCount: integerSchema({ minimum: 0 })
2198
+ taggedCount: integerSchema({ minimum: 0 })
2206
2199
  },
2207
2200
  {
2208
- title: "OpensteerNetworkSaveOutput",
2209
- required: ["savedCount"]
2201
+ title: "OpensteerNetworkTagOutput",
2202
+ required: ["taggedCount"]
2210
2203
  }
2211
2204
  );
2212
2205
  var opensteerNetworkClearInputSchema = objectSchema(
@@ -5681,7 +5674,7 @@ var opensteerSemanticOperationNames = [
5681
5674
  "dom.scroll",
5682
5675
  "dom.extract",
5683
5676
  "network.query",
5684
- "network.save",
5677
+ "network.tag",
5685
5678
  "network.clear",
5686
5679
  "network.minimize",
5687
5680
  "network.diff",
@@ -5742,7 +5735,7 @@ var opensteerPackageRunnableSemanticOperationNames = /* @__PURE__ */ new Set([
5742
5735
  "dom.scroll",
5743
5736
  "dom.extract",
5744
5737
  "network.query",
5745
- "network.save",
5738
+ "network.tag",
5746
5739
  "network.clear",
5747
5740
  "network.minimize",
5748
5741
  "network.diff",
@@ -6652,18 +6645,17 @@ var opensteerSemanticOperationSpecificationsBase = [
6652
6645
  }),
6653
6646
  defineSemanticOperationSpec({
6654
6647
  name: "network.query",
6655
- description: "Query live or saved network records for reverse engineering workflows.",
6648
+ description: "Query persisted network records for reverse engineering workflows.",
6656
6649
  inputSchema: opensteerNetworkQueryInputSchema,
6657
6650
  outputSchema: opensteerNetworkQueryOutputSchema,
6658
- requiredCapabilities: [],
6659
- resolveRequiredCapabilities: (input) => input.source === "saved" ? [] : input.includeBodies === true ? ["inspect.network", "inspect.networkBodies"] : ["inspect.network"]
6651
+ requiredCapabilities: []
6660
6652
  }),
6661
6653
  defineSemanticOperationSpec({
6662
- name: "network.save",
6663
- description: "Persist filtered live network records into the saved network registry under a tag.",
6664
- inputSchema: opensteerNetworkSaveInputSchema,
6665
- outputSchema: opensteerNetworkSaveOutputSchema,
6666
- requiredCapabilities: ["inspect.network"]
6654
+ name: "network.tag",
6655
+ description: "Apply a tag to persisted network records matching the provided filters.",
6656
+ inputSchema: opensteerNetworkTagInputSchema,
6657
+ outputSchema: opensteerNetworkTagOutputSchema,
6658
+ requiredCapabilities: []
6667
6659
  }),
6668
6660
  defineSemanticOperationSpec({
6669
6661
  name: "network.clear",
@@ -7545,7 +7537,7 @@ var SqliteSavedNetworkStore = class {
7545
7537
  async initialize() {
7546
7538
  await this.ensureDatabaseDirectory();
7547
7539
  }
7548
- async save(records, tag) {
7540
+ async save(records, options) {
7549
7541
  const database = await this.requireDatabase();
7550
7542
  const readExisting = database.prepare(`
7551
7543
  SELECT record_id
@@ -7554,123 +7546,7 @@ var SqliteSavedNetworkStore = class {
7554
7546
  AND page_ref_key = @page_ref_key
7555
7547
  AND request_id = @request_id
7556
7548
  `);
7557
- const upsertRecord = database.prepare(`
7558
- INSERT INTO saved_network_records (
7559
- record_id,
7560
- request_id,
7561
- session_ref,
7562
- page_ref,
7563
- page_ref_key,
7564
- frame_ref,
7565
- document_ref,
7566
- action_id,
7567
- method,
7568
- method_lc,
7569
- url,
7570
- url_lc,
7571
- hostname,
7572
- hostname_lc,
7573
- path,
7574
- path_lc,
7575
- status,
7576
- status_text,
7577
- resource_type,
7578
- navigation_request,
7579
- request_headers_json,
7580
- response_headers_json,
7581
- request_body_json,
7582
- response_body_json,
7583
- initiator_json,
7584
- timing_json,
7585
- transfer_json,
7586
- source_json,
7587
- capture_state,
7588
- request_body_state,
7589
- response_body_state,
7590
- request_body_skip_reason,
7591
- response_body_skip_reason,
7592
- request_body_error,
7593
- response_body_error,
7594
- redirect_from_request_id,
7595
- redirect_to_request_id,
7596
- saved_at
7597
- ) VALUES (
7598
- @record_id,
7599
- @request_id,
7600
- @session_ref,
7601
- @page_ref,
7602
- @page_ref_key,
7603
- @frame_ref,
7604
- @document_ref,
7605
- @action_id,
7606
- @method,
7607
- @method_lc,
7608
- @url,
7609
- @url_lc,
7610
- @hostname,
7611
- @hostname_lc,
7612
- @path,
7613
- @path_lc,
7614
- @status,
7615
- @status_text,
7616
- @resource_type,
7617
- @navigation_request,
7618
- @request_headers_json,
7619
- @response_headers_json,
7620
- @request_body_json,
7621
- @response_body_json,
7622
- @initiator_json,
7623
- @timing_json,
7624
- @transfer_json,
7625
- @source_json,
7626
- @capture_state,
7627
- @request_body_state,
7628
- @response_body_state,
7629
- @request_body_skip_reason,
7630
- @response_body_skip_reason,
7631
- @request_body_error,
7632
- @response_body_error,
7633
- @redirect_from_request_id,
7634
- @redirect_to_request_id,
7635
- @saved_at
7636
- )
7637
- ON CONFLICT(record_id) DO UPDATE SET
7638
- page_ref = excluded.page_ref,
7639
- page_ref_key = excluded.page_ref_key,
7640
- frame_ref = excluded.frame_ref,
7641
- document_ref = excluded.document_ref,
7642
- action_id = excluded.action_id,
7643
- method = excluded.method,
7644
- method_lc = excluded.method_lc,
7645
- url = excluded.url,
7646
- url_lc = excluded.url_lc,
7647
- hostname = excluded.hostname,
7648
- hostname_lc = excluded.hostname_lc,
7649
- path = excluded.path,
7650
- path_lc = excluded.path_lc,
7651
- status = excluded.status,
7652
- status_text = excluded.status_text,
7653
- resource_type = excluded.resource_type,
7654
- navigation_request = excluded.navigation_request,
7655
- request_headers_json = excluded.request_headers_json,
7656
- response_headers_json = excluded.response_headers_json,
7657
- request_body_json = excluded.request_body_json,
7658
- response_body_json = excluded.response_body_json,
7659
- initiator_json = excluded.initiator_json,
7660
- timing_json = excluded.timing_json,
7661
- transfer_json = excluded.transfer_json,
7662
- source_json = excluded.source_json,
7663
- capture_state = excluded.capture_state,
7664
- request_body_state = excluded.request_body_state,
7665
- response_body_state = excluded.response_body_state,
7666
- request_body_skip_reason = excluded.request_body_skip_reason,
7667
- response_body_skip_reason = excluded.response_body_skip_reason,
7668
- request_body_error = excluded.request_body_error,
7669
- response_body_error = excluded.response_body_error,
7670
- redirect_from_request_id = excluded.redirect_from_request_id,
7671
- redirect_to_request_id = excluded.redirect_to_request_id,
7672
- saved_at = excluded.saved_at
7673
- `);
7549
+ const upsertRecord = database.prepare(buildSavedNetworkUpsertSql(options.bodyWriteMode));
7674
7550
  const insertTag = database.prepare(`
7675
7551
  INSERT OR IGNORE INTO saved_network_tags (record_id, tag)
7676
7552
  VALUES (@record_id, @tag)
@@ -7726,10 +7602,14 @@ var SqliteSavedNetworkStore = class {
7726
7602
  redirect_to_request_id: entry.record.redirectToRequestId ?? null,
7727
7603
  saved_at: entry.savedAt ?? Date.now()
7728
7604
  });
7729
- if (tag !== void 0) {
7605
+ const tags = new Set(entry.tags ?? []);
7606
+ if (options.tag !== void 0) {
7607
+ tags.add(options.tag);
7608
+ }
7609
+ for (const currentTag of tags) {
7730
7610
  const result = insertTag.run({
7731
7611
  record_id: recordId,
7732
- tag
7612
+ tag: currentTag
7733
7613
  });
7734
7614
  savedCount += result.changes ?? 0;
7735
7615
  }
@@ -7737,6 +7617,39 @@ var SqliteSavedNetworkStore = class {
7737
7617
  return savedCount;
7738
7618
  });
7739
7619
  }
7620
+ async tagByFilter(filter, tag) {
7621
+ const database = await this.requireDatabase();
7622
+ const { whereSql, parameters } = buildSavedNetworkWhere(filter);
7623
+ const selectRecords = database.prepare(
7624
+ `
7625
+ SELECT r.record_id
7626
+ FROM saved_network_records r
7627
+ ${whereSql}
7628
+ `
7629
+ );
7630
+ const insertTag = database.prepare(`
7631
+ INSERT OR IGNORE INTO saved_network_tags (record_id, tag)
7632
+ VALUES (@record_id, @tag)
7633
+ `);
7634
+ return withSqliteTransaction(database, () => {
7635
+ let taggedCount = 0;
7636
+ const rows = selectRecords.all(
7637
+ ...parameters
7638
+ );
7639
+ for (const row of rows) {
7640
+ const recordId = row.record_id;
7641
+ if (typeof recordId !== "string") {
7642
+ continue;
7643
+ }
7644
+ const result = insertTag.run({
7645
+ record_id: recordId,
7646
+ tag
7647
+ });
7648
+ taggedCount += result.changes ?? 0;
7649
+ }
7650
+ return taggedCount;
7651
+ });
7652
+ }
7740
7653
  async query(input = {}) {
7741
7654
  const database = await this.requireDatabase();
7742
7655
  const limit = Math.max(1, Math.min(input.limit ?? 50, 200));
@@ -7939,6 +7852,10 @@ var SqliteSavedNetworkStore = class {
7939
7852
  function buildSavedNetworkWhere(input) {
7940
7853
  const clauses = [];
7941
7854
  const parameters = [];
7855
+ if (input.pageRef !== void 0) {
7856
+ clauses.push("r.page_ref_key = ?");
7857
+ parameters.push(input.pageRef);
7858
+ }
7942
7859
  if (input.recordId !== void 0) {
7943
7860
  clauses.push("r.record_id = ?");
7944
7861
  parameters.push(input.recordId);
@@ -7991,6 +7908,127 @@ function buildSavedNetworkWhere(input) {
7991
7908
  parameters
7992
7909
  };
7993
7910
  }
7911
+ function buildSavedNetworkUpsertSql(bodyWriteMode) {
7912
+ const bodyUpdateSql = bodyWriteMode === "authoritative" ? `
7913
+ request_body_json = excluded.request_body_json,
7914
+ response_body_json = excluded.response_body_json,
7915
+ request_body_state = excluded.request_body_state,
7916
+ response_body_state = excluded.response_body_state,
7917
+ request_body_skip_reason = excluded.request_body_skip_reason,
7918
+ response_body_skip_reason = excluded.response_body_skip_reason,
7919
+ request_body_error = excluded.request_body_error,
7920
+ response_body_error = excluded.response_body_error,
7921
+ ` : "";
7922
+ return `
7923
+ INSERT INTO saved_network_records (
7924
+ record_id,
7925
+ request_id,
7926
+ session_ref,
7927
+ page_ref,
7928
+ page_ref_key,
7929
+ frame_ref,
7930
+ document_ref,
7931
+ action_id,
7932
+ method,
7933
+ method_lc,
7934
+ url,
7935
+ url_lc,
7936
+ hostname,
7937
+ hostname_lc,
7938
+ path,
7939
+ path_lc,
7940
+ status,
7941
+ status_text,
7942
+ resource_type,
7943
+ navigation_request,
7944
+ request_headers_json,
7945
+ response_headers_json,
7946
+ request_body_json,
7947
+ response_body_json,
7948
+ initiator_json,
7949
+ timing_json,
7950
+ transfer_json,
7951
+ source_json,
7952
+ capture_state,
7953
+ request_body_state,
7954
+ response_body_state,
7955
+ request_body_skip_reason,
7956
+ response_body_skip_reason,
7957
+ request_body_error,
7958
+ response_body_error,
7959
+ redirect_from_request_id,
7960
+ redirect_to_request_id,
7961
+ saved_at
7962
+ ) VALUES (
7963
+ @record_id,
7964
+ @request_id,
7965
+ @session_ref,
7966
+ @page_ref,
7967
+ @page_ref_key,
7968
+ @frame_ref,
7969
+ @document_ref,
7970
+ @action_id,
7971
+ @method,
7972
+ @method_lc,
7973
+ @url,
7974
+ @url_lc,
7975
+ @hostname,
7976
+ @hostname_lc,
7977
+ @path,
7978
+ @path_lc,
7979
+ @status,
7980
+ @status_text,
7981
+ @resource_type,
7982
+ @navigation_request,
7983
+ @request_headers_json,
7984
+ @response_headers_json,
7985
+ @request_body_json,
7986
+ @response_body_json,
7987
+ @initiator_json,
7988
+ @timing_json,
7989
+ @transfer_json,
7990
+ @source_json,
7991
+ @capture_state,
7992
+ @request_body_state,
7993
+ @response_body_state,
7994
+ @request_body_skip_reason,
7995
+ @response_body_skip_reason,
7996
+ @request_body_error,
7997
+ @response_body_error,
7998
+ @redirect_from_request_id,
7999
+ @redirect_to_request_id,
8000
+ @saved_at
8001
+ )
8002
+ ON CONFLICT(record_id) DO UPDATE SET
8003
+ page_ref = excluded.page_ref,
8004
+ page_ref_key = excluded.page_ref_key,
8005
+ frame_ref = excluded.frame_ref,
8006
+ document_ref = excluded.document_ref,
8007
+ action_id = excluded.action_id,
8008
+ method = excluded.method,
8009
+ method_lc = excluded.method_lc,
8010
+ url = excluded.url,
8011
+ url_lc = excluded.url_lc,
8012
+ hostname = excluded.hostname,
8013
+ hostname_lc = excluded.hostname_lc,
8014
+ path = excluded.path,
8015
+ path_lc = excluded.path_lc,
8016
+ status = excluded.status,
8017
+ status_text = excluded.status_text,
8018
+ resource_type = excluded.resource_type,
8019
+ navigation_request = excluded.navigation_request,
8020
+ request_headers_json = excluded.request_headers_json,
8021
+ response_headers_json = excluded.response_headers_json,
8022
+ ${bodyUpdateSql} initiator_json = excluded.initiator_json,
8023
+ timing_json = excluded.timing_json,
8024
+ transfer_json = excluded.transfer_json,
8025
+ source_json = excluded.source_json,
8026
+ capture_state = excluded.capture_state,
8027
+ redirect_from_request_id = excluded.redirect_from_request_id,
8028
+ redirect_to_request_id = excluded.redirect_to_request_id,
8029
+ saved_at = MIN(saved_network_records.saved_at, excluded.saved_at)
8030
+ `;
8031
+ }
7994
8032
  function inflateSavedNetworkRow(row, includeBodies) {
7995
8033
  const requestBody = includeBodies && row.request_body_json !== null ? JSON.parse(row.request_body_json) : void 0;
7996
8034
  const responseBody = includeBodies && row.response_body_json !== null ? JSON.parse(row.response_body_json) : void 0;
@@ -8061,7 +8099,6 @@ function inflateSavedNetworkRow(row, includeBodies) {
8061
8099
  }
8062
8100
  return {
8063
8101
  recordId: row.record_id,
8064
- source: "saved",
8065
8102
  ...row.action_id === null ? {} : { actionId: row.action_id },
8066
8103
  ...row.tags === null || row.tags.length === 0 ? {} : { tags: row.tags.split(TAG_DELIMITER).filter((tag) => tag.length > 0) },
8067
8104
  savedAt: row.saved_at,
@@ -8408,7 +8445,7 @@ var DEFAULT_TIMEOUTS = {
8408
8445
  "dom.scroll": 1e4,
8409
8446
  "dom.extract": 15e3,
8410
8447
  "network.query": 15e3,
8411
- "network.save": 15e3,
8448
+ "network.tag": 15e3,
8412
8449
  "network.clear": 1e4,
8413
8450
  "scripts.capture": 15e3,
8414
8451
  "request.raw": 3e4,
@@ -10198,6 +10235,19 @@ var MemoryDomDescriptorStore = class {
10198
10235
  }
10199
10236
  };
10200
10237
 
10238
+ // ../runtime-core/src/action-boundary.ts
10239
+ async function captureActionBoundarySnapshot(engine, pageRef) {
10240
+ const frames = await engine.listFrames({ pageRef });
10241
+ const mainFrame = frames.find((frame) => frame.isMainFrame);
10242
+ if (!mainFrame) {
10243
+ throw new Error(`page ${pageRef} does not expose a main frame`);
10244
+ }
10245
+ return {
10246
+ pageRef,
10247
+ documentRef: mainFrame.documentRef
10248
+ };
10249
+ }
10250
+
10201
10251
  // ../runtime-core/src/runtimes/dom/executor.ts
10202
10252
  var MAX_DOM_ACTION_ATTEMPTS = 3;
10203
10253
  var DEFAULT_SCROLL_OPTIONS = {
@@ -10327,6 +10377,7 @@ var DomActionExecutor = class {
10327
10377
  })
10328
10378
  );
10329
10379
  let finalResolved = resolved;
10380
+ let finalSnapshot;
10330
10381
  if (input.pressEnter) {
10331
10382
  await this.settle(resolved.pageRef, "dom.input", timeout);
10332
10383
  const enterSession = this.options.createResolutionSession();
@@ -10342,6 +10393,9 @@ var DomActionExecutor = class {
10342
10393
  () => bridge.inspectActionTarget(enterResolved.locator)
10343
10394
  );
10344
10395
  this.assertKeyboardActionable("dom.input", enterResolved, inspectionBeforeEnter);
10396
+ finalSnapshot = await timeout.runStep(
10397
+ () => captureActionBoundarySnapshot(this.options.engine, enterResolved.pageRef)
10398
+ );
10345
10399
  await timeout.runStep(
10346
10400
  () => bridge.pressKey(enterResolved.locator, {
10347
10401
  key: "Enter"
@@ -10349,7 +10403,7 @@ var DomActionExecutor = class {
10349
10403
  );
10350
10404
  finalResolved = enterResolved;
10351
10405
  }
10352
- await this.settle(finalResolved.pageRef, "dom.input", timeout);
10406
+ await this.settle(finalResolved.pageRef, "dom.input", timeout, finalSnapshot);
10353
10407
  return finalResolved;
10354
10408
  } catch (error) {
10355
10409
  lastError = error;
@@ -10422,8 +10476,16 @@ var DomActionExecutor = class {
10422
10476
  );
10423
10477
  }
10424
10478
  }
10479
+ const actionBoundarySnapshot = await timeout.runStep(
10480
+ () => captureActionBoundarySnapshot(this.options.engine, pointerTarget.resolved.pageRef)
10481
+ );
10425
10482
  const outcome = await dispatch(pointerTarget, point, timeout);
10426
- await this.settle(pointerTarget.resolved.pageRef, input.operation, timeout);
10483
+ await this.settle(
10484
+ pointerTarget.resolved.pageRef,
10485
+ input.operation,
10486
+ timeout,
10487
+ actionBoundarySnapshot
10488
+ );
10427
10489
  return outcome;
10428
10490
  } catch (error) {
10429
10491
  lastError = error;
@@ -10441,16 +10503,17 @@ var DomActionExecutor = class {
10441
10503
  }
10442
10504
  return runWithPolicyTimeout(this.options.policy.timeout, { operation }, execute);
10443
10505
  }
10444
- async settle(pageRef, operation, timeout) {
10506
+ async settle(pageRef, operation, timeout, snapshot) {
10445
10507
  const bridge = this.requireBridge();
10446
10508
  await timeout.runStep(
10447
10509
  () => bridge.finalizeDomAction(pageRef, {
10448
10510
  operation,
10511
+ ...snapshot === void 0 ? {} : { snapshot },
10449
10512
  signal: timeout.signal,
10450
10513
  remainingMs: () => timeout.remainingMs(),
10451
- policySettle: (targetPageRef) => settleWithPolicy(this.options.policy.settle, {
10514
+ policySettle: (targetPageRef, trigger) => settleWithPolicy(this.options.policy.settle, {
10452
10515
  operation,
10453
- trigger: "dom-action",
10516
+ trigger,
10454
10517
  engine: this.options.engine,
10455
10518
  pageRef: targetPageRef,
10456
10519
  signal: timeout.signal,
@@ -15772,8 +15835,8 @@ async function dispatchSemanticOperation(runtime, operation, input, options = {}
15772
15835
  input,
15773
15836
  options
15774
15837
  );
15775
- case "network.save":
15776
- return runtime.saveNetwork(
15838
+ case "network.tag":
15839
+ return runtime.tagNetwork(
15777
15840
  input,
15778
15841
  options
15779
15842
  );
@@ -16279,16 +16342,20 @@ var DefaultComputerUseRuntime = class {
16279
16342
  const preActionDisplay = createComputerDisplayTransform(preActionNativeViewport);
16280
16343
  const nativeAction = toNativeComputerAction(input.input.action, preActionDisplay);
16281
16344
  const screenshot = normalizeScreenshotOptions(input.input.screenshot);
16345
+ const snapshot = await input.timeout.runStep(
16346
+ () => captureActionBoundarySnapshot(this.options.engine, input.pageRef)
16347
+ );
16282
16348
  const executed = await input.timeout.runStep(
16283
16349
  () => bridge.execute({
16284
16350
  pageRef: input.pageRef,
16351
+ snapshot,
16285
16352
  action: nativeAction,
16286
16353
  screenshot,
16287
16354
  signal: input.timeout.signal,
16288
16355
  remainingMs: () => input.timeout.remainingMs(),
16289
- policySettle: async (pageRef) => settleWithPolicy(this.options.policy.settle, {
16356
+ policySettle: async (pageRef, trigger) => settleWithPolicy(this.options.policy.settle, {
16290
16357
  operation: "computer.execute",
16291
- trigger: "dom-action",
16358
+ trigger,
16292
16359
  engine: this.options.engine,
16293
16360
  pageRef,
16294
16361
  signal: input.timeout.signal,
@@ -17022,9 +17089,9 @@ function inferRequestPlanFromNetworkRecord(record, input, options = {}) {
17022
17089
  key: input.key,
17023
17090
  version: input.version,
17024
17091
  provenance: {
17025
- source: record.source === "saved" ? "saved-network-record" : "live-network-record",
17092
+ source: record.savedAt === void 0 ? "network-record" : "saved-network-record",
17026
17093
  sourceId: record.recordId,
17027
- ...record.source === "saved" ? record.savedAt === void 0 ? {} : { capturedAt: record.savedAt } : options.observedAt === void 0 ? {} : { capturedAt: options.observedAt }
17094
+ ...record.savedAt === void 0 ? options.observedAt === void 0 ? {} : { capturedAt: options.observedAt } : { capturedAt: record.savedAt }
17028
17095
  },
17029
17096
  payload,
17030
17097
  ...record.tags === void 0 || record.tags.length === 0 ? {} : { tags: record.tags }
@@ -17404,51 +17471,55 @@ function resolveBodyEncoding(charset) {
17404
17471
  return "utf8";
17405
17472
  }
17406
17473
  }
17407
- var NetworkJournal = class {
17474
+ var NetworkHistory = class {
17408
17475
  metadataByRequestId = /* @__PURE__ */ new Map();
17409
17476
  requestIdByRecordId = /* @__PURE__ */ new Map();
17410
17477
  requestIdsByActionId = /* @__PURE__ */ new Map();
17411
17478
  requestIdsByTag = /* @__PURE__ */ new Map();
17412
- sync(records, options = {}) {
17479
+ tombstonedRequestIds = /* @__PURE__ */ new Set();
17480
+ materialize(records, options = {}) {
17413
17481
  const observedAt = Date.now();
17414
- return records.map((record) => this.materializeLiveRecord(record, observedAt, options));
17415
- }
17416
- materializeLiveRecord(record, observedAt, options = {}) {
17417
- let metadata = this.metadataByRequestId.get(record.requestId);
17418
- if (!metadata) {
17419
- metadata = {
17420
- recordId: `record:${randomUUID()}`,
17421
- observedAt,
17422
- ...record.pageRef === void 0 ? {} : { pageRef: record.pageRef },
17423
- tags: /* @__PURE__ */ new Set()
17424
- };
17425
- this.metadataByRequestId.set(record.requestId, metadata);
17426
- this.requestIdByRecordId.set(metadata.recordId, record.requestId);
17427
- } else if (metadata.pageRef === void 0 && record.pageRef !== void 0) {
17428
- metadata.pageRef = record.pageRef;
17482
+ const materialized = [];
17483
+ for (const record of records) {
17484
+ const entry = this.materializeRecord(record, observedAt, options);
17485
+ if (entry !== void 0) {
17486
+ materialized.push(entry);
17487
+ }
17429
17488
  }
17430
- return {
17431
- recordId: metadata.recordId,
17432
- source: "live",
17433
- ...metadata.actionId === void 0 ? {} : { actionId: metadata.actionId },
17434
- ...metadata.tags.size === 0 ? {} : { tags: [...metadata.tags].sort() },
17435
- record: toProtocolNetworkRecord(record, {
17436
- redactSecretHeaders: options.redactSecretHeaders ?? true
17437
- })
17438
- };
17489
+ return materialized;
17439
17490
  }
17440
- diffNewRequestIds(records, baselineRequestIds) {
17441
- const observedAt = Date.now();
17442
- const all = records.map(
17443
- (record) => this.materializeLiveRecord(record, observedAt, {
17444
- redactSecretHeaders: true
17445
- })
17446
- );
17447
- const delta = all.filter((entry) => !baselineRequestIds.has(entry.record.requestId));
17448
- return {
17449
- all,
17450
- delta
17451
- };
17491
+ async persist(records, store, options) {
17492
+ const observedAt = options.observedAt ?? Date.now();
17493
+ const metadataToSave = /* @__PURE__ */ new Set();
17494
+ const persisted = [];
17495
+ for (const record of records) {
17496
+ const entry = this.materializeRecord(record, observedAt, {
17497
+ ...options.redactSecretHeaders === void 0 ? {} : { redactSecretHeaders: options.redactSecretHeaders }
17498
+ });
17499
+ if (entry === void 0) {
17500
+ continue;
17501
+ }
17502
+ const requestId = entry.record.requestId;
17503
+ const metadata = this.metadataByRequestId.get(requestId);
17504
+ if (metadata === void 0) {
17505
+ continue;
17506
+ }
17507
+ const savedAt = metadata.savedAt ?? observedAt;
17508
+ metadataToSave.add(metadata);
17509
+ persisted.push({
17510
+ ...entry,
17511
+ savedAt
17512
+ });
17513
+ }
17514
+ if (persisted.length > 0) {
17515
+ await store.save(persisted, {
17516
+ bodyWriteMode: options.bodyWriteMode
17517
+ });
17518
+ for (const metadata of metadataToSave) {
17519
+ metadata.savedAt ??= observedAt;
17520
+ }
17521
+ }
17522
+ return persisted;
17452
17523
  }
17453
17524
  assignActionId(records, actionId) {
17454
17525
  for (const record of records) {
@@ -17489,11 +17560,73 @@ var NetworkJournal = class {
17489
17560
  getPageRefForRequestId(requestId) {
17490
17561
  return this.metadataByRequestId.get(requestId)?.pageRef;
17491
17562
  }
17563
+ getKnownRequestIds() {
17564
+ return new Set(this.metadataByRequestId.keys());
17565
+ }
17566
+ clearTag(tag) {
17567
+ const requestIds = [...this.requestIdsByTag.get(tag) ?? []];
17568
+ this.requestIdsByTag.delete(tag);
17569
+ for (const requestId of requestIds) {
17570
+ const metadata = this.metadataByRequestId.get(requestId);
17571
+ if (!metadata) {
17572
+ continue;
17573
+ }
17574
+ metadata.tags.delete(tag);
17575
+ if (metadata.tags.size === 0) {
17576
+ this.tombstoneRequestIds([requestId]);
17577
+ }
17578
+ }
17579
+ }
17580
+ tombstoneRequestIds(requestIds) {
17581
+ for (const requestId of requestIds) {
17582
+ this.tombstonedRequestIds.add(requestId);
17583
+ const metadata = this.metadataByRequestId.get(requestId);
17584
+ if (!metadata) {
17585
+ continue;
17586
+ }
17587
+ this.metadataByRequestId.delete(requestId);
17588
+ this.requestIdByRecordId.delete(metadata.recordId);
17589
+ if (metadata.actionId !== void 0) {
17590
+ this.requestIdsByActionId.get(metadata.actionId)?.delete(requestId);
17591
+ }
17592
+ for (const tag of metadata.tags) {
17593
+ this.requestIdsByTag.get(tag)?.delete(requestId);
17594
+ }
17595
+ }
17596
+ }
17492
17597
  clear() {
17493
17598
  this.metadataByRequestId.clear();
17494
17599
  this.requestIdByRecordId.clear();
17495
17600
  this.requestIdsByActionId.clear();
17496
17601
  this.requestIdsByTag.clear();
17602
+ this.tombstonedRequestIds.clear();
17603
+ }
17604
+ materializeRecord(record, observedAt, options) {
17605
+ if (this.tombstonedRequestIds.has(record.requestId)) {
17606
+ return void 0;
17607
+ }
17608
+ let metadata = this.metadataByRequestId.get(record.requestId);
17609
+ if (!metadata) {
17610
+ metadata = {
17611
+ recordId: `record:${randomUUID()}`,
17612
+ observedAt,
17613
+ ...record.pageRef === void 0 ? {} : { pageRef: record.pageRef },
17614
+ tags: /* @__PURE__ */ new Set()
17615
+ };
17616
+ this.metadataByRequestId.set(record.requestId, metadata);
17617
+ this.requestIdByRecordId.set(metadata.recordId, record.requestId);
17618
+ } else if (metadata.pageRef === void 0 && record.pageRef !== void 0) {
17619
+ metadata.pageRef = record.pageRef;
17620
+ }
17621
+ return {
17622
+ recordId: metadata.recordId,
17623
+ ...metadata.actionId === void 0 ? {} : { actionId: metadata.actionId },
17624
+ ...metadata.tags.size === 0 ? {} : { tags: [...metadata.tags].sort() },
17625
+ ...metadata.savedAt === void 0 ? {} : { savedAt: metadata.savedAt },
17626
+ record: toProtocolNetworkRecord(record, {
17627
+ redactSecretHeaders: options.redactSecretHeaders ?? true
17628
+ })
17629
+ };
17497
17630
  }
17498
17631
  addIndexedRequestId(index, key, requestId) {
17499
17632
  const requestIds = index.get(key) ?? /* @__PURE__ */ new Set();
@@ -22321,12 +22454,11 @@ var OpensteerSessionRuntime = class {
22321
22454
  engine;
22322
22455
  dom;
22323
22456
  computer;
22324
- networkJournal = new NetworkJournal();
22457
+ networkHistory = new NetworkHistory();
22325
22458
  extractionDescriptors;
22326
22459
  sessionRef;
22327
22460
  pageRef;
22328
22461
  runId;
22329
- backgroundNetworkPersistence = /* @__PURE__ */ new Set();
22330
22462
  cookieJars = /* @__PURE__ */ new Map();
22331
22463
  recipeCache = /* @__PURE__ */ new Map();
22332
22464
  ownsEngine = false;
@@ -22756,19 +22888,28 @@ var OpensteerSessionRuntime = class {
22756
22888
  const output = await this.runWithOperationTimeout(
22757
22889
  "page.evaluate",
22758
22890
  async (timeout) => {
22759
- const remainingMs = timeout.remainingMs();
22760
- const evaluated = await timeout.runStep(
22761
- () => this.requireEngine().evaluatePage({
22891
+ const baselineRequestIds = await this.beginMutationCapture(timeout);
22892
+ try {
22893
+ const remainingMs = timeout.remainingMs();
22894
+ const evaluated = await timeout.runStep(
22895
+ () => this.requireEngine().evaluatePage({
22896
+ pageRef,
22897
+ script: input.script,
22898
+ ...input.args === void 0 ? {} : { args: input.args },
22899
+ ...remainingMs === void 0 ? {} : { timeoutMs: remainingMs }
22900
+ })
22901
+ );
22902
+ await this.completeMutationCapture(timeout, baselineRequestIds, void 0);
22903
+ return {
22762
22904
  pageRef,
22763
- script: input.script,
22764
- ...input.args === void 0 ? {} : { args: input.args },
22765
- ...remainingMs === void 0 ? {} : { timeoutMs: remainingMs }
22766
- })
22767
- );
22768
- return {
22769
- pageRef,
22770
- value: toJsonValueOrNull(evaluated.data)
22771
- };
22905
+ value: toJsonValueOrNull(evaluated.data)
22906
+ };
22907
+ } catch (error) {
22908
+ await this.completeMutationCapture(timeout, baselineRequestIds, void 0).catch(
22909
+ () => void 0
22910
+ );
22911
+ throw error;
22912
+ }
22772
22913
  },
22773
22914
  options
22774
22915
  );
@@ -23132,38 +23273,19 @@ var OpensteerSessionRuntime = class {
23132
23273
  }
23133
23274
  async queryNetwork(input = {}, options = {}) {
23134
23275
  assertValidSemanticOperationInput("network.query", input);
23135
- if (input.source !== "saved") {
23136
- await this.ensurePageRef();
23137
- }
23138
23276
  const root = await this.ensureRoot();
23139
23277
  const startedAt = Date.now();
23140
23278
  try {
23141
23279
  const output = await this.runWithOperationTimeout(
23142
23280
  "network.query",
23143
23281
  async (timeout) => {
23144
- if (input.source === "saved") {
23145
- await timeout.runStep(() => this.flushBackgroundNetworkPersistence());
23146
- return {
23147
- records: await timeout.runStep(
23148
- () => root.registry.savedNetwork.query({
23149
- ...input.recordId === void 0 ? {} : { recordId: input.recordId },
23150
- ...input.requestId === void 0 ? {} : { requestId: input.requestId },
23151
- ...input.actionId === void 0 ? {} : { actionId: input.actionId },
23152
- ...input.tag === void 0 ? {} : { tag: input.tag },
23153
- ...input.url === void 0 ? {} : { url: input.url },
23154
- ...input.hostname === void 0 ? {} : { hostname: input.hostname },
23155
- ...input.path === void 0 ? {} : { path: input.path },
23156
- ...input.method === void 0 ? {} : { method: input.method },
23157
- ...input.status === void 0 ? {} : { status: input.status },
23158
- ...input.resourceType === void 0 ? {} : { resourceType: input.resourceType },
23159
- ...input.includeBodies === void 0 ? {} : { includeBodies: input.includeBodies },
23160
- ...input.limit === void 0 ? {} : { limit: input.limit }
23161
- })
23162
- )
23163
- };
23164
- }
23282
+ await this.syncPersistedNetworkSelection(timeout, input, {
23283
+ includeBodies: input.includeBodies ?? false
23284
+ });
23165
23285
  return {
23166
- records: await this.queryLiveNetwork(input, timeout)
23286
+ records: await timeout.runStep(
23287
+ () => root.registry.savedNetwork.query(this.toSavedNetworkQueryInput(input))
23288
+ )
23167
23289
  };
23168
23290
  },
23169
23291
  options
@@ -23174,7 +23296,6 @@ var OpensteerSessionRuntime = class {
23174
23296
  completedAt: Date.now(),
23175
23297
  outcome: "ok",
23176
23298
  data: {
23177
- source: input.source ?? "live",
23178
23299
  includeBodies: input.includeBodies ?? false,
23179
23300
  limit: input.limit ?? 50,
23180
23301
  count: output.records.length
@@ -23200,56 +23321,42 @@ var OpensteerSessionRuntime = class {
23200
23321
  throw error;
23201
23322
  }
23202
23323
  }
23203
- async saveNetwork(input, options = {}) {
23204
- assertValidSemanticOperationInput("network.save", input);
23205
- await this.ensurePageRef();
23324
+ async tagNetwork(input, options = {}) {
23325
+ assertValidSemanticOperationInput("network.tag", input);
23206
23326
  const root = await this.ensureRoot();
23327
+ const filter = this.toQueryInputFromTagInput(input);
23328
+ const savedFilter = this.toSavedNetworkQueryInput(filter);
23207
23329
  const startedAt = Date.now();
23208
23330
  try {
23209
23331
  const output = await this.runWithOperationTimeout(
23210
- "network.save",
23332
+ "network.tag",
23211
23333
  async (timeout) => {
23212
- const records = await this.queryLiveNetwork(
23213
- {
23214
- includeBodies: true,
23215
- source: "live",
23216
- ...input.pageRef === void 0 ? {} : { pageRef: input.pageRef },
23217
- ...input.recordId === void 0 ? {} : { recordId: input.recordId },
23218
- ...input.requestId === void 0 ? {} : { requestId: input.requestId },
23219
- ...input.actionId === void 0 ? {} : { actionId: input.actionId },
23220
- ...input.url === void 0 ? {} : { url: input.url },
23221
- ...input.hostname === void 0 ? {} : { hostname: input.hostname },
23222
- ...input.path === void 0 ? {} : { path: input.path },
23223
- ...input.method === void 0 ? {} : { method: input.method },
23224
- ...input.status === void 0 ? {} : { status: input.status },
23225
- ...input.resourceType === void 0 ? {} : { resourceType: input.resourceType }
23226
- },
23227
- timeout,
23228
- { ignoreLimit: true, redactSecretHeaders: false }
23229
- );
23230
- this.networkJournal.addTag(records, input.tag);
23334
+ const records = await this.syncPersistedNetworkSelection(timeout, filter, {
23335
+ includeBodies: false
23336
+ });
23337
+ this.networkHistory.addTag(records, input.tag);
23231
23338
  return {
23232
- savedCount: await timeout.runStep(
23233
- () => root.registry.savedNetwork.save(records, input.tag)
23339
+ taggedCount: await timeout.runStep(
23340
+ () => root.registry.savedNetwork.tagByFilter(savedFilter, input.tag)
23234
23341
  )
23235
23342
  };
23236
23343
  },
23237
23344
  options
23238
23345
  );
23239
23346
  await this.appendTrace({
23240
- operation: "network.save",
23347
+ operation: "network.tag",
23241
23348
  startedAt,
23242
23349
  completedAt: Date.now(),
23243
23350
  outcome: "ok",
23244
23351
  data: {
23245
23352
  tag: input.tag,
23246
- savedCount: output.savedCount
23353
+ taggedCount: output.taggedCount
23247
23354
  }
23248
23355
  });
23249
23356
  return output;
23250
23357
  } catch (error) {
23251
23358
  await this.appendTrace({
23252
- operation: "network.save",
23359
+ operation: "network.tag",
23253
23360
  startedAt,
23254
23361
  completedAt: Date.now(),
23255
23362
  outcome: "error",
@@ -23266,7 +23373,19 @@ var OpensteerSessionRuntime = class {
23266
23373
  const output = await this.runWithOperationTimeout(
23267
23374
  "network.clear",
23268
23375
  async (timeout) => {
23269
- await timeout.runStep(() => this.flushBackgroundNetworkPersistence());
23376
+ if (this.sessionRef !== void 0) {
23377
+ const liveRequestIds = await this.readLiveRequestIds(timeout, {
23378
+ includeCurrentPageOnly: false
23379
+ });
23380
+ if (input.tag === void 0) {
23381
+ this.networkHistory.tombstoneRequestIds(liveRequestIds);
23382
+ }
23383
+ }
23384
+ if (input.tag === void 0) {
23385
+ this.networkHistory.tombstoneRequestIds(this.networkHistory.getKnownRequestIds());
23386
+ } else {
23387
+ this.networkHistory.clearTag(input.tag);
23388
+ }
23270
23389
  return {
23271
23390
  clearedCount: await timeout.runStep(() => root.registry.savedNetwork.clear(input))
23272
23391
  };
@@ -23983,7 +24102,6 @@ var OpensteerSessionRuntime = class {
23983
24102
  });
23984
24103
  const networkRecords = await this.queryLiveNetwork(
23985
24104
  {
23986
- source: "live",
23987
24105
  pageRef,
23988
24106
  ...input.network?.url === void 0 ? {} : { url: input.network.url },
23989
24107
  ...input.network?.hostname === void 0 ? {} : { hostname: input.network.hostname },
@@ -23999,7 +24117,7 @@ var OpensteerSessionRuntime = class {
23999
24117
  );
24000
24118
  const persistedNetwork = filterReverseObservationWindow(
24001
24119
  networkRecords.filter(isReverseRelevantNetworkRecord),
24002
- this.networkJournal,
24120
+ this.networkHistory,
24003
24121
  input.captureWindowMs
24004
24122
  );
24005
24123
  const fallbackSavedNetwork = persistedNetwork.length === 0 ? (await root.registry.savedNetwork.query({
@@ -24014,7 +24132,10 @@ var OpensteerSessionRuntime = class {
24014
24132
  const observationId = `observation:${randomUUID()}`;
24015
24133
  const networkTag = `reverse-case:${caseRecord.id}:${observationId}`;
24016
24134
  if (observationNetwork.length > 0) {
24017
- await root.registry.savedNetwork.save(observationNetwork, networkTag);
24135
+ await root.registry.savedNetwork.save(observationNetwork, {
24136
+ tag: networkTag,
24137
+ bodyWriteMode: input.network?.includeBodies === false ? "metadata-only" : "authoritative"
24138
+ });
24018
24139
  }
24019
24140
  const scriptArtifactIds = input.includeScripts === false ? [] : (await this.captureScriptsInternal(
24020
24141
  pageRef,
@@ -24110,7 +24231,7 @@ var OpensteerSessionRuntime = class {
24110
24231
  includeBodies: true,
24111
24232
  redactSecretHeaders: false
24112
24233
  }),
24113
- observedAt: this.networkJournal.getObservedAt(recordId)
24234
+ observedAt: this.networkHistory.getObservedAt(recordId)
24114
24235
  }))
24115
24236
  );
24116
24237
  const clusteredRecords = observationRecords.map((entry) => {
@@ -25050,7 +25171,10 @@ var OpensteerSessionRuntime = class {
25050
25171
  timeout.signal
25051
25172
  )).filter((record) => !baselineRequestIds.has(record.record.requestId));
25052
25173
  if (deltaRecords.length > 0) {
25053
- await root.registry.savedNetwork.save(deltaRecords, `interaction:${pageRef}`);
25174
+ await root.registry.savedNetwork.save(deltaRecords, {
25175
+ tag: `interaction:${pageRef}`,
25176
+ bodyWriteMode: "authoritative"
25177
+ });
25054
25178
  }
25055
25179
  const trace = await root.registry.interactionTraces.write({
25056
25180
  key: input.key ?? buildInteractionTraceKey(pageInfo.url),
@@ -25393,7 +25517,7 @@ var OpensteerSessionRuntime = class {
25393
25517
  includeBodies: true
25394
25518
  });
25395
25519
  const inferred = inferRequestPlanFromNetworkRecord(source, input, {
25396
- ...this.networkJournal.getObservedAt(source.recordId) === void 0 ? {} : { observedAt: this.networkJournal.getObservedAt(source.recordId) }
25520
+ ...this.networkHistory.getObservedAt(source.recordId) === void 0 ? {} : { observedAt: this.networkHistory.getObservedAt(source.recordId) }
25397
25521
  });
25398
25522
  return timeout.runStep(
25399
25523
  () => root.registry.requestPlans.write({
@@ -26205,7 +26329,7 @@ var OpensteerSessionRuntime = class {
26205
26329
  await this.runWithOperationTimeout(
26206
26330
  "session.close",
26207
26331
  async (timeout) => {
26208
- await timeout.runStep(() => this.flushBackgroundNetworkPersistence());
26332
+ await timeout.runStep(() => this.flushPersistedNetworkHistory());
26209
26333
  if (engine === void 0) {
26210
26334
  return;
26211
26335
  }
@@ -26274,10 +26398,7 @@ var OpensteerSessionRuntime = class {
26274
26398
  }
26275
26399
  async disconnect() {
26276
26400
  try {
26277
- await this.flushBackgroundNetworkPersistence();
26278
- if (this.sessionRef !== void 0 && this.pageRef !== void 0) {
26279
- await this.saveNetwork({ tag: "auto" }).catch(() => void 0);
26280
- }
26401
+ await this.flushPersistedNetworkHistory();
26281
26402
  } finally {
26282
26403
  await this.resetRuntimeState({
26283
26404
  disposeEngine: true
@@ -26369,7 +26490,10 @@ var OpensteerSessionRuntime = class {
26369
26490
  };
26370
26491
  }
26371
26492
  if (target.kind === "element") {
26372
- const elementTarget = { kind: "selector", selector: `[c="${String(target.element)}"]` };
26493
+ const elementTarget = {
26494
+ kind: "selector",
26495
+ selector: `[c="${String(target.element)}"]`
26496
+ };
26373
26497
  const resolved2 = await timeout.runStep(
26374
26498
  () => this.requireDom().resolveTarget({
26375
26499
  pageRef,
@@ -26432,11 +26556,11 @@ var OpensteerSessionRuntime = class {
26432
26556
  };
26433
26557
  }
26434
26558
  async queryLiveNetwork(input, timeout, options = {}) {
26435
- const requestIds = resolveLiveQueryRequestIds(input, this.networkJournal);
26559
+ const requestIds = resolveLiveQueryRequestIds(input, this.networkHistory);
26436
26560
  if (requestIds !== void 0 && requestIds.length === 0) {
26437
26561
  return [];
26438
26562
  }
26439
- const pageRef = resolveLiveQueryPageRef(input, this.pageRef, requestIds, this.networkJournal);
26563
+ const pageRef = resolveLiveQueryPageRef(input, this.pageRef, requestIds, this.networkHistory);
26440
26564
  const includeCurrentPageOnly = pageRef === void 0 && input.recordId === void 0;
26441
26565
  const metadataRecords = await timeout.runStep(
26442
26566
  () => this.readLiveNetworkRecords(
@@ -26463,7 +26587,7 @@ var OpensteerSessionRuntime = class {
26463
26587
  ...input.status === void 0 ? {} : { status: input.status },
26464
26588
  ...input.resourceType === void 0 ? {} : { resourceType: input.resourceType }
26465
26589
  });
26466
- const sorted = sortLiveNetworkRecords(filtered, this.networkJournal);
26590
+ const sorted = sortLiveNetworkRecords(filtered, this.networkHistory);
26467
26591
  const limit = options.ignoreLimit ? sorted.length : Math.max(1, Math.min(input.limit ?? 50, 200));
26468
26592
  const limited = sorted.slice(0, limit);
26469
26593
  if (!(input.includeBodies ?? false) || limited.length === 0) {
@@ -26679,21 +26803,40 @@ var OpensteerSessionRuntime = class {
26679
26803
  if (delta.length === 0) {
26680
26804
  return;
26681
26805
  }
26682
- this.networkJournal.assignActionId(delta, `action:${randomUUID()}`);
26683
- if (networkTag === void 0) {
26684
- return;
26806
+ this.networkHistory.assignActionId(delta, `action:${randomUUID()}`);
26807
+ if (networkTag !== void 0) {
26808
+ this.networkHistory.addTag(delta, networkTag);
26685
26809
  }
26686
- this.networkJournal.addTag(delta, networkTag);
26687
- this.scheduleBackgroundNetworkSaveByRequestIds(
26810
+ await this.persistLiveRequestIds(
26688
26811
  delta.map((record) => record.record.requestId),
26689
- networkTag
26812
+ timeout,
26813
+ {
26814
+ includeCurrentPageOnly: true
26815
+ }
26690
26816
  );
26691
26817
  }
26692
26818
  async resolveNetworkRecordByRecordId(recordId, timeout, options) {
26693
26819
  const root = await this.ensureRoot();
26820
+ await this.syncPersistedNetworkSelection(
26821
+ timeout,
26822
+ {
26823
+ recordId,
26824
+ includeBodies: options.includeBodies
26825
+ },
26826
+ {
26827
+ includeBodies: options.includeBodies
26828
+ }
26829
+ );
26830
+ const saved = await timeout.runStep(
26831
+ () => root.registry.savedNetwork.getByRecordId(recordId, {
26832
+ includeBodies: options.includeBodies
26833
+ })
26834
+ );
26835
+ if (saved) {
26836
+ return saved;
26837
+ }
26694
26838
  const live = await this.queryLiveNetwork(
26695
26839
  {
26696
- source: "live",
26697
26840
  recordId,
26698
26841
  includeBodies: options.includeBodies,
26699
26842
  limit: 1
@@ -26704,24 +26847,15 @@ var OpensteerSessionRuntime = class {
26704
26847
  ...options.redactSecretHeaders === void 0 ? {} : { redactSecretHeaders: options.redactSecretHeaders }
26705
26848
  }
26706
26849
  );
26707
- if (live.length > 0) {
26850
+ if (live[0] !== void 0) {
26708
26851
  return live[0];
26709
26852
  }
26710
- await timeout.runStep(() => this.flushBackgroundNetworkPersistence());
26711
- const saved = await timeout.runStep(
26712
- () => root.registry.savedNetwork.getByRecordId(recordId, {
26713
- includeBodies: options.includeBodies
26714
- })
26715
- );
26716
- if (!saved) {
26717
- throw new OpensteerProtocolError("not-found", `network record ${recordId} was not found`, {
26718
- details: {
26719
- recordId,
26720
- kind: "network-record"
26721
- }
26722
- });
26723
- }
26724
- return saved;
26853
+ throw new OpensteerProtocolError("not-found", `network record ${recordId} was not found`, {
26854
+ details: {
26855
+ recordId,
26856
+ kind: "network-record"
26857
+ }
26858
+ });
26725
26859
  }
26726
26860
  resolveCurrentStateSource() {
26727
26861
  const ownership = this.sessionInfoBase.provider?.ownership;
@@ -26961,7 +27095,6 @@ var OpensteerSessionRuntime = class {
26961
27095
  timeout.throwIfAborted();
26962
27096
  const records = await this.queryLiveNetwork(
26963
27097
  {
26964
- source: "live",
26965
27098
  pageRef,
26966
27099
  url,
26967
27100
  method,
@@ -26992,7 +27125,6 @@ var OpensteerSessionRuntime = class {
26992
27125
  timeout.throwIfAborted();
26993
27126
  const records = await this.queryLiveNetwork(
26994
27127
  {
26995
- source: "live",
26996
27128
  pageRef,
26997
27129
  ...filter.url === void 0 ? {} : { url: filter.url },
26998
27130
  ...filter.host === void 0 ? {} : { hostname: filter.host },
@@ -27058,12 +27190,12 @@ var OpensteerSessionRuntime = class {
27058
27190
  };
27059
27191
  }
27060
27192
  }
27061
- async readLiveNetworkRecords(input, signal) {
27193
+ async readBrowserNetworkRecords(input, signal) {
27062
27194
  const sessionRef = this.sessionRef;
27063
27195
  if (!sessionRef) {
27064
27196
  throw new Error("Opensteer session is not initialized");
27065
27197
  }
27066
- const records = await this.requireEngine().getNetworkRecords({
27198
+ return this.requireEngine().getNetworkRecords({
27067
27199
  sessionRef,
27068
27200
  ...input.includeCurrentPageOnly === false || input.pageRef !== void 0 ? input.pageRef === void 0 ? {} : { pageRef: input.pageRef } : this.pageRef === void 0 ? {} : { pageRef: this.pageRef },
27069
27201
  ...input.requestIds === void 0 ? {} : { requestIds: input.requestIds },
@@ -27076,10 +27208,102 @@ var OpensteerSessionRuntime = class {
27076
27208
  includeBodies: input.includeBodies,
27077
27209
  signal
27078
27210
  });
27079
- return this.networkJournal.sync(records, {
27211
+ }
27212
+ async readLiveNetworkRecords(input, signal) {
27213
+ const records = await this.readBrowserNetworkRecords(input, signal);
27214
+ return this.networkHistory.materialize(records, {
27080
27215
  redactSecretHeaders: input.redactSecretHeaders ?? true
27081
27216
  });
27082
27217
  }
27218
+ async persistLiveRequestIds(requestIds, timeout, options) {
27219
+ if (requestIds.length === 0) {
27220
+ return [];
27221
+ }
27222
+ const root = await this.ensureRoot();
27223
+ const browserRecords = await timeout.runStep(
27224
+ () => this.readBrowserNetworkRecords(
27225
+ {
27226
+ includeBodies: true,
27227
+ includeCurrentPageOnly: options.includeCurrentPageOnly,
27228
+ ...options.pageRef === void 0 ? {} : { pageRef: options.pageRef },
27229
+ requestIds
27230
+ },
27231
+ timeout.signal
27232
+ )
27233
+ );
27234
+ return timeout.runStep(
27235
+ () => this.networkHistory.persist(browserRecords, root.registry.savedNetwork, {
27236
+ bodyWriteMode: "authoritative",
27237
+ redactSecretHeaders: false
27238
+ })
27239
+ );
27240
+ }
27241
+ async syncPersistedNetworkSelection(timeout, input, options) {
27242
+ if (this.sessionRef === void 0) {
27243
+ return [];
27244
+ }
27245
+ const requestIds = resolveLiveQueryRequestIds(input, this.networkHistory);
27246
+ if (requestIds !== void 0 && requestIds.length === 0) {
27247
+ return [];
27248
+ }
27249
+ const pageRef = resolveLiveQueryPageRef(input, this.pageRef, requestIds, this.networkHistory);
27250
+ const includeCurrentPageOnly = pageRef === void 0 && input.recordId === void 0;
27251
+ const browserRecords = await timeout.runStep(
27252
+ () => this.readBrowserNetworkRecords(
27253
+ {
27254
+ ...pageRef === void 0 ? {} : { pageRef },
27255
+ ...requestIds === void 0 ? {} : { requestIds },
27256
+ ...input.url === void 0 ? {} : { url: input.url },
27257
+ ...input.hostname === void 0 ? {} : { hostname: input.hostname },
27258
+ ...input.path === void 0 ? {} : { path: input.path },
27259
+ ...input.method === void 0 ? {} : { method: input.method },
27260
+ ...input.status === void 0 ? {} : { status: input.status },
27261
+ ...input.resourceType === void 0 ? {} : { resourceType: input.resourceType },
27262
+ includeBodies: options.includeBodies,
27263
+ includeCurrentPageOnly
27264
+ },
27265
+ timeout.signal
27266
+ )
27267
+ );
27268
+ const root = await this.ensureRoot();
27269
+ return timeout.runStep(
27270
+ () => this.networkHistory.persist(browserRecords, root.registry.savedNetwork, {
27271
+ bodyWriteMode: options.includeBodies ? "authoritative" : "metadata-only",
27272
+ redactSecretHeaders: false
27273
+ })
27274
+ );
27275
+ }
27276
+ toSavedNetworkQueryInput(input) {
27277
+ return {
27278
+ ...input.pageRef === void 0 ? {} : { pageRef: input.pageRef },
27279
+ ...input.recordId === void 0 ? {} : { recordId: input.recordId },
27280
+ ...input.requestId === void 0 ? {} : { requestId: input.requestId },
27281
+ ...input.actionId === void 0 ? {} : { actionId: input.actionId },
27282
+ ...input.tag === void 0 ? {} : { tag: input.tag },
27283
+ ...input.url === void 0 ? {} : { url: input.url },
27284
+ ...input.hostname === void 0 ? {} : { hostname: input.hostname },
27285
+ ...input.path === void 0 ? {} : { path: input.path },
27286
+ ...input.method === void 0 ? {} : { method: input.method },
27287
+ ...input.status === void 0 ? {} : { status: input.status },
27288
+ ...input.resourceType === void 0 ? {} : { resourceType: input.resourceType },
27289
+ ...input.includeBodies === void 0 ? {} : { includeBodies: input.includeBodies },
27290
+ ...input.limit === void 0 ? {} : { limit: input.limit }
27291
+ };
27292
+ }
27293
+ toQueryInputFromTagInput(input) {
27294
+ return {
27295
+ ...input.pageRef === void 0 ? {} : { pageRef: input.pageRef },
27296
+ ...input.recordId === void 0 ? {} : { recordId: input.recordId },
27297
+ ...input.requestId === void 0 ? {} : { requestId: input.requestId },
27298
+ ...input.actionId === void 0 ? {} : { actionId: input.actionId },
27299
+ ...input.url === void 0 ? {} : { url: input.url },
27300
+ ...input.hostname === void 0 ? {} : { hostname: input.hostname },
27301
+ ...input.path === void 0 ? {} : { path: input.path },
27302
+ ...input.method === void 0 ? {} : { method: input.method },
27303
+ ...input.status === void 0 ? {} : { status: input.status },
27304
+ ...input.resourceType === void 0 ? {} : { resourceType: input.resourceType }
27305
+ };
27306
+ }
27083
27307
  async readLiveRequestIds(timeout, options) {
27084
27308
  const records = await timeout.runStep(
27085
27309
  () => this.readLiveNetworkRecords(
@@ -27103,7 +27327,17 @@ var OpensteerSessionRuntime = class {
27103
27327
  )
27104
27328
  );
27105
27329
  const delta = records.filter((record) => !baselineRequestIds.has(record.record.requestId));
27106
- return sortLiveNetworkRecords(delta, this.networkJournal)[0]?.recordId;
27330
+ if (delta.length === 0) {
27331
+ return void 0;
27332
+ }
27333
+ await this.persistLiveRequestIds(
27334
+ delta.map((record) => record.record.requestId),
27335
+ timeout,
27336
+ {
27337
+ includeCurrentPageOnly: options.includeCurrentPageOnly
27338
+ }
27339
+ );
27340
+ return sortLiveNetworkRecords(delta, this.networkHistory)[0]?.recordId;
27107
27341
  }
27108
27342
  async executeTransportRequestWithJournal(request, timeout, sessionRef) {
27109
27343
  const baselineRequestIds = await this.readLiveRequestIds(timeout, {
@@ -27387,7 +27621,6 @@ var OpensteerSessionRuntime = class {
27387
27621
  const syntheticSessionRef = binding?.sessionRef ?? createSessionRef(`${transportLabel}-${this.workspace}`);
27388
27622
  const record = {
27389
27623
  recordId,
27390
- source: "saved",
27391
27624
  savedAt: now,
27392
27625
  record: {
27393
27626
  kind: "http",
@@ -27409,7 +27642,10 @@ var OpensteerSessionRuntime = class {
27409
27642
  ...response.body === void 0 ? {} : { responseBody: toProtocolBodyPayload(response.body) }
27410
27643
  }
27411
27644
  };
27412
- await root.registry.savedNetwork.save([record], tag);
27645
+ await root.registry.savedNetwork.save([record], {
27646
+ bodyWriteMode: "authoritative",
27647
+ ...tag === void 0 ? {} : { tag }
27648
+ });
27413
27649
  return recordId;
27414
27650
  }
27415
27651
  async executeResolvedRequestPlan(plan, input, timeout, binding) {
@@ -27782,7 +28018,6 @@ var OpensteerSessionRuntime = class {
27782
28018
  const record = await pollUntilResult(timeout, async () => {
27783
28019
  const matches = await this.queryLiveNetwork(
27784
28020
  {
27785
- source: "live",
27786
28021
  ...step.url === void 0 ? {} : { url: interpolateTemplate(step.url, variables) },
27787
28022
  ...step.hostname === void 0 ? {} : { hostname: interpolateTemplate(step.hostname, variables) },
27788
28023
  ...step.path === void 0 ? {} : { path: interpolateTemplate(step.path, variables) },
@@ -28240,37 +28475,7 @@ var OpensteerSessionRuntime = class {
28240
28475
  const pageUrl = step.pageUrl === void 0 ? void 0 : interpolateTemplate(step.pageUrl, variables);
28241
28476
  return snapshot.sessionStorage?.filter((entry) => entry.origin === origin).find((entry) => pageUrl === void 0 || entry.origin === new URL(pageUrl).origin)?.entries.find((entry) => entry.key === key)?.value;
28242
28477
  }
28243
- scheduleBackgroundNetworkSaveByRequestIds(requestIds, tag) {
28244
- const task = (async () => {
28245
- const root = await this.ensureRoot();
28246
- const requestIdSet = new Set(requestIds);
28247
- const records = await this.readLiveNetworkRecords(
28248
- {
28249
- includeBodies: true,
28250
- includeCurrentPageOnly: false,
28251
- ...this.pageRef === void 0 ? {} : { pageRef: this.pageRef },
28252
- requestIds,
28253
- redactSecretHeaders: false
28254
- },
28255
- new AbortController().signal
28256
- );
28257
- const filtered = records.filter((record) => requestIdSet.has(record.record.requestId));
28258
- if (filtered.length === 0) {
28259
- return;
28260
- }
28261
- await root.registry.savedNetwork.save(filtered, tag);
28262
- })();
28263
- this.backgroundNetworkPersistence.add(task);
28264
- task.finally(() => {
28265
- this.backgroundNetworkPersistence.delete(task);
28266
- });
28267
- void task.catch(() => void 0);
28268
- }
28269
- async flushBackgroundNetworkPersistence() {
28270
- if (this.backgroundNetworkPersistence.size === 0) {
28271
- return;
28272
- }
28273
- await Promise.all([...this.backgroundNetworkPersistence]);
28478
+ async flushPersistedNetworkHistory() {
28274
28479
  }
28275
28480
  toDomTargetRef(target) {
28276
28481
  if (target.kind === "description") {
@@ -28305,7 +28510,9 @@ var OpensteerSessionRuntime = class {
28305
28510
  ...workspace.registry,
28306
28511
  ...overrides.requestPlans === void 0 ? {} : { requestPlans: overrides.requestPlans },
28307
28512
  ...overrides.authRecipes === void 0 ? {} : { authRecipes: overrides.authRecipes },
28308
- ...overrides.recipes === void 0 ? {} : { recipes: overrides.recipes }
28513
+ ...overrides.recipes === void 0 ? {} : { recipes: overrides.recipes },
28514
+ ...overrides.reverseCases === void 0 ? {} : { reverseCases: overrides.reverseCases },
28515
+ ...overrides.reversePackages === void 0 ? {} : { reversePackages: overrides.reversePackages }
28309
28516
  }
28310
28517
  };
28311
28518
  } else {
@@ -28562,8 +28769,7 @@ var OpensteerSessionRuntime = class {
28562
28769
  }
28563
28770
  async resetRuntimeState(options) {
28564
28771
  const engine = this.engine;
28565
- this.networkJournal.clear();
28566
- this.backgroundNetworkPersistence.clear();
28772
+ this.networkHistory.clear();
28567
28773
  this.sessionRef = void 0;
28568
28774
  this.pageRef = void 0;
28569
28775
  this.runId = void 0;
@@ -28639,10 +28845,10 @@ function buildEngineNetworkRecordFilters(input) {
28639
28845
  ...input.resourceType === void 0 ? {} : { resourceType: input.resourceType }
28640
28846
  };
28641
28847
  }
28642
- function resolveLiveQueryRequestIds(input, journal) {
28848
+ function resolveLiveQueryRequestIds(input, history) {
28643
28849
  const requestIdCandidates = [];
28644
28850
  if (input.recordId !== void 0) {
28645
- const requestId = journal.getRequestId(input.recordId);
28851
+ const requestId = history.getRequestId(input.recordId);
28646
28852
  if (requestId === void 0) {
28647
28853
  return [];
28648
28854
  }
@@ -28652,24 +28858,24 @@ function resolveLiveQueryRequestIds(input, journal) {
28652
28858
  requestIdCandidates.push(/* @__PURE__ */ new Set([input.requestId]));
28653
28859
  }
28654
28860
  if (input.actionId !== void 0) {
28655
- requestIdCandidates.push(journal.getRequestIdsForActionId(input.actionId));
28861
+ requestIdCandidates.push(history.getRequestIdsForActionId(input.actionId));
28656
28862
  }
28657
28863
  if (input.tag !== void 0) {
28658
- requestIdCandidates.push(journal.getRequestIdsForTag(input.tag));
28864
+ requestIdCandidates.push(history.getRequestIdsForTag(input.tag));
28659
28865
  }
28660
28866
  if (requestIdCandidates.length === 0) {
28661
28867
  return void 0;
28662
28868
  }
28663
28869
  return intersectRequestIdSets(requestIdCandidates);
28664
28870
  }
28665
- function resolveLiveQueryPageRef(input, currentPageRef, requestIds, journal) {
28871
+ function resolveLiveQueryPageRef(input, currentPageRef, requestIds, history) {
28666
28872
  const requestedPageRef = selectLiveQueryPageRef(input, currentPageRef);
28667
28873
  if (requestedPageRef !== void 0 || requestIds === void 0) {
28668
28874
  return requestedPageRef;
28669
28875
  }
28670
28876
  const pageRefs = /* @__PURE__ */ new Set();
28671
28877
  for (const requestId of requestIds) {
28672
- const pageRef = journal.getPageRefForRequestId(requestId);
28878
+ const pageRef = history.getPageRefForRequestId(requestId);
28673
28879
  if (pageRef === void 0) {
28674
28880
  continue;
28675
28881
  }
@@ -28711,10 +28917,10 @@ function filterNetworkQueryRecords(records, input) {
28711
28917
  return true;
28712
28918
  });
28713
28919
  }
28714
- function sortLiveNetworkRecords(records, journal) {
28920
+ function sortLiveNetworkRecords(records, history) {
28715
28921
  return [...records].sort((left, right) => {
28716
- const leftObservedAt = journal.getObservedAt(left.recordId) ?? 0;
28717
- const rightObservedAt = journal.getObservedAt(right.recordId) ?? 0;
28922
+ const leftObservedAt = history.getObservedAt(left.recordId) ?? 0;
28923
+ const rightObservedAt = history.getObservedAt(right.recordId) ?? 0;
28718
28924
  if (leftObservedAt !== rightObservedAt) {
28719
28925
  return rightObservedAt - leftObservedAt;
28720
28926
  }
@@ -28921,7 +29127,7 @@ function buildMinimizedRequestPlan(input) {
28921
29127
  provenance: {
28922
29128
  source: "network-minimize",
28923
29129
  sourceId: input.record.recordId,
28924
- ...input.record.source === "saved" && input.record.savedAt !== void 0 ? { capturedAt: input.record.savedAt } : {}
29130
+ ...input.record.savedAt === void 0 ? {} : { capturedAt: input.record.savedAt }
28925
29131
  },
28926
29132
  payload: normalizeRequestPlanPayload({
28927
29133
  transport: {
@@ -29140,12 +29346,12 @@ function originFromUrl(url) {
29140
29346
  return void 0;
29141
29347
  }
29142
29348
  }
29143
- function filterReverseObservationWindow(records, journal, captureWindowMs) {
29349
+ function filterReverseObservationWindow(records, history, captureWindowMs) {
29144
29350
  if (captureWindowMs === void 0) {
29145
29351
  return records;
29146
29352
  }
29147
29353
  const observedAfter = Date.now() - captureWindowMs;
29148
- return records.filter((record) => (journal.getObservedAt(record.recordId) ?? 0) >= observedAfter);
29354
+ return records.filter((record) => (history.getObservedAt(record.recordId) ?? 0) >= observedAfter);
29149
29355
  }
29150
29356
  function isReverseRelevantNetworkRecord(record) {
29151
29357
  return record.record.resourceType === "document" || record.record.resourceType === "fetch" || record.record.resourceType === "xhr" || record.record.resourceType === "websocket" || record.record.resourceType === "event-stream";
@@ -31152,6 +31358,7 @@ var OpensteerRuntime = class extends OpensteerSessionRuntime {
31152
31358
  ...options.policy === void 0 ? {} : { policy: options.policy },
31153
31359
  ...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
31154
31360
  ...options.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: options.extractionDescriptorStore },
31361
+ ...options.registryOverrides === void 0 ? {} : { registryOverrides: options.registryOverrides },
31155
31362
  cleanupRootOnClose
31156
31363
  })
31157
31364
  );
@@ -31180,6 +31387,7 @@ var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
31180
31387
  ...options.policy === void 0 ? {} : { policy: options.policy },
31181
31388
  ...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
31182
31389
  ...options.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: options.extractionDescriptorStore },
31390
+ ...options.registryOverrides === void 0 ? {} : { registryOverrides: options.registryOverrides },
31183
31391
  cleanupRootOnClose
31184
31392
  })
31185
31393
  );
@@ -31204,6 +31412,7 @@ function buildSharedRuntimeOptions(input) {
31204
31412
  ...input.policy === void 0 ? {} : { policy: input.policy },
31205
31413
  ...input.descriptorStore === void 0 ? {} : { descriptorStore: input.descriptorStore },
31206
31414
  ...input.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: input.extractionDescriptorStore },
31415
+ ...input.registryOverrides === void 0 ? {} : { registryOverrides: input.registryOverrides },
31207
31416
  cleanupRootOnClose: input.cleanupRootOnClose,
31208
31417
  sessionInfo: {
31209
31418
  provider: {
@@ -31944,6 +32153,20 @@ var OpensteerCloudClient = class {
31944
32153
  });
31945
32154
  return await response.json();
31946
32155
  }
32156
+ async importReverseCases(entries) {
32157
+ const response = await this.request("/registry/reverse-cases/import", {
32158
+ method: "POST",
32159
+ body: { entries }
32160
+ });
32161
+ return await response.json();
32162
+ }
32163
+ async importReversePackages(entries) {
32164
+ const response = await this.request("/registry/reverse-packages/import", {
32165
+ method: "POST",
32166
+ body: { entries }
32167
+ });
32168
+ return await response.json();
32169
+ }
31947
32170
  buildAuthorizationHeader() {
31948
32171
  return `Bearer ${this.config.apiKey}`;
31949
32172
  }
@@ -32459,11 +32682,13 @@ function asRecord(value) {
32459
32682
  var REGISTRY_SYNC_MAX_PAYLOAD_BYTES = 15e5;
32460
32683
  var REGISTRY_SYNC_MAX_ENTRIES_PER_BATCH = 100;
32461
32684
  async function syncLocalRegistryToCloud(client, workspace, store) {
32462
- const [descriptors, requestPlans, recipes, authRecipes] = await Promise.all([
32685
+ const [descriptors, requestPlans, recipes, authRecipes, reverseCases, reversePackages] = await Promise.all([
32463
32686
  store.registry.descriptors.list(),
32464
32687
  store.registry.requestPlans.list(),
32465
32688
  store.registry.recipes.list(),
32466
- store.registry.authRecipes.list()
32689
+ store.registry.authRecipes.list(),
32690
+ store.registry.reverseCases.list(),
32691
+ store.registry.reversePackages.list()
32467
32692
  ]);
32468
32693
  const descriptorEntries = descriptors.map((record) => toDescriptorImportEntry(workspace, record));
32469
32694
  await Promise.all([
@@ -32479,6 +32704,14 @@ async function syncLocalRegistryToCloud(client, workspace, store) {
32479
32704
  importInBatches(
32480
32705
  authRecipes.map((record) => toRegistryImportEntry(workspace, record)),
32481
32706
  (entries) => client.importAuthRecipes(entries)
32707
+ ),
32708
+ importInBatches(
32709
+ reverseCases.map((record) => toRegistryImportEntry(workspace, record)),
32710
+ (entries) => client.importReverseCases(entries)
32711
+ ),
32712
+ importInBatches(
32713
+ reversePackages.map((record) => toRegistryImportEntry(workspace, record)),
32714
+ (entries) => client.importReversePackages(entries)
32482
32715
  )
32483
32716
  ]);
32484
32717
  }
@@ -32688,9 +32921,9 @@ var CloudSessionProxy = class {
32688
32921
  await this.ensureSession();
32689
32922
  return this.requireClient().invoke("network.query", input);
32690
32923
  }
32691
- async saveNetwork(input) {
32924
+ async tagNetwork(input) {
32692
32925
  await this.ensureSession();
32693
- return this.requireClient().invoke("network.save", input);
32926
+ return this.requireClient().invoke("network.tag", input);
32694
32927
  }
32695
32928
  async minimizeNetwork(input) {
32696
32929
  await this.ensureSession();
@@ -33055,5 +33288,5 @@ function createOpensteerSemanticRuntime(input = {}) {
33055
33288
  }
33056
33289
 
33057
33290
  export { CloudSessionProxy, DEFAULT_OPENSTEER_ENGINE, DEFERRED_MATCH_ATTR_KEYS, ElementPathError, MATCH_ATTRIBUTE_PRIORITY, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL, OPENSTEER_ENGINE_NAMES, OPENSTEER_FILESYSTEM_WORKSPACE_LAYOUT, OPENSTEER_FILESYSTEM_WORKSPACE_VERSION, OpensteerAttachAmbiguousError, OpensteerBrowserManager, OpensteerCloudClient, OpensteerRuntime, OpensteerSessionRuntime2 as OpensteerSessionRuntime, STABLE_PRIMARY_ATTR_KEYS, assertProviderSupportsEngine, buildArrayFieldPathCandidates, buildDomDescriptorKey, buildDomDescriptorPayload, buildDomDescriptorVersion, buildPathCandidates, buildPathSelectorHint, buildSegmentSelector, clearPersistedSessionRecord, cloneElementPath, cloneReplayElementPath, cloneStructuralElementAnchor, createDomRuntime, createFilesystemOpensteerWorkspace, createOpensteerExtractionDescriptorStore, createOpensteerSemanticRuntime, defaultFallbackPolicy, defaultPolicy, defaultRetryPolicy, defaultSettlePolicy, defaultTimeoutPolicy, delayWithSignal, discoverLocalCdpBrowsers, dispatchSemanticOperation, hashDomDescriptorDescription, inspectCdpEndpoint, isCurrentUrlField, isProcessRunning, isValidCssAttributeKey, listLocalChromeProfiles, normalizeExtractedValue, normalizeOpensteerEngineName, normalizeOpensteerProviderMode, normalizeWorkspaceId, parseDomDescriptorRecord, parseExtractionDescriptorRecord, pathExists, readPersistedCloudSessionRecord, readPersistedLocalBrowserSessionRecord, readPersistedSessionRecord, resolveCloudConfig, resolveCloudSessionRecordPath, resolveDomActionBridge, resolveExtractedValueInContext, resolveFilesystemWorkspacePath, resolveLiveSessionRecordPath, resolveLocalSessionRecordPath, resolveOpensteerEngineName, resolveOpensteerProvider, resolveOpensteerRuntimeConfig, runWithPolicyTimeout, sanitizeElementPath, sanitizeReplayElementPath, sanitizeStructuralElementAnchor, settleWithPolicy, shouldKeepAttributeForPath, writePersistedSessionRecord };
33058
- //# sourceMappingURL=chunk-KYRC6CLB.js.map
33059
- //# sourceMappingURL=chunk-KYRC6CLB.js.map
33291
+ //# sourceMappingURL=chunk-IAA57HNW.js.map
33292
+ //# sourceMappingURL=chunk-IAA57HNW.js.map