@btraut/browser-bridge 0.11.1 → 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.
@@ -6,11 +6,37 @@
6
6
  if (!el) {
7
7
  throw new Error(`Missing element: ${id}`);
8
8
  }
9
- if (!(el instanceof HTMLAnchorElement)) {
10
- throw new Error(`Expected <a> element: ${id}`);
11
- }
12
9
  return el;
13
10
  };
11
+ var setConnectedIndicator = (state) => {
12
+ const connected = state === "connected";
13
+ const indicator = byId("bb-conn-indicator");
14
+ indicator.setAttribute("data-connected", connected ? "true" : "false");
15
+ indicator.setAttribute(
16
+ "aria-label",
17
+ connected ? "Connected" : "Disconnected"
18
+ );
19
+ indicator.setAttribute("title", connected ? "Connected" : state);
20
+ };
21
+ var getConnectionStatus = async () => {
22
+ const response = await new Promise(
23
+ (resolve) => {
24
+ chrome.runtime.sendMessage(
25
+ { action: "drive.connection_status" },
26
+ (message) => {
27
+ resolve(message);
28
+ }
29
+ );
30
+ }
31
+ );
32
+ if (!response?.ok || !response.result) {
33
+ throw new Error("Connection status is unavailable.");
34
+ }
35
+ return response.result;
36
+ };
37
+ var renderStatus = (status) => {
38
+ setConnectedIndicator(status.state);
39
+ };
14
40
  var openOptionsPopupWindow = async () => {
15
41
  const chromeAny = chrome;
16
42
  const url = chromeAny.runtime.getURL("options.html");
@@ -53,6 +79,20 @@
53
79
  window.open(url, "_blank", "noopener");
54
80
  };
55
81
  var main = () => {
82
+ const refreshStatus = async () => {
83
+ try {
84
+ const status = await getConnectionStatus();
85
+ renderStatus(status);
86
+ } catch {
87
+ renderStatus({ state: "disconnected" });
88
+ }
89
+ };
90
+ const interval = window.setInterval(() => {
91
+ void refreshStatus();
92
+ }, 1500);
93
+ window.addEventListener("unload", () => {
94
+ clearInterval(interval);
95
+ });
56
96
  byId("bb-settings").addEventListener("click", (e) => {
57
97
  e.preventDefault();
58
98
  void openOptionsPopupWindow().finally(() => window.close());
@@ -61,6 +101,7 @@
61
101
  e.preventDefault();
62
102
  void openGithub().finally(() => window.close());
63
103
  });
104
+ void refreshStatus();
64
105
  };
65
106
  main();
66
107
  })();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/popup-ui.ts"],
