☰
拆解Amical Monorepo架构:Electron桌面App、Next.js文档站与Swift/Windows原生Helper全景
2026/10/12 8:23:01 网站建设 项目流程

【免费下载链接】amical

🎙️ AI Dictation App - Open Source and Local-first ⚡ Type 3x faster, no keyboard needed. 🆓 Powered by open source models, works offline, fast and accurate.

项目地址:https://gitcode.com/gh_mirrors/am/amical
点击查看免费下载

Amical 是一个开源、本地优先(Local-first)的 AI 语音听写桌面应用:基于 Whisper 语音转文字与开源大模型,无需键盘即可实现约 3 倍速输入,支持离线工作,兼顾速度与准确率。本文带你全景拆解这个 Monorepo——apps/下既有 Electron 桌面 App,也有 Next.js 文档官网;packages/下则藏着 Swift 与 C# 编写的原生 Helper,以及 C++ 编译的 Whisper 本地转写引擎。

一、Monorepo 总览:一个仓库,五种技术栈

仓库根目录用pnpm workspace + Turborepo组织所有子项目,核心配置只有三个文件:

  • 工作区定义:pnpm-workspace.yaml——apps/*与packages/*全部纳入,同时把whisper.cpp子模块排除在 Node 依赖之外
  • 构建编排:turbo.json——声明了build、dev、test、type:check、build:native等任务与缓存规则
  • 根脚本:package.json——一键转发pnpm build、pnpm test等命令给 Turbo
amical/ ├── apps/ │ ├── desktop/ # Electron 桌面应用(核心产品) │ └── www/ # Next.js 官网 + 文档站 └── packages/ ├── native-helpers/ # SwiftHelper(macOS) / WindowsHelper(Win) ├── whisper-wrapper/ # C++ 编译的 Whisper 本地转写 Node 插件 ├── types/ # 跨语言共享类型与协议定义 ├── ui/ # 共享 React 组件库 ├── eslint-config/ # 共享 ESLint 配置 └── typescript-config/ # 共享 TS 编译配置

这种"应用与库分离"的结构让桌面端、官网、原生助手可以独立开发、独立打包,又能共享类型和 Lint 规则。

二、Electron 桌面 App:多进程协作 + tRPC 数据层

桌面应用位于 apps/desktop/,是仓库中体量最大的部分,技术栈包括 Electron 44、React 19、Vite 7、TailwindCSS 4、tRPC、Zod 与 better-sqlite3(详见 apps/desktop/package.json)。

2.1 主进程分层

主进程入口做了"防崩溃"设计:main.ts 只保留最小导入,把整个应用放进动态import()中,任何模块加载失败都会落到致命错误对话框,而不是无提示崩溃。随后由 app.ts 完成单实例锁、amical://协议注册、系统证书链修复等初始化。

核心目录结构如下:

目录职责
core/AppManager、窗口管理(主窗、悬浮 Widget、笔记窗)
managers/服务管理、快捷键管理、系统托盘
lifecycle/听写会话状态机(25 个文件)
runtime/运行时分层与标签体系
services/自动更新、更新提示
telemetry/听写链路追踪

2.2 听写生命周期状态机

最有意思的是 lifecycle/ 目录:整个"开始录音 → 转写 → 注入文本"的过程被建模成纯函数状态机 machine.ts,在IDLE → STARTING → RECORDING → RESOLVING → SETTLING五个阶段间转移,且配套了回放、录制、恢复等一整套契约测试(见 tests/main/),这是桌面 App 可靠性的核心保障。

2.3 tRPC + SQLite 的本地数据层

渲染进程与主进程之间不用手写 IPC 字符串,而是用tRPC定义类型安全的 routers/;本地数据则交给 better-sqlite3 + Drizzle ORM,迁移文件全部集中在 db/migrations/,涵盖笔记、设置、听写统计等表。

三、Next.js 文档站:Fumadocs + Cloudflare

官网与文档站在 apps/www/,基于 Next.js 15 +Fumadocs(MDX 文档框架)构建:

  • 全部文档以 MDX 编写在 content/docs/,如 getting-started.mdx、bring-your-own-key.mdx,覆盖快捷键、自定义词汇、本地模型等 19 个主题
  • 首页与博客在 app/(home)/,文档路由由 app/docs/[[...slug]]/ 动态渲染
  • 部署脚本 wrangler.jsonc 表明站点托管在 Cloudflare Pages,配合next-plausible做轻量统计

值得注意:pnpm-workspace.yaml 将apps/www排除出 pnpm 工作区,让文档站保持独立的生命周期。

四、原生 Helper:Swift 与 C# 双端实现

Electron 无法直接监听全局热键、粘贴文本或读取无障碍树,Amical 的解法是为每个平台写一个独立的原生小助手进程,与主进程通过 stdin/stdout 进行 JSON-RPC 通信:

4.1 SwiftHelper(macOS)

位于 packages/native-helpers/swift-helper/,用 SwiftPM 构建(Package.swift),核心服务包括:

  • ShortcutManager.swift:全局快捷键监听
  • AccessibilityService.swift:检测当前焦点 App,实现"上下文感知听写"
  • AudioService.swift:系统音频采集(会议转写场景)
  • EventTapHandler.swift:按键事件处理
  • RpcHandler.swift:RPC 请求分发

录音开始/停止音效(rec-start.mp3等)直接编译嵌入二进制,配合ObjCExceptionCatcher目标兜底 Objective-C 异常。

4.2 WindowsHelper(Windows)

位于 packages/native-helpers/windows-helper/,C# + .NET 8 实现,结构与 Swift 端一一对应:ShortcutManager.cs、ShortcutMonitor.cs、RpcHandler.cs,以及 Services/ 下的剪贴板、录音氛围音等 10 个服务。STAThreadRunner保证 UI 相关调用运行在 STA 线程上,配套单元测试在 windows-helper-tests/。

五、whisper-wrapper:离线转写的 C++ 引擎

本地转写能力来自 packages/whisper-wrapper/:

  • 通过 git submodule 引入 whisper.cpp,pnpm install时自动打补丁并编译 C++ Node 插件(addon/addon.cpp)
  • 支持 CUDA / Vulkan 加速路径(build:native:cuda、build:native:vulkan)
  • 桌面端另有 gRPC 客户端 dictation.proto 定义转写协议,配合独立 Node worker 运行模型,避免阻塞主进程

六、@amical/types:跨语言协议的"单一事实来源"

Electron(TS)、Swift、C# 三端通信,最怕协议漂移。packages/types/ 的解法是:

  1. 用 Zod 在 src/schemas/ 中定义全部 RPC 方法(如 paste-text.ts、start-recording.ts)与事件
  2. 通过 QuickType 从 JSON Schema 一键生成 Swift / C# 模型(scripts/generate-swift-models.ts、generate-csharp-models.ts)
  3. Windows 端构建前先执行generate:all,保证三端类型永远同步

七、本地开发快速上手

按 README.md 的步骤,克隆仓库后即可跑起桌面端:

git clone --recurse-submodules https://gitcode.com/gh_mirrors/am/amical cd amical corepack enable pnpm install --frozen-lockfile # 会自动编译 Whisper 原生插件 pnpm --filter @amical/desktop download-node pnpm turbo run dev --filter=@amical/desktop

前置要求:Node 24+、CMake 3.20+;macOS 需 Xcode/Swift 5.9+,Windows 需 VS 2022 Build Tools 与 .NET 8 SDK。提交前建议执行pnpm type:check与pnpm test。

总结

Amical 的 Monorepo 是一份很值得借鉴的"跨技术栈桌面产品"架构样本:

  • 应用与基建分离:Electron App、Next.js 站点、原生 Helper 各自独立,共享类型与工具链
  • 协议先行:Zod 定义 + 代码生成,让 TS/Swift/C# 三端通信零漂移
  • 状态机驱动:核心听写流程纯函数化,可用回放测试保证稳定性
  • 本地优先:Whisper C++ 引擎 + SQLite 本地存储,离线也能完整工作

如果你是 Electron 开发者,建议优先阅读 apps/desktop/src/main/ 的分层设计与 lifecycle/ 状态机;如果关注跨端 RPC,packages/types/ 的代码生成方案几乎可以原样搬用到你的项目里。

【免费下载链接】amical

🎙️ AI Dictation App - Open Source and Local-first ⚡ Type 3x faster, no keyboard needed. 🆓 Powered by open source models, works offline, fast and accurate.

项目地址:https://gitcode.com/gh_mirrors/am/amical
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询