browser-cookie-bridge 1.3.0 → 1.4.0
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 +7 -5
- package/extension-template/manifest.json +1 -1
- package/macos-app/Info.plist +2 -2
- package/macos-app/Sources/BraveCodexSyncApp/BraveCodexSyncApp.swift +12 -0
- package/macos-app/Sources/BraveCodexSyncApp/SyncModel.swift +124 -3
- package/package.json +1 -1
- package/src/cli.js +4 -2
- package/src/config.js +3 -0
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
|
|
45
45
|
---
|
|
46
46
|
|
|
47
|
-
> **Version 1.
|
|
47
|
+
> **Version 1.4.0 adds an optional one-click Codex restart flow.** When enabled for a manual sync, Browser Cookie Bridge force quits Codex, waits for its database to close, performs the verified local transfer, preserves the imported/skipped/failed counts, and reopens Codex only after success. The option is off by default.
|
|
48
48
|
|
|
49
49
|
## Why Browser Cookie Bridge
|
|
50
50
|
|
|
@@ -57,6 +57,7 @@ Browser Cookie Bridge gives those browser profiles a small, native control panel
|
|
|
57
57
|
- 🍪 **Cookie and session transfer** — cookies are enabled by default, including supported domain, path, expiry, security, `SameSite`, and partition attributes.
|
|
58
58
|
- 🌐 **Seven Chromium browsers** — Brave, Chrome, Edge, Arc, Vivaldi, Opera, and Perplexity Comet can be sources or destinations.
|
|
59
59
|
- ✨ **ChatGPT Codex import** — merge selected local browser data into Codex's built-in browser; Codex is destination-only.
|
|
60
|
+
- 🔁 **Optional Codex restart** — manual Sync can force quit a running Codex instance and reopen it only after a successful local transfer; off by default.
|
|
60
61
|
- ☁️ **Optional Browserless upload** — create or refresh a Browserless authenticated profile with cookies, local storage, and IndexedDB; see a local size preflight, live progress, cancellation, and post-upload verification.
|
|
61
62
|
- 🕘 **Background automation** — sync when you sign in, at a fixed daily time, or whenever you choose.
|
|
62
63
|
- ◉ **Native menu-bar app** — closing the window removes the Dock icon while the helper continues running.
|
|
@@ -125,11 +126,11 @@ The final command compiles the native SwiftUI app, enables **Open at login**, **
|
|
|
125
126
|
No browser extension is needed for this path.
|
|
126
127
|
|
|
127
128
|
1. Select a source browser and **ChatGPT Codex** as the destination.
|
|
128
|
-
2. Quit Codex completely
|
|
129
|
+
2. Quit Codex completely, or enable **Restart Codex automatically**. Closing only its browser panel is not enough.
|
|
129
130
|
3. Choose **Cookies** and, optionally, **History URLs**.
|
|
130
|
-
4. Press **Sync now** and reopen Codex after the success message.
|
|
131
|
+
4. Press **Sync now** and reopen Codex after the success message if automatic restart is off.
|
|
131
132
|
|
|
132
|
-
|
|
133
|
+
By default, an open Codex blocks the transfer. The optional **Restart Codex automatically** setting applies only to a manual Sync: it force quits Codex, waits for its database to close, and reopens Codex only after the transfer succeeds. Scheduled and login syncs never force quit it.
|
|
133
134
|
|
|
134
135
|
### Browser → browser
|
|
135
136
|
|
|
@@ -171,6 +172,7 @@ The official CLI records the Browserless upload-disclaimer acceptance timestamp
|
|
|
171
172
|
| **Sync at login** | Runs once whenever you sign in; on by default |
|
|
172
173
|
| **Open at login** | Starts the background app after macOS login; on by default |
|
|
173
174
|
| **Show in menu bar** | Keeps sync, status, updates, and support actions close at hand |
|
|
175
|
+
| **Restart Codex automatically** | Force quits Codex for a manual sync and reopens it only after success; off by default |
|
|
174
176
|
| **Check for updates** | Finds a newer GitHub release, verifies its DMG, and offers install + relaunch |
|
|
175
177
|
|
|
176
178
|
Automation uses the saved source, destination, and data choices for local transfers. A scheduled Codex sync safely exits without making changes when Codex is open. Browserless cloud uploads are always manual and require an explicit upload action.
|
|
@@ -180,7 +182,7 @@ Automation uses the saved source, destination, and data choices for local transf
|
|
|
180
182
|
```bash
|
|
181
183
|
browser-cookie-bridge install-app [--no-open]
|
|
182
184
|
browser-cookie-bridge setup [--hour 9] [--minute 0] [--no-schedule]
|
|
183
|
-
browser-cookie-bridge preferences --source brave --target codex --cookies on --history off
|
|
185
|
+
browser-cookie-bridge preferences --source brave --target codex --cookies on --history off --auto-restart-codex off
|
|
184
186
|
browser-cookie-bridge sync [--timeout 300] [--allow-cloud-upload]
|
|
185
187
|
browser-cookie-bridge browserless-preflight
|
|
186
188
|
browser-cookie-bridge doctor
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"name": "Browser Cookie Bridge",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
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.
|
|
14
|
-
<key>CFBundleVersion</key><string>
|
|
13
|
+
<key>CFBundleShortVersionString</key><string>1.4.0</string>
|
|
14
|
+
<key>CFBundleVersion</key><string>28</string>
|
|
15
15
|
<key>LSMinimumSystemVersion</key><string>13.5</string>
|
|
16
16
|
<key>NSHighResolutionCapable</key><true/>
|
|
17
17
|
</dict>
|
|
@@ -578,6 +578,18 @@ struct PreferencesPanel: View {
|
|
|
578
578
|
PreferenceRow(icon: "key.slash", color: .secondary, title: "Passwords", detail: "Browser extensions cannot access passwords", muted: true) {
|
|
579
579
|
FixedBadge("Unavailable")
|
|
580
580
|
}
|
|
581
|
+
if model.selectedTargetID == "codex" {
|
|
582
|
+
RowDivider()
|
|
583
|
+
PreferenceRow(
|
|
584
|
+
icon: "arrow.clockwise.circle",
|
|
585
|
+
color: Theme.accent,
|
|
586
|
+
title: "Restart Codex automatically",
|
|
587
|
+
detail: "Force quit before manual sync; reopen only after success"
|
|
588
|
+
) {
|
|
589
|
+
Toggle("", isOn: Binding(get: { model.autoRestartCodex }, set: { model.setAutoRestartCodex($0) }))
|
|
590
|
+
.labelsHidden().toggleStyle(.switch).tint(Theme.active).disabled(model.isWorking || model.isSyncing)
|
|
591
|
+
}
|
|
592
|
+
}
|
|
581
593
|
}
|
|
582
594
|
|
|
583
595
|
SectionLabel(title: "Automation", detail: "Runs in the background", separated: true)
|
|
@@ -77,6 +77,7 @@ final class SyncModel: ObservableObject {
|
|
|
77
77
|
@Published var openAtLogin = false
|
|
78
78
|
@Published var menuBarEnabled = true
|
|
79
79
|
@Published var autoCheckUpdates = true
|
|
80
|
+
@Published var autoRestartCodex = false
|
|
80
81
|
@Published var isCheckingForUpdates = false
|
|
81
82
|
@Published var isInstallingUpdate = false
|
|
82
83
|
@Published var availableUpdateVersion: String?
|
|
@@ -128,7 +129,7 @@ final class SyncModel: ObservableObject {
|
|
|
128
129
|
var targetName: String {
|
|
129
130
|
isBrowserlessTarget ? "Browserless Cloud" : selectedTargetBrowser?.name ?? "ChatGPT Codex"
|
|
130
131
|
}
|
|
131
|
-
var codexBlocked: Bool { selectedTargetID == "codex" && codexRunning }
|
|
132
|
+
var codexBlocked: Bool { selectedTargetID == "codex" && codexRunning && !autoRestartCodex }
|
|
132
133
|
var browserlessBlocked: Bool {
|
|
133
134
|
isBrowserlessTarget && (!browserlessConfigured || sourceBrowserRunning || selectedSourceID == "comet")
|
|
134
135
|
}
|
|
@@ -261,6 +262,7 @@ final class SyncModel: ObservableObject {
|
|
|
261
262
|
historyEnabled = config.imports?.history ?? false
|
|
262
263
|
menuBarEnabled = config.ui?.menuBar ?? true
|
|
263
264
|
autoCheckUpdates = config.ui?.autoCheckUpdates ?? true
|
|
265
|
+
autoRestartCodex = config.ui?.autoRestartCodex ?? false
|
|
264
266
|
browserlessProfileName = config.browserless?.profileName ?? "browser-cookie-bridge"
|
|
265
267
|
browserlessRegion = config.browserless?.region ?? "sfo"
|
|
266
268
|
browserlessOnlyDomains = (config.browserless?.onlyDomains ?? []).joined(separator: ", ")
|
|
@@ -347,6 +349,11 @@ final class SyncModel: ObservableObject {
|
|
|
347
349
|
if enabled { checkForUpdates() }
|
|
348
350
|
}
|
|
349
351
|
|
|
352
|
+
func setAutoRestartCodex(_ enabled: Bool) {
|
|
353
|
+
autoRestartCodex = enabled
|
|
354
|
+
persistPreferences(successMessage: enabled ? "Automatic Codex restart enabled" : "Automatic Codex restart disabled")
|
|
355
|
+
}
|
|
356
|
+
|
|
350
357
|
func checkForUpdates(showAlert: Bool = false) {
|
|
351
358
|
guard !isCheckingForUpdates, !isInstallingUpdate else { return }
|
|
352
359
|
guard let url = URL(string: "https://api.github.com/repos/apoorvdarshan/browser-cookie-bridge/releases/latest") else { return }
|
|
@@ -449,6 +456,68 @@ final class SyncModel: ObservableObject {
|
|
|
449
456
|
}
|
|
450
457
|
return
|
|
451
458
|
}
|
|
459
|
+
if selectedTargetID == "codex" && codexRunning && autoRestartCodex {
|
|
460
|
+
forceQuitCodexThenSync(showMenuBarAlert: showMenuBarAlert)
|
|
461
|
+
return
|
|
462
|
+
}
|
|
463
|
+
startSync(showMenuBarAlert: showMenuBarAlert, reopenCodexOnSuccess: false)
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
private func forceQuitCodexThenSync(showMenuBarAlert: Bool) {
|
|
467
|
+
isSyncing = true
|
|
468
|
+
uploadCanceling = false
|
|
469
|
+
state = .syncing
|
|
470
|
+
primaryStatus = "Closing Codex for sync"
|
|
471
|
+
secondaryStatus = "Force quitting ChatGPT Codex and waiting for its browser database to close…"
|
|
472
|
+
let applications = NSWorkspace.shared.runningApplications.filter {
|
|
473
|
+
$0.bundleIdentifier == "com.openai.codex"
|
|
474
|
+
}
|
|
475
|
+
guard !applications.isEmpty, applications.allSatisfy({ $0.forceTerminate() }) else {
|
|
476
|
+
finishCodexPreparationFailure(
|
|
477
|
+
message: "macOS could not force quit ChatGPT Codex. Quit it manually, then try again.",
|
|
478
|
+
showMenuBarAlert: showMenuBarAlert
|
|
479
|
+
)
|
|
480
|
+
return
|
|
481
|
+
}
|
|
482
|
+
waitForCodexToQuit(attemptsRemaining: 50, showMenuBarAlert: showMenuBarAlert)
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
private func waitForCodexToQuit(attemptsRemaining: Int, showMenuBarAlert: Bool) {
|
|
486
|
+
let stillRunning = NSWorkspace.shared.runningApplications.contains {
|
|
487
|
+
$0.bundleIdentifier == "com.openai.codex"
|
|
488
|
+
}
|
|
489
|
+
if !stillRunning {
|
|
490
|
+
codexRunning = false
|
|
491
|
+
secondaryStatus = "Codex is closed — waiting briefly for its database to be released…"
|
|
492
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) { [weak self] in
|
|
493
|
+
self?.startSync(showMenuBarAlert: showMenuBarAlert, reopenCodexOnSuccess: true)
|
|
494
|
+
}
|
|
495
|
+
return
|
|
496
|
+
}
|
|
497
|
+
guard attemptsRemaining > 0 else {
|
|
498
|
+
finishCodexPreparationFailure(
|
|
499
|
+
message: "ChatGPT Codex did not close within 10 seconds. Quit it manually, then try again.",
|
|
500
|
+
showMenuBarAlert: showMenuBarAlert
|
|
501
|
+
)
|
|
502
|
+
return
|
|
503
|
+
}
|
|
504
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
|
|
505
|
+
self?.waitForCodexToQuit(attemptsRemaining: attemptsRemaining - 1, showMenuBarAlert: showMenuBarAlert)
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
private func finishCodexPreparationFailure(message: String, showMenuBarAlert: Bool) {
|
|
510
|
+
isSyncing = false
|
|
511
|
+
state = .error
|
|
512
|
+
primaryStatus = "Could not close Codex"
|
|
513
|
+
secondaryStatus = message
|
|
514
|
+
updateEndpointRunningStatus()
|
|
515
|
+
if showMenuBarAlert {
|
|
516
|
+
postNativeAlert(title: primaryStatus, message: secondaryStatus, kind: .error)
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
private func startSync(showMenuBarAlert: Bool, reopenCodexOnSuccess: Bool) {
|
|
452
521
|
isSyncing = true
|
|
453
522
|
uploadCanceling = false
|
|
454
523
|
state = .syncing
|
|
@@ -507,7 +576,13 @@ final class SyncModel: ObservableObject {
|
|
|
507
576
|
: "Keep both browsers open and check the extensions")
|
|
508
577
|
}
|
|
509
578
|
self.updateEndpointRunningStatus()
|
|
510
|
-
if
|
|
579
|
+
if success && reopenCodexOnSuccess {
|
|
580
|
+
self.reopenCodexAfterSuccessfulSync(
|
|
581
|
+
partial: partial,
|
|
582
|
+
syncSummary: self.secondaryStatus,
|
|
583
|
+
showMenuBarAlert: showMenuBarAlert
|
|
584
|
+
)
|
|
585
|
+
} else if showMenuBarAlert {
|
|
511
586
|
self.postNativeAlert(
|
|
512
587
|
title: self.primaryStatus,
|
|
513
588
|
message: self.secondaryStatus,
|
|
@@ -517,6 +592,44 @@ final class SyncModel: ObservableObject {
|
|
|
517
592
|
}
|
|
518
593
|
}
|
|
519
594
|
|
|
595
|
+
private func reopenCodexAfterSuccessfulSync(partial: Bool, syncSummary: String, showMenuBarAlert: Bool) {
|
|
596
|
+
let transferResult = syncSummary.replacingOccurrences(
|
|
597
|
+
of: "Reopen Codex to use the updated sessions. ",
|
|
598
|
+
with: ""
|
|
599
|
+
)
|
|
600
|
+
guard let codexURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.openai.codex") else {
|
|
601
|
+
state = .warning
|
|
602
|
+
primaryStatus = "Codex sessions updated, but Codex was not reopened"
|
|
603
|
+
secondaryStatus = "\(transferResult)\n\nCodex could not be found. Open it manually to use the updated sessions."
|
|
604
|
+
if showMenuBarAlert {
|
|
605
|
+
postNativeAlert(title: primaryStatus, message: secondaryStatus, kind: .warning)
|
|
606
|
+
}
|
|
607
|
+
return
|
|
608
|
+
}
|
|
609
|
+
NSWorkspace.shared.openApplication(at: codexURL, configuration: NSWorkspace.OpenConfiguration()) { [weak self] _, error in
|
|
610
|
+
Task { @MainActor in
|
|
611
|
+
guard let self else { return }
|
|
612
|
+
if let error {
|
|
613
|
+
self.state = .warning
|
|
614
|
+
self.primaryStatus = "Codex sessions updated, but Codex was not reopened"
|
|
615
|
+
self.secondaryStatus = "\(transferResult)\n\nCodex could not be reopened: \(error.localizedDescription)"
|
|
616
|
+
} else {
|
|
617
|
+
self.codexRunning = true
|
|
618
|
+
self.state = partial ? .warning : .success
|
|
619
|
+
self.primaryStatus = partial ? "Codex sync completed with warnings" : "Codex sessions updated"
|
|
620
|
+
self.secondaryStatus = "\(transferResult)\n\nChatGPT Codex reopened successfully."
|
|
621
|
+
}
|
|
622
|
+
if showMenuBarAlert {
|
|
623
|
+
self.postNativeAlert(
|
|
624
|
+
title: self.primaryStatus,
|
|
625
|
+
message: self.secondaryStatus,
|
|
626
|
+
kind: self.state == .success ? .information : .warning
|
|
627
|
+
)
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
520
633
|
func cancelSync() {
|
|
521
634
|
guard isBrowserlessTarget, isSyncing, !uploadCanceling else { return }
|
|
522
635
|
uploadCanceling = true
|
|
@@ -627,6 +740,7 @@ final class SyncModel: ObservableObject {
|
|
|
627
740
|
"--history", historyEnabled ? "on" : "off",
|
|
628
741
|
"--menu-bar", menuBarEnabled ? "on" : "off",
|
|
629
742
|
"--auto-check-updates", autoCheckUpdates ? "on" : "off",
|
|
743
|
+
"--auto-restart-codex", autoRestartCodex ? "on" : "off",
|
|
630
744
|
"--browserless-profile", browserlessProfileName,
|
|
631
745
|
"--browserless-region", browserlessRegion,
|
|
632
746
|
"--browserless-domains", browserlessOnlyDomains,
|
|
@@ -827,7 +941,13 @@ final class SyncModel: ObservableObject {
|
|
|
827
941
|
$0.bundleIdentifier == selectedBrowser.bundleIdentifier
|
|
828
942
|
}
|
|
829
943
|
guard !isSyncing else { return }
|
|
830
|
-
if selectedTargetID == "codex" && codexRunning {
|
|
944
|
+
if selectedTargetID == "codex" && codexRunning && autoRestartCodex {
|
|
945
|
+
if state == .ready || primaryStatus == "Quit Codex before syncing" {
|
|
946
|
+
state = .ready
|
|
947
|
+
primaryStatus = "Ready to sync and restart Codex"
|
|
948
|
+
secondaryStatus = "Sync will force quit Codex and reopen it only after a successful transfer"
|
|
949
|
+
}
|
|
950
|
+
} else if selectedTargetID == "codex" && codexRunning {
|
|
831
951
|
state = .warning
|
|
832
952
|
primaryStatus = "Quit Codex before syncing"
|
|
833
953
|
secondaryStatus = "Close ChatGPT Codex completely so its local cookie database can be updated safely"
|
|
@@ -948,6 +1068,7 @@ private struct AppConfig: Decodable {
|
|
|
948
1068
|
let menuBar: Bool?
|
|
949
1069
|
let openAtLogin: Bool?
|
|
950
1070
|
let autoCheckUpdates: Bool?
|
|
1071
|
+
let autoRestartCodex: Bool?
|
|
951
1072
|
}
|
|
952
1073
|
|
|
953
1074
|
struct BrowserlessSettings: Decodable {
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -45,7 +45,7 @@ Commands:
|
|
|
45
45
|
setup [--hour 9] [--minute 0] [--no-schedule]
|
|
46
46
|
install-app [--no-open]
|
|
47
47
|
bootstrap-bundled --app-path /Applications/Browser Cookie Bridge.app
|
|
48
|
-
preferences --source brave --target codex --cookies on --history off --menu-bar on --auto-check-updates on
|
|
48
|
+
preferences --source brave --target codex --cookies on --history off --menu-bar on --auto-check-updates on --auto-restart-codex off
|
|
49
49
|
sync [--timeout 300] [--allow-cloud-upload]
|
|
50
50
|
browserless-preflight
|
|
51
51
|
doctor
|
|
@@ -128,12 +128,13 @@ function preferences(args) {
|
|
|
128
128
|
menuBar: booleanFlag(args, "--menu-bar", existing.ui?.menuBar === true),
|
|
129
129
|
openAtLogin: booleanFlag(args, "--open-at-login", existing.ui?.openAtLogin !== false),
|
|
130
130
|
autoCheckUpdates: booleanFlag(args, "--auto-check-updates", existing.ui?.autoCheckUpdates !== false),
|
|
131
|
+
autoRestartCodex: booleanFlag(args, "--auto-restart-codex", existing.ui?.autoRestartCodex === true),
|
|
131
132
|
browserlessProfileName: stringFlag(args, "--browserless-profile", existing.browserless?.profileName || "browser-cookie-bridge"),
|
|
132
133
|
browserlessRegion: stringFlag(args, "--browserless-region", existing.browserless?.region || "sfo"),
|
|
133
134
|
browserlessOnlyDomains: optionalStringFlag(args, "--browserless-domains", (existing.browserless?.onlyDomains || []).join(",")),
|
|
134
135
|
});
|
|
135
136
|
console.log(
|
|
136
|
-
`Saved: source=${config.sourceBrowser}, target=${config.targetBrowser}, cookies=${config.imports.cookies ? "on" : "off"}, history=${config.imports.history ? "on" : "off"}, menu-bar=${config.ui.menuBar ? "on" : "off"}, open-at-login=${config.ui.openAtLogin ? "on" : "off"}, auto-check-updates=${config.ui.autoCheckUpdates ? "on" : "off"}`,
|
|
137
|
+
`Saved: source=${config.sourceBrowser}, target=${config.targetBrowser}, cookies=${config.imports.cookies ? "on" : "off"}, history=${config.imports.history ? "on" : "off"}, menu-bar=${config.ui.menuBar ? "on" : "off"}, open-at-login=${config.ui.openAtLogin ? "on" : "off"}, auto-check-updates=${config.ui.autoCheckUpdates ? "on" : "off"}, auto-restart-codex=${config.ui.autoRestartCodex ? "on" : "off"}`,
|
|
137
138
|
);
|
|
138
139
|
}
|
|
139
140
|
|
|
@@ -435,6 +436,7 @@ function setAppLogin(enabled) {
|
|
|
435
436
|
menuBar: existing.ui?.menuBar === true,
|
|
436
437
|
openAtLogin: enabled,
|
|
437
438
|
autoCheckUpdates: existing.ui?.autoCheckUpdates !== false,
|
|
439
|
+
autoRestartCodex: existing.ui?.autoRestartCodex === true,
|
|
438
440
|
browserlessProfileName: existing.browserless?.profileName,
|
|
439
441
|
browserlessRegion: existing.browserless?.region,
|
|
440
442
|
browserlessOnlyDomains: existing.browserless?.onlyDomains,
|
package/src/config.js
CHANGED
|
@@ -50,6 +50,7 @@ export function installConfig({ home, hour = 9, minute = 0, nodePath = process.e
|
|
|
50
50
|
menuBar: existing.ui?.menuBar !== false,
|
|
51
51
|
openAtLogin: existing.ui?.openAtLogin !== false,
|
|
52
52
|
autoCheckUpdates: existing.ui?.autoCheckUpdates !== false,
|
|
53
|
+
autoRestartCodex: existing.ui?.autoRestartCodex === true,
|
|
53
54
|
},
|
|
54
55
|
browserless: {
|
|
55
56
|
profileName: cleanProfileName(existing.browserless?.profileName) || "browser-cookie-bridge",
|
|
@@ -77,6 +78,7 @@ export function updatePreferences({
|
|
|
77
78
|
menuBar,
|
|
78
79
|
openAtLogin,
|
|
79
80
|
autoCheckUpdates,
|
|
81
|
+
autoRestartCodex,
|
|
80
82
|
browserlessProfileName,
|
|
81
83
|
browserlessRegion,
|
|
82
84
|
browserlessOnlyDomains,
|
|
@@ -98,6 +100,7 @@ export function updatePreferences({
|
|
|
98
100
|
menuBar: Boolean(menuBar),
|
|
99
101
|
openAtLogin: Boolean(openAtLogin),
|
|
100
102
|
autoCheckUpdates: Boolean(autoCheckUpdates),
|
|
103
|
+
autoRestartCodex: Boolean(autoRestartCodex),
|
|
101
104
|
};
|
|
102
105
|
const region = browserlessRegion ?? config.browserless?.region ?? "sfo";
|
|
103
106
|
if (!["sfo", "lon", "ams"].includes(region)) throw new Error("Browserless region must be sfo, lon, or ams");
|