@btraut/browser-bridge 0.12.0 → 0.12.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,16 @@ The format is based on "Keep a Changelog", and this project adheres to Semantic
8
8
 
9
9
  _TBD_
10
10
 
11
+ ## [0.12.1] - 2026-02-17
12
+
13
+ ### Changed
14
+
15
+ - Extension popup now shows a compact `Connected` indicator (green/red) instead of the verbose connection diagnostics panel.
16
+
17
+ ### Fixed
18
+
19
+ - Extension background now preflights Core `/health` before dialing websocket, avoiding noisy `ERR_CONNECTION_REFUSED` extension errors while Core is offline.
20
+
11
21
  ## [0.12.0] - 2026-02-17
12
22
 
13
23
  ### Changed
package/README.md CHANGED
@@ -318,7 +318,7 @@ tail -n 80 .context/logs/browser-bridge/mcp-adapter.jsonl
318
318
  - CLI: `browser-bridge diagnostics doctor --session-id <id>`
319
319
  - Reports extension and debugger status alongside session state.
320
320
  - Includes runtime context for caller, Core, and extension endpoints so mismatch causes are visible in one run.
321
- - Popup health panel shows live connection state (`connecting`, `connected`, `disconnected`, `backoff`), endpoint/source, and latest failure summary.
321
+ - Popup shows a simple `Connected` indicator (`green` when connected, `red` otherwise).
322
322
 
323
323
  ### End-to-End Connection Troubleshooting Flow
324
324
 
@@ -336,17 +336,15 @@ browser-bridge dev info --json
336
336
  browser-bridge diagnostics doctor --json
337
337
  ```
338
338
 
339
- 3. Open extension popup and compare:
340
- - `Connection` state
341
- - `Endpoint`
342
- - `Source`
343
- - `Last failure`
339
+ 3. Open the extension popup and check `Connected`:
340
+ - Green dot: extension is currently connected to Core.
341
+ - Red dot: extension is disconnected or reconnecting.
344
342
 
345
- 4. If caller/core/extension endpoints differ:
343
+ 4. If caller/core/extension endpoints differ in the diagnostics report:
346
344
  - Default mode: remove custom host/port env overrides and retry (`BROWSER_BRIDGE_CORE_HOST`, `BROWSER_BRIDGE_CORE_PORT`).
347
345
  - Isolated mode: re-run `browser-bridge dev activate --extension-id <id>` for the intended worktree.
348
346
 
349
- 5. If state is `backoff` and failures continue:
347
+ 5. If the popup stays red and failures continue:
350
348
  - Inspect logs:
351
349
 
352
350
  ```bash
@@ -68,111 +68,35 @@ body.bb-page.bb-page--popup {
68
68
  padding: 2px;
69
69
  }
70
70
 
71
- .bb-health {
71
+ .bb-connection {
72
72
  border: 1px solid var(--bb-border-2);
73
73
  border-radius: var(--bb-radius-sm);
74
74
  background: var(--bb-bg);
75
75
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.06);
76
76
  padding: 10px 12px;
77
77
  margin: 0 0 10px;
78
- }
79
-
80
- .bb-health-head {
81
78
  display: flex;
82
79
  align-items: center;
83
80
  justify-content: space-between;
84
- margin-bottom: 8px;
85
- }
86
-
87
- .bb-health-label {
88
- font-size: 12px;
89
- font-weight: 700;
90
- letter-spacing: 0.04em;
91
- color: var(--bb-ink-2);
92
- text-transform: uppercase;
93
- }
94
-
95
- .bb-health-state {
96
- border: 1px solid var(--bb-border);
97
- border-radius: 999px;
98
- padding: 2px 8px;
99
- font-size: 11px;
100
- font-weight: 700;
101
- text-transform: capitalize;
102
- color: var(--bb-ink);
103
- background: rgba(0, 0, 0, 0.04);
104
- }
105
-
106
- .bb-health-state[data-state='connected'] {
107
- color: #1f6f3f;
108
- border-color: rgba(31, 111, 63, 0.35);
109
- background: rgba(31, 111, 63, 0.12);
110
81
  }
111
82
 
