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 +20 -4
- package/extension-template/manifest.json +1 -1
- package/macos-app/Info.plist +2 -2
- package/package.json +3 -2
- package/src/app-installer.js +16 -3
- package/src/cli.js +8 -4
- package/src/paths.js +14 -1
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.
|
|
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
|
|
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,
|
|
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&v=1" />
|
|
271
|
+
<source media="(prefers-color-scheme: light)" srcset="https://cookiebridge.apoorvdarshan.com/api/star-history.svg?theme=light&v=1" />
|
|
272
|
+
<img alt="Browser Cookie Bridge GitHub star history" src="https://cookiebridge.apoorvdarshan.com/api/star-history.svg?theme=light&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.
|
|
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"],
|
package/macos-app/Info.plist
CHANGED
|
@@ -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.
|
|
14
|
-
<key>CFBundleVersion</key><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.
|
|
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"
|
package/src/app-installer.js
CHANGED
|
@@ -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 {
|
|
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("
|
|
151
|
-
const destination = installApp({
|
|
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>${
|
|
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 &&
|
|
67
|
+
return isCurrentUser && isAppBundleWithIdentifier(systemApp) ? systemApp : userInstalledAppPath(home);
|
|
55
68
|
}
|
|
56
69
|
|
|
57
70
|
export function braveCookiePaths(home = os.homedir()) {
|