【免费下载链接】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.
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/ 的解法是:
- 用 Zod 在 src/schemas/ 中定义全部 RPC 方法(如 paste-text.ts、start-recording.ts)与事件
- 通过 QuickType 从 JSON Schema 一键生成 Swift / C# 模型(scripts/generate-swift-models.ts、generate-csharp-models.ts)
- 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.
相关推荐
Open CoDesign 架构全景:Electron 桌面端 + 多包 Monorepo 的分层设计与边界约束
Open CoDesign 架构全景:Electron 桌面端 + 多包 Monorepo 的分层设计与边界约束 这篇架构指南以 website/archite
人工智能AI 应用桌面应用Styled System 贡献指南:PR 流程、文档站点与 Monorepo 架构全解析
Styled System 贡献指南:PR 流程、文档站点与 Monorepo 架构全解析 本文以开源仓库 styled system https://link
前端UI组件设计系统OpenUI 文档站点架构解析:基于 Next.js 与 Fumadocs 构建 SDK 技术文档
OpenUI 文档站点架构解析:基于 Next.js 与 Fumadocs 构建 SDK 技术文档 OpenUI 是面向 Generative UI 的开源标准
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考