【免费下载链接】MoePeekA lightweight macOS selection translator built with pure Swift 6, featuring on-device Apple Translate for privacy, only 5MB install size and stable ~50MB memory usage. 一款轻量级 macOS 划词翻译工具纯 Swift 6 开发设备端 Apple 翻译保护隐私安装体积仅 5MB后台运行内存稳定约 50MB项目地址https://gitcode.com/gh_mirrors/mo/MoePeek点击查看免费下载MoePeek是一款轻量级 macOS 划词翻译工具纯 Swift 6 开发、安装体积仅 5MB。本文将深度剖析它的核心架构状态机中枢 TranslationCoordinator.swift 如何编排抓词 → 语言检测 → 多引擎并行翻译的全数据流。一、为什么需要协调者MoePeek 架构总览划词翻译看似简单实则要同时处理一堆棘手的并发问题文本从哪来划词、剪贴板、OCR 截图、手动输入5 种入口谁来翻译Apple Translation、Google、DeepL、OpenAI、DeepSeek……十几个引擎并行用户按两次快捷键怎么办旧请求会不会污染新结果MoePeek 的答案是经典的Coordinator 协调者模式所有流程最终都汇入同一个状态机中枢由它统一调度。整体数据流如下用户动作快捷键 / 划词浮标 / OCR / 剪贴板 → TranslationCoordinator状态机中枢Sources/Core/TranslationCoordinator.swift → 文本抓取TextSelectionManager 三层降级AX API → AppleScript → 剪贴板 → 语言检测LanguageDetectorNLLanguageRecognizer 加权提示 → 并行翻译TranslationProviderRegistry 展开的多引擎/多模型槽位 → PopupPanelController浮动结果面板不抢焦点 架构说明也见项目自带的 CLAUDE.md其中Core Data Flow一节与本文描述一致。二、核心状态机Phase 与 ProviderState 双层设计打开 TranslationCoordinator.swift你会看到两层状态枚举这是整个状态机的骨架第一层整体阶段Phaseenum Phase: Sendable { case idle // 空闲无翻译会话 case active // 活跃有进行中的翻译 }第二层每个翻译引擎独立维护ProviderStateenum ProviderState: Sendable, Equatable { case awaitingUser // 等待用户手动点击按需引擎 case waiting // 排队中 case translating // 请求已发出 case streaming(partial: String) // 流式接收中partial 为已累积文本 case completed(text: String) // 完成 case error(message: String) // 出错 }这种设计的妙处在于一次划词可能同时调用 4 个引擎每个引擎有自己的心跳。UI 层PopupView.swift直接观察providerStates字典哪个引擎出结果就先渲染哪个而不用等最慢的那个。另外还有一个容易被忽略的枚举ActionOutcomeL9-L16它告诉调用方要不要弹面板——.present表示展示新结果.preserve表示抓词失败、保留现状。抓不到文字时绝不弹一个报错的空面板这个细节是体验打磨的关键。三、文本抓取三层降级策略划词的难点在于拿到前台 App 中选中的文字。TextSelectionManager.swift 实现了教科书式的三层降级层级方案适用场景Tier 1AccessibilityGrabber.swift 无障碍 API绝大多数 AppTier 2AppleScriptGrabber.swiftSafari 专用兜底Tier 3ClipboardGrabber.swift 模拟 ⌘C通用最终兜底其中第三层最见功力。模拟 ⌘C 会污染用户剪贴板ClipboardGrabber.swift 做了四件事备份逐类型保存剪贴板全部原始数据标记给模拟按键打自定义标签0x4D6F6550键盘监视器据此区分我们自己按的 ⌘C和用户真实按的 ⌘C超时守卫在可配置期限内等待剪贴板变化还原读取完毕后恢复原剪贴板若期间用户自己复制了东西则放弃还原、尊重用户四、语言检测不只是猜语言LanguageDetector.swift 基于系统NLLanguageRecognizer但做了两个实用增强权重提示hints英语加权 2.0、简体中文 1.5、日语 0.6……先验概率让短文本检测更稳偏好联动buildLanguageHints() 会根据你的目标语言反推源语言——目标设为中文时英语、日语的权重自动上调同时排除目标语言本身当源语言的荒谬结果短文本更严格5 字符以内的文本置信度阈值自动提高到 0.5避免OK被误判检测到源语言后resolveTargetLanguage会自动翻转方向目标是中文、源也是中文时自动切到英语。五、多引擎并行一个 Provider 协议打天下所有翻译后端都实现同一个协议 TranslationProvider.swift核心只有一个流式方法func translateStream(_ text: String, from: String?, to: String?) - AsyncThrowingStreamString, Error统一的流式接口让Google 一次性返回和OpenAI 逐字流式返回对上层完全无感——非流式引擎用singleResultStream包装成一个 chunk 即可。TranslationProviderRegistry.swift 负责把用户启用的引擎展开成槽位支持多模型的引擎如 OpenAI 兼容服务会被拆成多个ModelSlotProvider每个模型一个卡片最多 20 个并行。此外onDemandProviderIDs里的引擎标记为按需——划词时不会自动触发留在awaitingUser状态等你手动点击。数据到达引擎前的最后一道处理在 launchProvider若源文本是 Markdown 且引擎是 LLM 类原文照发并通过TaskLocal上下文TranslationRequestContext.swift附加保留 Markdown 结构、原样保留图片占位符的提示词机器翻译 API 则降级为纯文本。六、防止旧结果覆盖新会话token 与 generation 双保险划词工具最常见的 bug 是快速按两次快捷键慢的那个请求后完成把新结果冲掉了。MoePeek 用两枚令牌解决actionToken会话级每次translateSelection()等入口调用时先beginAction()自增。抓词是异步的返回时必须校验requestToken actionToken——期间若来了新请求旧结果直接丢弃返回.preserve。translationGeneration翻译级每次translate()自增runProvider中每收到一个流式 chunk 都校验generation translationGeneration不匹配就静默退出不再写任何状态。配套的单元测试 TranslationActionOutcomeTests.swift 用受控的CheckedContinuation精确复现了重叠请求过期抓取等时序场景比如staleSelectionDoesNotRestoreOverNewInputSession就验证了过期抓词绝不覆盖新输入会话。七、一次划词的完整旅程把前面所有模块串起来按 ⌥D 之后的完整数据流是快捷键触发AppDelegate.swift 中KeyboardShortcuts.onKeyUp回调先取消可能未完成的智能翻译任务权限检查无障碍权限未授予 → 直接进入active并设置globalError弹面板引导授权抓词三层降级拿文字失败且为空 → 返回.preserve不弹面板、不清空已有结果进入翻译startTranslation取消所有旧任务、重置错误、写入sourceText语言解析手动指定 or 自动检测 → 定出targetLanguage并行发射自动类引擎各起一个Task状态waiting → translating → streaming → completed渲染面板随Observable状态变化实时刷新流式文本逐字上屏dismiss()时cancelAll()收尾回到idle八、总结这套架构值得抄作业的地方单一状态源所有 UI 读同一个 Coordinator天然不会出现面板和状态两张皮状态分层全局 Phase 每引擎 ProviderState兼顾整体与局部令牌防竞态token/generation 双保险是长生命周期菜单栏 App 的必修课协议化 Provider加一个新翻译引擎只需实现协议 在 builtIn() 注册一行如果你想动手研读建议按 Sources/Core/ → Sources/Services/ → Tests/ 的顺序走核心文件基本都已在文中标注了相对路径。5MB 的安装包里这套状态机就是它快、稳、不抢焦点体验的根基。赞分享【免费下载链接】MoePeekA lightweight macOS selection translator built with pure Swift 6, featuring on-device Apple Translate for privacy, only 5MB install size and stable ~50MB memory usage. 一款轻量级 macOS 划词翻译工具纯 Swift 6 开发设备端 Apple 翻译保护隐私安装体积仅 5MB后台运行内存稳定约 50MB项目地址https://gitcode.com/gh_mirrors/mo/MoePeek点击查看免费下载相关推荐PlayTranslate翻译瀑布是如何工作的后端级联与冷却状态机深度剖析指南PlayTranslate翻译瀑布是如何工作的后端级联与冷却状态机深度剖析指南 PlayTranslate 是一款面向游戏、视觉小说和漫画的实时翻译 AndrSketchyBar翻译功能终极指南如何在macOS状态栏快速实现划词翻译SketchyBar翻译功能终极指南如何在macOS状态栏快速实现划词翻译 SketchyBar是一款高度可定制的macOS状态栏替代工具让用户能够完全自定桌面应用本地大模型划词翻译将Ollama与LM Studio接入MoePeek的私有化教程本地大模型划词翻译将Ollama与LM Studio接入MoePeek的私有化教程 MoePeek 是一款轻量级 macOS 划词翻译工具原生内置了 Oll创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?