@btraut/browser-bridge 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -8,6 +8,13 @@ The format is based on "Keep a Changelog", and this project adheres to Semantic
8
8
 
9
9
  _TBD_
10
10
 
11
+ ## [0.7.1] - 2026-02-11
12
+
13
+ ### Fixed
14
+
15
+ - Diagnostics doctor: stop failing by default when `session_id` is omitted, treat detached debugger as expected idle behavior, and downgrade stale drive/inspect errors to warnings.
16
+ - Core error latching: clear drive/inspect/debugger `last_error` state after successful operations so recovered sessions report healthy diagnostics.
17
+
11
18
  ## [0.7.0] - 2026-02-10
12
19
 
13
20
  ### Fixed
package/dist/api.js CHANGED
@@ -848,6 +848,10 @@ var DriveController = class {
848
848
  this.lastError = error;
849
849
  this.lastErrorAt = (/* @__PURE__ */ new Date()).toISOString();
850
850
  }
851
+ clearLastError() {
852
+ this.lastError = void 0;
853
+ this.lastErrorAt = void 0;
854
+ }
851
855
  async execute(sessionId, action, params, timeoutMs) {
852
856
  return await driveMutex.runExclusive(async () => {
853
857
  try {
@@ -888,6 +892,7 @@ var DriveController = class {
888
892
  timeoutMs
889
893
  );
890
894
  if (response.status === "ok") {
895
+ this.clearLastError();
891
896
  return {
892
897
  ok: true,
893
898
  result: response.result
@@ -2800,6 +2805,7 @@ var InspectService = class {
2800
2805
  });
2801
2806
  }
2802
2807
  markInspectConnected(sessionId) {
2808
+ this.clearLastError();
2803
2809
  try {
2804
2810
  const session = this.registry.require(sessionId);
2805
2811
  if (session.state === "INIT" /* INIT */ || session.state === "DRIVE_READY" /* DRIVE_READY */) {
@@ -2814,6 +2820,10 @@ var InspectService = class {
2814
2820
  this.lastError = error;
2815
2821
  this.lastErrorAt = (/* @__PURE__ */ new Date()).toISOString();
2816
2822
  }
2823
+ clearLastError() {
2824
+ this.lastError = void 0;
2825
+ this.lastErrorAt = void 0;
2826
+ }
2817
2827
  buildUnavailableError() {
2818
2828
  return new InspectError(
2819
2829
  "INSPECT_UNAVAILABLE",
@@ -3474,10 +3484,20 @@ var registerArtifactsRoutes = (router, options = {}) => {
3474
3484
  };
3475
3485
 
3476
3486
  // packages/core/src/diagnostics.ts
3487
+ var STALE_ERROR_THRESHOLD_MS = 2 * 60 * 1e3;
3488
+ var getErrorAgeMs = (timestamp) => {
3489
+ const parsed = Date.parse(timestamp);
3490
+ if (!Number.isFinite(parsed)) {
3491
+ return void 0;
3492
+ }
3493
+ return Math.max(0, Date.now() - parsed);
3494
+ };
3477
3495
  var buildDiagnosticReport = (sessionId, context = {}) => {
3478
3496
  const extensionConnected = context.extension?.connected ?? false;
3479
3497
  const debuggerAttached = context.debugger?.attached ?? false;
3480
3498
  const sessionState = context.sessionState;
3499
+ const hasSessionId = Boolean(sessionId);
3500
+ const warnings = [];
3481
3501
  const checks = [
3482
3502
  {
3483
3503
  name: "extension.connected",
@@ -3486,13 +3506,13 @@ var buildDiagnosticReport = (sessionId, context = {}) => {
3486
3506
  },
3487
3507
  {
3488
3508
  name: "debugger.attached",
3489
- ok: debuggerAttached,
3490
- message: debuggerAttached ? "Debugger is attached." : "Debugger is not attached."
3509
+ ok: true,
3510
+ message: debuggerAttached ? "Debugger is attached." : "Debugger is not attached (inspect is idle)."
3491
3511
  },
3492
3512
  {
3493
3513
  name: "session.state",
3494
- ok: Boolean(sessionState),
3495
- message: sessionState ? `Session state is ${sessionState}.` : sessionId ? "Session state unavailable." : "Session id not provided.",
3514
+ ok: hasSessionId ? Boolean(sessionState) : true,
3515
+ message: sessionState ? `Session state is ${sessionState}.` : hasSessionId ? "Session state unavailable." : "Session id not provided.",
3496
3516
  details: {
3497
3517
  session_id: sessionId || null,
3498
3518
  state: sessionState ?? "UNKNOWN"
@@ -3500,26 +3520,42 @@ var buildDiagnosticReport = (sessionId, context = {}) => {
3500
3520
  }
3501
3521
  ];
3502
3522
  if (context.driveLastError) {
3523
+ const ageMs = getErrorAgeMs(context.driveLastError.at);
3524
+ const isStale = ageMs !== void 0 && ageMs > STALE_ERROR_THRESHOLD_MS;
3525
+ if (isStale) {
3526
+ warnings.push(
3527
+ `Ignoring stale drive error (${Math.round(ageMs / 1e3)}s old): ${context.driveLastError.message}`
3528
+ );
3529
+ }
3503
3530
  checks.push({
3504
3531
  name: "drive.last_error",
3505
- ok: false,
3532
+ ok: isStale,
3506
3533
  message: context.driveLastError.message,
3507
3534
  details: {
3508
3535
  code: context.driveLastError.code,
3509
3536
  retryable: context.driveLastError.retryable,
3510
- at: context.driveLastError.at
3537
+ at: context.driveLastError.at,
3538
+ ...ageMs !== void 0 ? { age_ms: ageMs } : {}
3511
3539
  }
3512
3540
  });
3513
3541
  }
3514
3542
  if (context.inspectLastError) {
3543
+ const ageMs = getErrorAgeMs(context.inspectLastError.at);
3544
+ const isStale = ageMs !== void 0 && ageMs > STALE_ERROR_THRESHOLD_MS;
3545
+ if (isStale) {
3546
+ warnings.push(
3547
+ `Ignoring stale inspect error (${Math.round(ageMs / 1e3)}s old): ${context.inspectLastError.message}`
3548
+ );
3549
+ }
3515
3550
  checks.push({
3516
3551
  name: "inspect.last_error",
3517
- ok: false,
3552
+ ok: isStale,
3518
3553
  message: context.inspectLastError.message,
3519
3554
  details: {
3520
3555
  code: context.inspectLastError.code,
3521
3556
  retryable: context.inspectLastError.retryable,
3522
- at: context.inspectLastError.at
3557
+ at: context.inspectLastError.at,
3558
+ ...ageMs !== void 0 ? { age_ms: ageMs } : {}
3523
3559
  }
3524
3560
  });
3525
3561
  }
@@ -3578,6 +3614,7 @@ var buildDiagnosticReport = (sessionId, context = {}) => {
3578
3614
  loop_detected: context.recoveryMetrics.loopDetected
3579
3615
  } : {}
3580
3616
  } : void 0,
3617
+ ...warnings.length > 0 ? { warnings } : {},
3581
3618
  notes: ["Diagnostics include runtime status; some checks may be stubbed."]
3582
3619
  };
3583
3620
  return report;
@@ -4271,6 +4308,7 @@ var DebuggerBridge = class {
4271
4308
  }
4272
4309
  state.attached = true;
4273
4310
  this.touch(tabId, state);
4311
+ this.clearLastError();
4274
4312
  return { ok: true, result: { attached: true } };
4275
4313
  } catch (error) {
4276
4314
  const info = this.handleBridgeError(error);
@@ -4298,6 +4336,7 @@ var DebuggerBridge = class {
4298
4336
  return { ok: false, error };
4299
4337
  }
4300
4338
  this.markDetached(tabId);
4339
+ this.clearLastError();
4301
4340
  return { ok: true, result: { attached: false } };
4302
4341
  } catch (error) {
4303
4342
  const info = this.handleBridgeError(error);
@@ -4330,6 +4369,7 @@ var DebuggerBridge = class {
4330
4369
  return { ok: false, error };
4331
4370
  }
4332
4371
  this.touch(tabId, this.ensureTab(tabId));
4372
+ this.clearLastError();
4333
4373
  return { ok: true, result: response.result };
4334
4374
  } catch (error) {
4335
4375
  const info = this.handleBridgeError(error);
@@ -4415,6 +4455,10 @@ var DebuggerBridge = class {
4415
4455
  this.lastError = error;
4416
4456
  this.lastErrorAt = (/* @__PURE__ */ new Date()).toISOString();
4417
4457
  }
4458
+ clearLastError() {
4459
+ this.lastError = void 0;
4460
+ this.lastErrorAt = void 0;
4461
+ }
4418
4462
  handleBridgeError(error) {
4419
4463
  if (error instanceof ExtensionBridgeError) {
4420
4464
  const info2 = toDriveError(error);