4
- "sourcesContent": ["const byId = (id: string): HTMLAnchorElement => {\n const el = document.getElementById(id);\n if (!el) {\n throw new Error(`Missing element: ${id}`);\n }\n if (!(el instanceof HTMLAnchorElement)) {\n throw new Error(`Expected <a> element: ${id}`);\n }\n return el;\n};\n\nconst openOptionsPopupWindow = async (): Promise<void> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const chromeAny = chrome as any;\n const url = chromeAny.runtime.getURL('options.html');\n\n // Prefer a dedicated popup window so the options UI isn't crushed inside the toolbar popup.\n if (chromeAny.windows?.create) {\n await new Promise<void>((resolve) => {\n chromeAny.windows.create(\n {\n type: 'popup',\n url,\n focused: true,\n width: 900,\n height: 720,\n },\n () => resolve()\n );\n });\n return;\n }\n\n // Fallbacks for environments where `chrome.windows` isn't available.\n if (chromeAny.runtime?.openOptionsPage) {\n await chromeAny.runtime.openOptionsPage();\n return;\n }\n if (chromeAny.tabs?.create) {\n await new Promise<void>((resolve) => {\n chromeAny.tabs.create({ url }, () => resolve());\n });\n return;\n }\n\n window.open(url, '_blank', 'noopener');\n};\n\nconst openGithub = async (): Promise<void> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const chromeAny = chrome as any;\n const url = 'https://github.com/btraut/browser-bridge';\n if (chromeAny.tabs?.create) {\n await new Promise<void>((resolve) => {\n chromeAny.tabs.create({ url }, () => resolve());\n });\n return;\n }\n window.open(url, '_blank', 'noopener');\n};\n\nconst main = (): void => {\n byId('bb-settings').addEventListener('click', (e) => {\n e.preventDefault();\n void openOptionsPopupWindow().finally(() => window.close());\n });\n byId('bb-about').addEventListener('click', (e) => {\n e.preventDefault();\n void openGithub().finally(() => window.close());\n });\n};\n\nmain();\n\n// Make this file a module (avoid global name collisions across UI entrypoints).\nexport {};\n"],
5
- "mappings": ";;;AAAA,MAAM,OAAO,CAAC,OAAkC;AAC9C,UAAM,KAAK,SAAS,eAAe,EAAE;AACrC,QAAI,CAAC,IAAI;AACP,YAAM,IAAI,MAAM,oBAAoB,EAAE,EAAE;AAAA,IAC1C;AACA,QAAI,EAAE,cAAc,oBAAoB;AACtC,YAAM,IAAI,MAAM,yBAAyB,EAAE,EAAE;AAAA,IAC/C;AACA,WAAO;AAAA,EACT;AAEA,MAAM,yBAAyB,YAA2B;AAExD,UAAM,YAAY;AAClB,UAAM,MAAM,UAAU,QAAQ,OAAO,cAAc;AAGnD,QAAI,UAAU,SAAS,QAAQ;AAC7B,YAAM,IAAI,QAAc,CAAC,YAAY;AACnC,kBAAU,QAAQ;AAAA,UAChB;AAAA,YACE,MAAM;AAAA,YACN;AAAA,YACA,SAAS;AAAA,YACT,OAAO;AAAA,YACP,QAAQ;AAAA,UACV;AAAA,UACA,MAAM,QAAQ;AAAA,QAChB;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAGA,QAAI,UAAU,SAAS,iBAAiB;AACtC,YAAM,UAAU,QAAQ,gBAAgB;AACxC;AAAA,IACF;AACA,QAAI,UAAU,MAAM,QAAQ;AAC1B,YAAM,IAAI,QAAc,CAAC,YAAY;AACnC,kBAAU,KAAK,OAAO,EAAE,IAAI,GAAG,MAAM,QAAQ,CAAC;AAAA,MAChD,CAAC;AACD;AAAA,IACF;AAEA,WAAO,KAAK,KAAK,UAAU,UAAU;AAAA,EACvC;AAEA,MAAM,aAAa,YAA2B;AAE5C,UAAM,YAAY;AAClB,UAAM,MAAM;AACZ,QAAI,UAAU,MAAM,QAAQ;AAC1B,YAAM,IAAI,QAAc,CAAC,YAAY;AACnC,kBAAU,KAAK,OAAO,EAAE,IAAI,GAAG,MAAM,QAAQ,CAAC;AAAA,MAChD,CAAC;AACD;AAAA,IACF;AACA,WAAO,KAAK,KAAK,UAAU,UAAU;AAAA,EACvC;AAEA,MAAM,OAAO,MAAY;AACvB,SAAK,aAAa,EAAE,iBAAiB,SAAS,CAAC,MAAM;AACnD,QAAE,eAAe;AACjB,WAAK,uBAAuB,EAAE,QAAQ,MAAM,OAAO,MAAM,CAAC;AAAA,IAC5D,CAAC;AACD,SAAK,UAAU,EAAE,iBAAiB,SAAS,CAAC,MAAM;AAChD,QAAE,eAAe;AACjB,WAAK,WAAW,EAAE,QAAQ,MAAM,OAAO,MAAM,CAAC;AAAA,IAChD,CAAC;AAAA,EACH;AAEA,OAAK;",
4
+ "sourcesContent": ["type DriveConnectionState =\n | 'connecting'\n | 'connected'\n | 'disconnected'\n | 'backoff';\n\ntype DriveConnectionStatus = {\n state: DriveConnectionState;\n};\n\ntype DriveConnectionStatusResponse = {\n ok: boolean;\n result?: DriveConnectionStatus;\n};\n\nconst byId = <T extends HTMLElement>(id: string): T => {\n const el = document.getElementById(id);\n if (!el) {\n throw new Error(`Missing element: ${id}`);\n }\n return el as T;\n};\n\nconst setConnectedIndicator = (state: DriveConnectionState): void => {\n const connected = state === 'connected';\n const indicator = byId<HTMLElement>('bb-conn-indicator');\n indicator.setAttribute('data-connected', connected ? 'true' : 'false');\n indicator.setAttribute(\n 'aria-label',\n connected ? 'Connected' : 'Disconnected'\n );\n indicator.setAttribute('title', connected ? 'Connected' : state);\n};\n\nconst getConnectionStatus = async (): Promise<DriveConnectionStatus> => {\n const response = await new Promise<DriveConnectionStatusResponse>(\n (resolve) => {\n chrome.runtime.sendMessage(\n { action: 'drive.connection_status' },\n (message: DriveConnectionStatusResponse) => {\n resolve(message);\n }\n );\n }\n );\n\n if (!response?.ok || !response.result) {\n throw new Error('Connection status is unavailable.');\n }\n\n return response.result;\n};\n\nconst renderStatus = (status: DriveConnectionStatus): void => {\n setConnectedIndicator(status.state);\n};\n\nconst openOptionsPopupWindow = async (): Promise<void> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const chromeAny = chrome as any;\n const url = chromeAny.runtime.getURL('options.html');\n\n if (chromeAny.windows?.create) {\n await new Promise<void>((resolve) => {\n chromeAny.windows.create(\n {\n type: 'popup',\n url,\n focused: true,\n width: 900,\n height: 720,\n },\n () => resolve()\n );\n });\n return;\n }\n\n if (chromeAny.runtime?.openOptionsPage) {\n await chromeAny.runtime.openOptionsPage();\n return;\n }\n if (chromeAny.tabs?.create) {\n await new Promise<void>((resolve) => {\n chromeAny.tabs.create({ url }, () => resolve());\n });\n return;\n }\n\n window.open(url, '_blank', 'noopener');\n};\n\nconst openGithub = async (): Promise<void> => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const chromeAny = chrome as any;\n const url = 'https://github.com/btraut/browser-bridge';\n if (chromeAny.tabs?.create) {\n await new Promise<void>((resolve) => {\n chromeAny.tabs.create({ url }, () => resolve());\n });\n return;\n }\n window.open(url, '_blank', 'noopener');\n};\n\nconst main = (): void => {\n const refreshStatus = async (): Promise<void> => {\n try {\n const status = await getConnectionStatus();\n renderStatus(status);\n } catch {\n renderStatus({ state: 'disconnected' });\n }\n };\n\n const interval = window.setInterval(() => {\n void refreshStatus();\n }, 1500);\n\n window.addEventListener('unload', () => {\n clearInterval(interval);\n });\n\n byId<HTMLAnchorElement>('bb-settings').addEventListener('click', (e) => {\n e.preventDefault();\n void openOptionsPopupWindow().finally(() => window.close());\n });\n\n byId<HTMLAnchorElement>('bb-about').addEventListener('click', (e) => {\n e.preventDefault();\n void openGithub().finally(() => window.close());\n });\n\n void refreshStatus();\n};\n\nmain();\n\nexport {};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Browser Bridge",
4
- "version": "0.11.1",
4
+ "version": "0.12.1",
5
5
  "description": "Control Chrome for Browser Bridge: drive tabs and inspect pages for coding agents.",
6
6
  "icons": {
7
7
  "16": "assets/icons/icon-16.png",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btraut/browser-bridge",
3
- "version": "0.11.1",
3
+ "version": "0.12.1",
4
4
  "license": "MIT",
5
5
  "engines": {
6
6
  "node": ">=20"
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "browser-bridge",
3
- "version": "0.11.1"
3
+ "version": "0.12.1"
4
4
  }