browser-cookie-bridge 1.4.0 → 1.4.2

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/README.md CHANGED
@@ -16,6 +16,7 @@
16
16
  <img src="https://img.shields.io/badge/local--first-cloud%20optional-C68B3C" alt="Local-first, cloud optional" />
17
17
  <img src="https://img.shields.io/github/stars/apoorvdarshan/browser-cookie-bridge?logo=github&color=C68B3C" alt="GitHub stars" />
18
18
  <a href="https://www.producthunt.com/products/browser-cookie-bridge"><img src="https://img.shields.io/badge/Product%20Hunt-View%20launch-DA552F?logo=producthunt&logoColor=white" alt="Browser Cookie Bridge on Product Hunt" /></a>
19
+ <a href="https://tally.so/r/J9j0D4"><img src="https://img.shields.io/badge/Windows-Join%20waitlist-8E2735?logo=windows&logoColor=white" alt="Join the Browser Cookie Bridge Windows waitlist" /></a>
19
20
  <img src="https://img.shields.io/badge/license-MIT-3DA639" alt="MIT License" />
20
21
  </p>
21
22
 
@@ -28,6 +29,7 @@
28
29
  <a href="CONTRIBUTING.md">Contribute</a> ·
29
30
  <a href="https://github.com/apoorvdarshan/browser-cookie-bridge/issues/new?template=bug_report.yml">Report a bug</a> ·
30
31
  <a href="https://www.producthunt.com/products/browser-cookie-bridge">Product Hunt</a> ·
32
+ <a href="https://tally.so/r/J9j0D4">Windows waitlist</a> ·
31
33
  <a href="#support">Support</a>
32
34
  </p>
33
35
 
@@ -52,6 +54,10 @@ Signing into the same sites across several browsers is repetitive. Export files
52
54
 
53
55
  Browser Cookie Bridge gives those browser profiles a small, native control panel. Local browser and Codex transfers stay on the Mac. If you explicitly select Browserless Cloud and click Upload, the app can instead send authenticated profile state to your own Browserless account.
54
56
 
