browser-cookie-bridge 1.4.4 → 1.4.6

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Browser Cookie Bridge",
4
- "version": "1.4.4",
4
+ "version": "1.4.6",
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.4</string>
14
- <key>CFBundleVersion</key><string>32</string>
13
+ <key>CFBundleShortVersionString</key><string>1.4.6</string>
14
+ <key>CFBundleVersion</key><string>34</string>
15
15
  <key>LSMinimumSystemVersion</key><string>13.5</string>
16
16
  <key>NSHighResolutionCapable</key><true/>
17
17
  </dict>
@@ -118,6 +118,7 @@ final class SyncModel: ObservableObject {
118
118
  private var activeSyncProcess: Process?
119
119
  private var uploadTimer: Timer?
120
120
  private var uploadStartedAt: Date?
121
+ private var runtimeReady = true
121
122
 
122
123
  var selectedBrowser: BrowserChoice {
123
124
  browsers.first(where: { $0.id == selectedSourceID }) ?? browsers[0]
@@ -140,7 +141,7 @@ final class SyncModel: ObservableObject {
140
141
  var browserlessBlocked: Bool {
141
142
  isBrowserlessTarget && (!browserlessConfigured || sourceBrowserRunning || selectedSourceID == "comet")
142
143
  }
143
- var syncBlocked: Bool { codexBlocked || sourceSiteDataBlocked || browserlessBlocked }
144
+ var syncBlocked: Bool { !runtimeReady || codexBlocked || sourceSiteDataBlocked || browserlessBlocked }
144
145
  var formattedUploadElapsed: String {
145
146
  let minutes = uploadElapsedSeconds / 60
146
147
  let seconds = uploadElapsedSeconds % 60
@@ -185,7 +186,7 @@ final class SyncModel: ObservableObject {
185
186
  }
186
187
 
187
188
  init() {
188
- bootstrapBundledRuntimeIfNeeded()
189
+ runtimeReady = bootstrapBundledRuntimeIfNeeded()
189
190
  let calendar = Calendar.current
190
191
  scheduleTime = calendar.date(bySettingHour: 9, minute: 0, second: 0, of: Date()) ?? Date()
191
192
  updateEndpointRunningStatus()
@@ -201,19 +202,19 @@ final class SyncModel: ObservableObject {
201
202
  }
202
203
  }
203
204
 
204
- private func bootstrapBundledRuntimeIfNeeded() {
205
- guard let resources = Bundle.main.resourceURL else { return }
205
+ private func bootstrapBundledRuntimeIfNeeded() -> Bool {
206
+ guard let resources = Bundle.main.resourceURL else { return true }
206
207
  let bundledRuntime = resources.appending(path: "runtime")
207
208
  let bundledNode = bundledRuntime.appending(path: "node/bin/node")
208
209
  let bundledCLI = bundledRuntime.appending(path: "bin/brave-codex-cookie-sync.js")
209
210
  guard FileManager.default.isExecutableFile(atPath: bundledNode.path),
210
- FileManager.default.fileExists(atPath: bundledCLI.path) else { return }
211
+ FileManager.default.fileExists(atPath: bundledCLI.path) else { return true }
211
212
 
212
213
  if Bundle.main.bundlePath.hasPrefix("/Volumes/") {
213
214
  state = .warning
214
215
  primaryStatus = "Move the app to Applications"
215
216
  secondaryStatus = "Drag Browser Cookie Bridge onto Applications in the DMG window, then open it there"
216
- return
217
+ return false
217
218
  }
218
219
 
219
220
  let process = Process()
@@ -230,7 +231,7 @@ final class SyncModel: ObservableObject {
230
231
  do {
231
232
  try process.run()
232
233
  process.waitUntilExit()
233
- guard process.terminationStatus != 0 else { return }
234
+ guard process.terminationStatus != 0 else { return true }
234
235
  let data = output.fileHandleForReading.readDataToEndOfFile()
235
236
  let message = String(decoding: data, as: UTF8.self)
236
237
  .split(separator: "\n")
@@ -239,10 +240,12 @@ final class SyncModel: ObservableObject {
239
240
  state = .error
240
241
  primaryStatus = "Could not prepare the local runtime"
241
242
  secondaryStatus = message ?? "Move the app to Applications and reopen it"
243
+ return false
242
244
  } catch {
243
245
  state = .error
244
246
  primaryStatus = "Could not prepare the local runtime"
245
247
  secondaryStatus = error.localizedDescription
248
+ return false
246
249
  }
247
250
  }
248
251
 
@@ -729,27 +732,22 @@ final class SyncModel: ObservableObject {
729
732
  }
730
733
  return
731
734
  }
732
- NSWorkspace.shared.openApplication(at: codexURL, configuration: NSWorkspace.OpenConfiguration()) { [weak self] _, error in
733
- Task { @MainActor in
734
- guard let self else { return }
735
- if let error {
736
- self.state = .warning
737
- self.primaryStatus = "Codex sessions updated, but Codex was not reopened"
738
- self.secondaryStatus = ([transferResult] + completedRestartMessages + ["Codex could not be reopened: \(error.localizedDescription)"]).joined(separator: "\n\n")
739
- } else {
740
- self.codexRunning = true
741
- self.state = partial || didSourceRestartFail ? .warning : .success
742
- self.primaryStatus = didSourceRestartFail ? "Sync complete, but the source did not reopen" : (partial ? "Codex sync completed with warnings" : "Codex sessions updated")
743
- self.secondaryStatus = ([transferResult] + completedRestartMessages + ["ChatGPT Codex reopened successfully."]).joined(separator: "\n\n")
744
- }
745
- if showMenuBarAlert {
746
- self.postNativeAlert(
747
- title: self.primaryStatus,
748
- message: self.secondaryStatus,
749
- kind: self.state == .success ? .information : .warning
750
- )
751
- }
752
- }
735
+ if NSWorkspace.shared.open(codexURL) {
736
+ codexRunning = true
737
+ state = partial || didSourceRestartFail ? .warning : .success
738
+ primaryStatus = didSourceRestartFail ? "Sync complete, but the source did not reopen" : (partial ? "Codex sync completed with warnings" : "Codex sessions updated")
739
+ secondaryStatus = ([transferResult] + completedRestartMessages + ["ChatGPT Codex reopened successfully."]).joined(separator: "\n\n")
740
+ } else {
741
+ state = .warning
742
+ primaryStatus = "Codex sessions updated, but Codex was not reopened"
743
+ secondaryStatus = ([transferResult] + completedRestartMessages + ["Codex could not be reopened. Open it manually to use the updated sessions."]).joined(separator: "\n\n")
744
+ }
745
+ if showMenuBarAlert {
746
+ postNativeAlert(
747
+ title: primaryStatus,
748
+ message: secondaryStatus,
749
+ kind: state == .success ? .information : .warning
750
+ )
753
751
  }
754
752
  }
755
753
 
@@ -1066,7 +1064,11 @@ final class SyncModel: ObservableObject {
1066
1064
  $0.bundleIdentifier == selectedBrowser.bundleIdentifier
1067
1065
  }
1068
1066
  guard !isSyncing else { return }
1069
- if selectedTargetID == "codex" && siteStorageEnabled && autoRestartBoth && (sourceBrowserRunning || codexRunning) {
1067
+ if !runtimeReady {
1068
+ state = .error
1069
+ primaryStatus = "Local sync runtime could not be refreshed"
1070
+ secondaryStatus = "Reopen the app or install the latest update before syncing"
1071
+ } else if selectedTargetID == "codex" && siteStorageEnabled && autoRestartBoth && (sourceBrowserRunning || codexRunning) {
1070
1072
  state = .ready
1071
1073
  primaryStatus = "Ready to sync and restart both apps"
1072
1074
  secondaryStatus = "Manual sync will force quit \(selectedBrowser.name) and Codex, then reopen only the apps that were running"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-cookie-bridge",
3
- "version": "1.4.4",
3
+ "version": "1.4.6",
4
4
  "description": "Local-first cookie and session transfer for macOS with optional Browserless upload",
5
5
  "type": "module",
6
6
  "bin": {