112
- .bb-health-state[data-state='connecting'],
113
- .bb-health-state[data-state='backoff'] {
114
- color: #8a5200;
115
- border-color: rgba(138, 82, 0, 0.35);
116
- background: rgba(138, 82, 0, 0.12);
117
- }
118
-
119
- .bb-health-state[data-state='disconnected'] {
120
- color: #a22b2b;
121
- border-color: rgba(162, 43, 43, 0.35);
122
- background: rgba(162, 43, 43, 0.12);
123
- }
124
-
125
- .bb-health-grid {
126
- display: grid;
127
- grid-template-columns: auto 1fr;
128
- gap: 6px 8px;
129
- margin: 0;
130
- }
131
-
132
- .bb-health-grid dt {
133
- margin: 0;
134
- font-size: 11px;
135
- color: var(--bb-ink-2);
136
- }
137
-
138
- .bb-health-grid dd {
139
- margin: 0;
140
- font-size: 12px;
141
- color: var(--bb-ink);
142
- overflow-wrap: anywhere;
143
- }
144
-
145
- .bb-health-error {
146
- min-height: 14px;
147
- margin: 8px 0 0;
148
- font-size: 11px;
149
- color: #a22b2b;
150
- }
151
-
152
- .bb-health-actions {
153
- margin-top: 6px;
154
- display: flex;
155
- align-items: center;
156
- gap: 8px;
157
- }
158
-
159
- .bb-health-copy {
160
- border: 1px solid var(--bb-border);
161
- border-radius: 8px;
162
- background: var(--bb-bg);
83
+ .bb-connection-label {
84
+ font-size: 14px;
85
+ font-weight: 600;
163
86
  color: var(--bb-ink);
164
- padding: 5px 8px;
165
- font-size: 12px;
166
- cursor: pointer;
167
87
  }
168
88
 
169
- .bb-health-copy:hover {
170
- background: var(--bb-hover);
89
+ .bb-connection-dot {
90
+ width: 11px;
91
+ height: 11px;
92
+ border-radius: 999px;
93
+ border: 1px solid rgba(162, 43, 43, 0.35);
94
+ background: #c93939;
171
95
  }
172
96
 
173
- .bb-health-copy-status {
174
- font-size: 11px;
175
- color: var(--bb-ink-2);
97
+ .bb-connection-dot[data-connected='true'] {
98
+ border-color: rgba(31, 111, 63, 0.4);
99
+ background: #2b9a52;
176
100
  }
177
101
 
178
102
  .bb-popup-head {
@@ -488,6 +488,8 @@ var ConnectionStateTracker = class {
488
488
  var DEFAULT_CORE_PORT = 3210;
489
489
  var CORE_PORT_KEY = "corePort";
490
490
  var CORE_WS_PATH = "/drive";
491
+ var CORE_HEALTH_PATH = "/health";
492
+ var CORE_HEALTH_TIMEOUT_MS = 1200;
491
493
  var DEBUGGER_PROTOCOL_VERSION = "1.3";
492
494
  var DEBUGGER_IDLE_TIMEOUT_KEY = "debuggerIdleTimeoutMs";
493
495
  var DEFAULT_DEBUGGER_IDLE_TIMEOUT_MS = 15e3;
@@ -1153,6 +1155,7 @@ var getWsEndpoint = async () => {
1153
1155
  url: `ws://${endpoint.host}:${endpoint.port}${CORE_WS_PATH}`
1154
1156
  };
1155
1157
  };
1158
+ var getHealthEndpoint = (endpoint) => `http://${endpoint.host}:${endpoint.port}${CORE_HEALTH_PATH}`;
1156
1159
  var DriveSocket = class {
1157
1160
  constructor() {
1158
1161
  this.socket = null;
@@ -1209,6 +1212,16 @@ var DriveSocket = class {
1209
1212
  async connect() {
1210
1213
  const { endpoint, url } = await getWsEndpoint();
1211
1214
  this.connection.setEndpoint(endpoint);
1215
+ const health = await this.checkCoreHealth(endpoint);
1216
+ if (!health.ok) {
1217
+ this.connection.markDisconnected();
1218
+ this.recordConnectionFailure(
1219
+ "core unavailable",
1220
+ new Error(health.detail)
1221
+ );
1222
+ this.scheduleReconnect();
1223
+ return;
1224
+ }
1212
1225
  try {
1213
1226
  const socket2 = new WebSocket(url);
1214
1227
  this.socket = socket2;
@@ -1241,6 +1254,39 @@ var DriveSocket = class {
1241
1254
  this.scheduleReconnect();
1242
1255
  }
1243
1256
  }
1257
+ async checkCoreHealth(endpoint) {
1258
+ const controller = new AbortController();
1259
+ const timeoutId = self.setTimeout(() => {
1260
+ controller.abort();
1261
+ }, CORE_HEALTH_TIMEOUT_MS);
1262
+ try {
1263
+ const response = await fetch(getHealthEndpoint(endpoint), {
1264
+ method: "GET",
1265
+ cache: "no-store",
1266
+ signal: controller.signal
1267
+ });
1268
+ if (!response.ok) {
1269
+ return {
1270
+ ok: false,
1271
+ detail: `health returned HTTP ${response.status}`
1272
+ };
1273
+ }
1274
+ return { ok: true, detail: "ok" };
1275
+ } catch (error) {
1276
+ if (error instanceof DOMException && error.name === "AbortError") {
1277
+ return {
1278
+ ok: false,
1279
+ detail: `health timed out after ${CORE_HEALTH_TIMEOUT_MS}ms`
1280
+ };
1281
+ }
1282
+ return {
1283
+ ok: false,
1284
+ detail: error instanceof Error && error.message.length > 0 ? error.message : "health check failed"
1285
+ };
1286
+ } finally {
1287
+ clearTimeout(timeoutId);
1288
+ }
1289
+ }
1244
1290
  getConnectionStatus() {
1245
1291
  return this.connection.getStatus();
1246
1292
  }