57
+ ## Windows waitlist
58
+
59
+ Browser Cookie Bridge currently ships for macOS. A separate Windows app is being explored, with demand guiding whether it moves into active development. If you use Windows, [join the early-access waitlist](https://tally.so/r/J9j0D4) and tell us which browsers and transfer paths matter to you.
60
+
55
61
  ## Features
56
62
 
57
63
  - 🍪 **Cookie and session transfer** — cookies are enabled by default, including supported domain, path, expiry, security, `SameSite`, and partition attributes.
@@ -92,7 +98,7 @@ The DMG is self-contained. Node.js 24+ and Xcode Command Line Tools are required
92
98
  - **[Apple silicon DMG](https://github.com/apoorvdarshan/browser-cookie-bridge/releases/latest/download/Browser-Cookie-Bridge-arm64.dmg)** — M1, M2, M3, M4, and newer
93
99
  - **[Intel DMG](https://github.com/apoorvdarshan/browser-cookie-bridge/releases/latest/download/Browser-Cookie-Bridge-x64.dmg)** — Intel-based Macs
94
100
 
95
- Open the DMG, drag **Browser Cookie Bridge** onto **Applications**, then open it from Applications. The current public build is checksum-verified and ad-hoc signed but not Apple-notarized, so macOS may require **Control-click Open** on first launch. It does not require Node.js, Xcode, Terminal, or an administrator password.
101
+ Open the DMG, drag **Browser Cookie Bridge** onto **Applications**, then open it from Applications. Current DMGs are checksum-verified, Developer ID-signed, and Apple-notarized for a standard macOS first-launch experience. The app does not require Node.js, Xcode, Terminal, or an administrator password.
96
102
 
97
103
  ### Via npm
98
104
 
@@ -102,7 +108,7 @@ Run the published package directly:
102
108
  npx browser-cookie-bridge install-app
103
109
  ```
104
110
 
105
- No administrator password is needed. The app is built from source on your Mac and installed in your user Applications folder unless an existing writable system Applications copy is being updated.
111
+ No administrator password is needed. The app is built from source on your Mac and installed in your user Applications folder. If a signed `/Applications/Browser Cookie Bridge.app` already exists, the CLI preserves it instead of replacing its Developer ID signature with an ad-hoc local build; use the app's built-in updater for signed releases.
106
112
 
107
113
  Both installation methods use the same bundle identifier and the same settings under `~/Library/Application Support/BraveCodexCookieSync`. Installing the DMG after npm does not create a separate product identity: the system Applications copy becomes canonical, and a stale matching user Applications copy is moved to the Trash on launch. Future updates replace that same app in place.
108
114
 
@@ -117,7 +123,7 @@ npm test
117
123
  npm run build:app
118
124
  ```
119
125
 
120
- The final command compiles the native SwiftUI app, enables **Open at login**, **Sync at login**, and the **menu-bar helper**, then launches it. A first install uses `~/Applications/Browser Cookie Bridge.app` without requesting administrator access. If an existing `/Applications/Browser Cookie Bridge.app` is present, later builds and updates keep using that system Applications copy instead of creating a duplicate. Daily sync stays off until you enable it.
126
+ The final command compiles the native SwiftUI app, enables **Open at login**, **Sync at login**, and the **menu-bar helper**, then launches it. A first install uses `~/Applications/Browser Cookie Bridge.app` without requesting administrator access. If an existing signed `/Applications/Browser Cookie Bridge.app` is present, the CLI keeps that system copy canonical and leaves app updates to the signed-DMG updater. Developers who intentionally need to replace it with a local ad-hoc build can pass `--replace-system-from-source`. Daily sync stays off until you enable it.
121
127
 
122
128
  ## Setup
123
129
 
@@ -180,7 +186,7 @@ Automation uses the saved source, destination, and data choices for local transf
180
186
  ## CLI
181
187
 
182
188
  ```bash
183
- browser-cookie-bridge install-app [--no-open]
189
+ browser-cookie-bridge install-app [--no-open] [--replace-system-from-source]
184
190
  browser-cookie-bridge setup [--hour 9] [--minute 0] [--no-schedule]
185
191
  browser-cookie-bridge preferences --source brave --target codex --cookies on --history off --auto-restart-codex off
186
192
  browser-cookie-bridge sync [--timeout 300] [--allow-cloud-upload]
@@ -257,6 +263,16 @@ The product landing page, documentation overview, Privacy Policy, and Terms are
257
263
  npm run web
258
264
  ```
259
265
 
266
+ ## Star History
267
+
268
+ <a href="https://github.com/apoorvdarshan/browser-cookie-bridge/stargazers">
269
+ <picture>
270
+ <source media="(prefers-color-scheme: dark)" srcset="https://cookiebridge.apoorvdarshan.com/api/star-history.svg?theme=dark&amp;v=1" />
271
+ <source media="(prefers-color-scheme: light)" srcset="https://cookiebridge.apoorvdarshan.com/api/star-history.svg?theme=light&amp;v=1" />
272
+ <img alt="Browser Cookie Bridge GitHub star history" src="https://cookiebridge.apoorvdarshan.com/api/star-history.svg?theme=light&amp;v=1" />
273
+ </picture>
274
+ </a>
275
+
260
276
  ## License
261
277
 
262
278
  [MIT](LICENSE) © 2026 [Apoorv Darshan](https://github.com/apoorvdarshan)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Browser Cookie Bridge",
4
- "version": "1.4.0",
4
+ "version": "1.4.2",
5
5
  "description": "Transfers selected browser data locally between supported browsers and into ChatGPT Codex.",
6
6
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5o6lDkXzU/23Jm2QRk4mfuxNnr3VlEIjRHcZr93Gdo7PI7asHJQhigaMGT6UOz0lkaTn1F+TGIPlsJo9GNBSsxbCfxWoBSXcFQFrPolY5LEfKaMtZQQ6eb4UAnp+bbUwb1den4On0piWU47Yzl6i0Jcdg4EG5H1kCSF/6nJsbKgF7OTaR/3drULu40yRvflzSXRhly3UDO7c5mgHJsaMwVV+VILsxbcPOoRINjuo3zDC737HFs67dpf38xF3tjSVL0HURAWKKobMvfABiDfVEm5O0Lvf+57d1Ib12QLT2qtVXNDy3iYwX+w2S0wH2vIMsfvoFPlRdmeqft70kZOqXwIDAQAB",
7
7
  "permissions": ["alarms", "cookies", "history"],
@@ -10,8 +10,8 @@
10
10
  <key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
11
11
  <key>CFBundleName</key><string>Browser Cookie Bridge</string>
12
12
  <key>CFBundlePackageType</key><string>APPL</string>
13
- <key>CFBundleShortVersionString</key><string>1.4.0</string>
14
- <key>CFBundleVersion</key><string>28</string>
13
+ <key>CFBundleShortVersionString</key><string>1.4.2</string>
14
+ <key>CFBundleVersion</key><string>30</string>
15
15
  <key>LSMinimumSystemVersion</key><string>13.5</string>
16
16
  <key>NSHighResolutionCapable</key><true/>
17
17
  </dict>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-cookie-bridge",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Local-first cookie and session transfer for macOS with optional Browserless upload",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,9 +8,10 @@
8
8
  },
9
9
  "scripts": {
10
10
  "test": "node --test test/*.test.js",
11
+ "test:web-worker": "node --test web/worker/*.test.mjs",
11
12
  "check": "node --check bin/brave-codex-cookie-sync.js && node --check src/app-installer.js && node --check src/browserless.js && node --check src/browserless-preflight.js && node --check src/browserless-runner.js && node --check src/broker.js && node --check src/chromium-reader.js && node --check src/cli.js && node --check src/codex-direct-import.js && node --check src/config.js && node --check src/paths.js && node --check src/scheduler.js && node --check src/updater.js && node --check scripts/build-dmg.js && node --check extension-template/background.js && node --check web/server.js && node --check web/script.js",
12
13
  "release:check": "node scripts/check-release-version.js",
13
- "build:app": "node bin/brave-codex-cookie-sync.js install-app --no-open",
14
+ "build:app": "node bin/brave-codex-cookie-sync.js install-app --no-open --replace-system-from-source",
14
15
  "build:dmg": "node scripts/build-dmg.js",
15
16
  "web": "node web/server.js",
16
17
  "web:deploy": "wrangler deploy --config web/wrangler.jsonc"
@@ -2,11 +2,25 @@ import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import { spawnSync } from "node:child_process";
5
- import { appSupportDir, installedAppPath, projectRoot } from "./paths.js";
5
+ import {
6
+ appSupportDir,
7
+ installedAppPath,
8
+ projectRoot,
9
+ systemInstalledAppPath,
10
+ } from "./paths.js";
6
11
 
7
- export function installApp({ home = os.homedir(), open = true } = {}) {
12
+ export function installApp({ home = os.homedir(), open = true, preserveSystemApp = true } = {}) {
8
13
  if (process.platform !== "darwin") throw new Error("The desktop app supports macOS only.");
9
14
 
15
+ const destination = installedAppPath(home);
16
+ const isSystemInstall = path.resolve(destination) === path.resolve(systemInstalledAppPath());
17
+ if (isSystemInstall && preserveSystemApp) {
18
+ console.log(`Preserving the signed installation at ${destination}`);
19
+ console.log("Use Check for Updates in the app to install signed releases.");
20
+ if (open) run("open", [destination]);
21
+ return destination;
22
+ }
23
+
10
24
  const packagePath = path.join(projectRoot(), "macos-app");
11
25
  run("swift", ["build", "-c", "release", "--package-path", packagePath]);
12
26
  const binPath = run("swift", [
@@ -32,7 +46,6 @@ export function installApp({ home = os.homedir(), open = true } = {}) {
32
46
 
33
47
  run("codesign", ["--force", "--deep", "--sign", "-", staging]);
34
48
 
35
- const destination = installedAppPath(home);
36
49
  fs.mkdirSync(path.dirname(destination), { recursive: true, mode: 0o755 });
37
50
  fs.rmSync(destination, { recursive: true, force: true });
38
51
  fs.cpSync(staging, destination, { recursive: true, force: true });
package/src/cli.js CHANGED
@@ -24,6 +24,7 @@ import {
24
24
  systemInstalledAppPath,
25
25
  userInstalledAppPath,
26
26
  APP_ID,
27
+ APP_BUNDLE_ID,
27
28
  SOURCE_BROWSERS,
28
29
  TARGET_BROWSERS,
29
30
  } from "./paths.js";
@@ -43,7 +44,7 @@ Local cookie and session transfer between Chromium browsers and into ChatGPT Cod
43
44
 
44
45
  Commands:
45
46
  setup [--hour 9] [--minute 0] [--no-schedule]
46
- install-app [--no-open]
47
+ install-app [--no-open] [--replace-system-from-source]
47
48
  bootstrap-bundled --app-path /Applications/Browser Cookie Bridge.app
48
49
  preferences --source brave --target codex --cookies on --history off --menu-bar on --auto-check-updates on --auto-restart-codex off
49
50
  sync [--timeout 300] [--allow-cloud-upload]
@@ -147,8 +148,11 @@ function installDesktopApp(args) {
147
148
  hour: existing?.schedule?.hour ?? 9,
148
149
  minute: existing?.schedule?.minute ?? 0,
149
150
  });
150
- console.log("Building the native macOS app…");
151
- const destination = installApp({ open: !args.includes("--no-open") });
151
+ console.log("Preparing the native macOS app…");
152
+ const destination = installApp({
153
+ open: !args.includes("--no-open"),
154
+ preserveSystemApp: !args.includes("--replace-system-from-source"),
155
+ });
152
156
  if (config.ui.openAtLogin) {
153
157
  installAppLogin({ appPath: destination, bootstrapNow: false });
154
158
  } else {
@@ -214,7 +218,7 @@ function archiveDuplicateUserApp(currentAppPath) {
214
218
  if (!fs.existsSync(duplicate)) return;
215
219
  const infoPath = path.join(duplicate, "Contents", "Info.plist");
216
220
  const info = fs.existsSync(infoPath) ? fs.readFileSync(infoPath, "utf8") : "";
217
- if (!info.includes(`<string>${APP_ID}</string>`)) return;
221
+ if (!info.includes(`<string>${APP_BUNDLE_ID}</string>`)) return;
218
222
 
219
223
  const trash = path.join(os.homedir(), ".Trash");
220
224
  fs.mkdirSync(trash, { recursive: true, mode: 0o700 });
package/src/paths.js CHANGED
@@ -4,6 +4,7 @@ import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
 
6
6
  export const APP_ID = "com.apoorvdarshan.brave-codex-cookie-sync";
7
+ export const APP_BUNDLE_ID = "com.apoorvdarshan.browser-cookie-bridge";
7
8
  export const LOGIN_SYNC_APP_ID = `${APP_ID}.login-sync`;
8
9
  export const APP_LOGIN_APP_ID = `${APP_ID}.app-login`;
9
10
  export const DEFAULT_PORT = 43128;
@@ -48,10 +49,22 @@ export function systemInstalledAppPath() {
48
49
  return path.join("/Applications", "Browser Cookie Bridge.app");
49
50
  }
50
51
 
52
+ export function isAppBundleWithIdentifier(appPath, identifier = APP_BUNDLE_ID) {
53
+ const infoPath = path.join(appPath, "Contents", "Info.plist");
54
+ if (!fs.existsSync(infoPath)) return false;
55
+ try {
56
+ const info = fs.readFileSync(infoPath, "utf8");
57
+ const escaped = identifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
58
+ return new RegExp(`<key>CFBundleIdentifier</key>\\s*<string>${escaped}</string>`).test(info);
59
+ } catch {
60
+ return false;
61
+ }
62
+ }
63
+
51
64
  export function installedAppPath(home = os.homedir()) {
52
65
  const systemApp = systemInstalledAppPath();
53
66
  const isCurrentUser = path.resolve(home) === path.resolve(os.homedir());
54
- return isCurrentUser && fs.existsSync(systemApp) ? systemApp : userInstalledAppPath(home);
67
+ return isCurrentUser && isAppBundleWithIdentifier(systemApp) ? systemApp : userInstalledAppPath(home);
55
68
  }
56
69
 
57
70
  export function braveCookiePaths(home = os.homedir()) {