browser-cookie-bridge 1.4.3 → 1.4.5

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.3",
4
+ "version": "1.4.5",
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.3</string>
14
- <key>CFBundleVersion</key><string>31</string>
13
+ <key>CFBundleShortVersionString</key><string>1.4.5</string>
14
+ <key>CFBundleVersion</key><string>33</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
 
@@ -1066,7 +1069,11 @@ final class SyncModel: ObservableObject {
1066
1069
  $0.bundleIdentifier == selectedBrowser.bundleIdentifier
1067
1070
  }
1068
1071
  guard !isSyncing else { return }
1069
- if selectedTargetID == "codex" && siteStorageEnabled && autoRestartBoth && (sourceBrowserRunning || codexRunning) {
1072
+ if !runtimeReady {
1073
+ state = .error
1074
+ primaryStatus = "Local sync runtime could not be refreshed"
1075
+ secondaryStatus = "Reopen the app or install the latest update before syncing"
1076
+ } else if selectedTargetID == "codex" && siteStorageEnabled && autoRestartBoth && (sourceBrowserRunning || codexRunning) {
1070
1077
  state = .ready
1071
1078
  primaryStatus = "Ready to sync and restart both apps"
1072
1079
  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.3",
3
+ "version": "1.4.5",
4
4
  "description": "Local-first cookie and session transfer for macOS with optional Browserless upload",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -309,14 +309,15 @@ async function sync(args, { signal } = {}) {
309
309
  if (isCodexTarget) {
310
310
  if (isCodexRunning()) throw new Error(CODEX_RUNNING_ERROR);
311
311
  const siteStorage = config.imports?.siteStorage === true;
312
- if (siteStorage && isChromiumBrowserRunning({ browser: source })) {
313
- throw new Error(`Quit ${source} completely before importing full site data into Codex.`);
314
- }
312
+ const source = requireClosedCodexSource({
313
+ sourceBrowser: config.sourceBrowser,
314
+ siteStorage,
315
+ });
315
316
  const payload = readChromiumProfile({
316
- browser: config.sourceBrowser || "brave",
317
+ browser: source,
317
318
  imports: config.imports || { cookies: true, history: false },
318
319
  });
319
- console.log(`Read ${payload.cookies.length} of ${payload.cookieStats.total} cookies (${payload.cookieStats.skipped} unavailable) and ${payload.history.length} history URLs from ${config.sourceBrowser || "brave"}.`);
320
+ console.log(`Read ${payload.cookies.length} of ${payload.cookieStats.total} cookies (${payload.cookieStats.skipped} unavailable) and ${payload.history.length} history URLs from ${source}.`);
320
321
  const result = directImportToCodex({
321
322
  cookies: payload.cookies,
322
323
  history: payload.history,
@@ -353,6 +354,18 @@ async function sync(args, { signal } = {}) {
353
354
  return result;
354
355
  }
355
356
 
357
+ export function requireClosedCodexSource({
358
+ sourceBrowser,
359
+ siteStorage,
360
+ runningCheck = isChromiumBrowserRunning,
361
+ }) {
362
+ const source = sourceBrowser || "brave";
363
+ if (siteStorage && runningCheck({ browser: source })) {
364
+ throw new Error(`Quit ${source} completely before importing full site data into Codex.`);
365
+ }
366
+ return source;
367
+ }
368
+
356
369
  function browserlessPreflight() {
357
370
  assertMacOS();
358
371
  const config = readConfig();