Voyager Safari 扩展迁移指南:从「Gemini Voyager」升级到「Voyager」(v1.6.0 改名)
【免费下载链接】voyagerEnhancement suite for Gemini, AI Studio, Claude & ChatGPT — plus a prompt manager for any websites, DeepSeek Harness included. / 面向 Gemini、AI Studio、Claude 与 ChatGPT 的增强套件;其中的提示词管理器可用于任意网站,如 DeepSeek Harness。项目地址: https://gitcode.com/gh_mirrors/ge/voyager
本篇指南基于仓库内 docs/es/guide/safari-migration.md 编写。从v1.6.0开始,Voyager 的 Safari 宿主应用由「Gemini Voyager」正式更名为「Voyager」。由于 macOS 依据应用名称来识别应用,直接安装新版会导致新旧两个应用并存、Safari 中出现重复扩展等混乱行为。读完本文,你将掌握一次性的安全替换流程、必须避开的两个操作雷区,以及迁移后 Sparkle 自动更新机制为何能接管后续所有版本升级——本文还会结合仓库源码说明应用内部是如何检测旧版残留并主动引导用户清理的。
为什么需要一次手动迁移
::: warning 仅需一次的手动操作 从v1.6.0起,Safari 宿主应用由「Gemini Voyager」改名为「Voyager」。macOS 按应用名称识别应用,直接安装新版本会使其与旧版并存,从而造成重复的扩展或令人困惑的行为。只需完成这一次替换,之后的自动更新将一如既往地工作。 :::
这一改名的影响范围比想象中更大:macOS 同时以「应用名称」和「Bundle ID」两个维度管理应用与扩展。Voyager 的 Safari 扩展注册在宿主应用(host app)内部,Safari 依靠宿主应用来定位对应的*.appex扩展。当Gemini Voyager.app与Voyager.app同时存在于/Applications时,Safari 会看到两个宿主、两套扩展实体,于是出现「同一个功能出现两个开关」「设置不生效」「扩展重复加载」等异常现象。
仓库源码对此场景有明确的定义:在 Voyager/App/AppDelegate.swift 中,旧版宿主应用的路径被硬编码为:
/// The pre-rename host app. If it lingers in /Applications alongside the new /// "Voyager.app", both Safari extensions coexist and conflict. private let legacyAppPath = "/Applications/Gemini Voyager.app"注释中直接点明:只要旧应用残留在/Applications中与新版并存,「两个 Safari 扩展就会共存并互相冲突」。这正是本次迁移必须手动完成的根本原因。
你的数据是安全的:Bundle ID 未改变
迁移最让人担心的就是数据丢失。官方文档明确承诺:应用的 Bundle ID 没有改变。你的文件夹、提示词库(prompt library)、云同步数据以及所有设置都会被完整保留;本次迁移只替换应用本身,绝不会触碰你的数据。
这一点在源码中有多重证据:
- 在 Voyager/Voyager.xcodeproj/project.pbxproj 中,宿主应用与扩展的
PRODUCT_BUNDLE_IDENTIFIER仍然保持旧标识com.yourCompany.Gemini-Voyager与com.yourCompany.Gemini-Voyager.Extension——改名只改显示名称(PRODUCT_NAME与CFBundleDisplayName变为Voyager/Voyager Extension),身份标识不变,系统据此认定「同一个应用」。 - 云端数据的归属也做了兼容设计。在 Voyager/Shared/NativeSupport.swift 中定义了
VoyagerGoogleDriveFolderIdentity:
enum VoyagerGoogleDriveFolderIdentity { static let currentName = "Voyager Data" static let legacyName = "Gemini Voyager Data" static let markerKey = "voyagerDataFolder" static let markerValue = "1" static func shouldRenameLegacyFolder( named name: String, canonicalNameAlreadyExists: Bool ) -> Bool { name == legacyName && !canonicalNameAlreadyExists } }旧版在 Google Drive 中使用的数据文件夹名是「Gemini Voyager Data」,新版本不仅认得旧名,还会在必要时将其迁移/重命名为规范的「Voyager Data」,且仅在规范目录尚不存在时才执行,避免破坏已有数据。对应逻辑由 Voyager/Tests/NativeSupportTests.swift 中的测试用例覆盖验证。
- 扩展的宿主交互契约同样不变。Voyager/Extension/SafariWebExtensionHandler.swift 中
NSExtensionPointIdentifier仍为com.apple.Safari.web-extension(见 Voyager/Extension/Info.plist),原生消息(通知投递、Google Drive 会话、iCloud 读写、剪贴板等)的编解码协议与旧版完全一致。
结论:你只需要关心「替换应用本体」,数据层无需任何额外操作。
迁移步骤(一次性四步)
按照官方文档的指引,替换过程只需四个步骤,全程无需命令行,也不需要备份恢复:
- 彻底退出 Safari(在 Safari 内按
⌘Q完全退出,仅关闭窗口是不够的)。 Safari 的扩展管理在退出状态下进行替换最稳妥,避免 Safari 持有旧扩展的句柄。 - 打开Finder → 应用程序,把旧的「Gemini Voyager.app」拖入废纸篓。
- 打开新下载的 DMG 镜像,把「Voyager.app」拖入应用程序。
- 重新打开 Safari →设置 → 扩展,启用「Voyager Extension」。
完成这四步后,旧扩展随旧应用一起被移除,新扩展在 Safari 中重新激活,功能与数据即刻恢复。
关于第 2 步,源码中还提供了一条「自动化兜底路径」:新版本应用在正常前台启动时,会主动检查旧版是否存在。见 Voyager/App/AppDelegate.swift 的promptLegacyAppRemovalIfNeeded():
private func promptLegacyAppRemovalIfNeeded() { guard !launchedForHandoff else { return } guard FileManager.default.fileExists(atPath: legacyAppPath) else { return } os_log(.default, log: notifLog, "legacy app detected at %{public}@", legacyAppPath) let alert = NSAlert() alert.alertStyle = .warning alert.messageText = "Remove the old “Gemini Voyager” app" alert.informativeText = "Voyager was renamed. An older “Gemini Voyager.app” is still in your " + "Applications folder, and keeping both can cause a duplicate Safari " + "extension. Move the old app to the Trash to finish migrating — your " + "folders, prompts, and settings are preserved." alert.addButton(withTitle: "Move Old App to Trash") alert.addButton(withTitle: "Migration Guide") alert.addButton(withTitle: "Not Now") ... }也就是说,即使你忘记手动删除旧版,新版启动时也会弹出提示框,给出三个选择:
| 按钮 | 行为 | 实现位置 |
|---|---|---|
| Move Old App to Trash | 调用NSWorkspace.shared.recycle把旧应用移入废纸篓;若失败则用 Finder 定位旧应用供手动处理 | AppDelegate.swift |
| Migration Guide | 打开迁移指南网页(即本文所对应的官方指南) | AppDelegate.swift |
| Not Now | 本次启动不再打扰,下次正常启动会再次提醒 | AppDelegate.swift |
同时,该提示仅在「普通前台启动」时弹出,后台的静默通知/URL 回跳(hand-off)启动会被launchedForHandoff标记拦截(AppDelegate.swift),不会在用户无感知的场景下弹出模态框。并且该提示是自愈式的——旧应用一旦删除,fileExists检查失败,提示就再也不会出现。
两件千万不要做的事
- ❌不要同时保留两个应用。如果旧「Gemini Voyager.app」仍留在原地,两个扩展将互相冲突(重复开关、行为混乱)。正确做法是按第 2 步把旧应用拖入废纸篓。
- ❌不要在 Safari 的扩展面板中对旧扩展点击「卸载」(Uninstall)。该操作指向的是旧宿主应用,会把手动迁移流程搞得更复杂,甚至可能留下残缺的扩展注册信息。请始终遵循「拖入废纸篓删除旧应用」这一方式。
迁移之后:Sparkle 自动更新正式接管
完成这一次替换后,后续所有 Safari 版本更新都将通过应用内置的自动更新器(Sparkle)进行,不再需要任何手动替换。
源码侧的完整证据链如下:
- Voyager/App/AppDelegate.swift 在启动时创建 Sparkle 标准更新控制器:
private let updaterController = SPUStandardUpdaterController( startingUpdater: true, updaterDelegate: nil, userDriverDelegate: nil )- 应用菜单中注册了「Check for Updates…」菜单项,并暴露了自动检查/自动下载开关(
setAutomaticUpdatesEnabled,见 AppDelegate.swift),用户可在偏好设置中控制是否自动下载更新。 - 发布侧,scripts/build-safari-release.sh 负责构建并公证
Voyager.app、用dmgbuild生成品牌化 DMG(voyager-$TAG.dmg),随后调用 scripts/generate-sparkle-appcast.sh 生成带sparkle:edSignature的appcast.xml并签名更新归档;该脚本会校验签名是否完整(grep -q 'sparkle:edSignature='),缺失则报错中止。 - scripts/verify-release-privacy.mjs 会在发布前检查构建环境变量
SPARKLE_PRIVATE_KEY是否已正确配置,防止发布出无法签名的更新包。
因此,迁移完成后你只需要关注新版应用弹出「有新版本可用」的提示并确认更新即可,Sparkle 会负责下载、签名校验与替换的全过程。
常见问题速查
- 升级到 v1.6.0 后 Safari 里出现了两个扩展开关?说明旧版
Gemini Voyager.app仍在/Applications中。按迁移步骤第 2 步删除旧应用,然后重启 Safari。 - 我已经装了新版,还能补救吗?可以。无论安装顺序如何,只需把旧应用拖入废纸篓并重启 Safari 即可完成迁移,数据不受影响。
- 迁移后 Google Drive / iCloud 数据还在吗?在。Bundle ID 未变,数据文件夹兼容旧名(「Gemini Voyager Data」),源码中的
VoyagerGoogleDriveFolderIdentity与对应测试保证了云端数据的连续性。 - 以后每次大版本更新都要手动替换吗?不需要。仅 v1.6.0 这一次改名需要手动操作,此后由 Sparkle 自动更新接管。
- 迁移过程中遇到疑问怎么办?可以通过仓库的 Issues 渠道反馈(原文档 docs/es/guide/safari-migration.md 末尾附有反馈入口)。
小结
v1.6.0 的改名是 Voyager 在 macOS 端的一次「身份换名不换芯」升级:显示名称与扩展名变为Voyager/Voyager Extension,而 Bundle ID、原生消息协议与云端数据标识全部保持兼容。用户只需要按官方流程完成「退出 Safari → 删除旧应用 → 安装新应用 → 启用扩展」这一一次性操作;即使忘记删除旧版,新版应用也会通过promptLegacyAppRemovalIfNeeded()主动检测残留并引导清理。此后,Sparkle 自动更新机制将全权接管后续版本升级,无需再做任何手动干预。
【免费下载链接】voyagerEnhancement suite for Gemini, AI Studio, Claude & ChatGPT — plus a prompt manager for any websites, DeepSeek Harness included. / 面向 Gemini、AI Studio、Claude 与 ChatGPT 的增强套件;其中的提示词管理器可用于任意网站,如 DeepSeek Harness。项目地址: https://gitcode.com/gh_mirrors/ge/voyager
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考