Repository navigation
Swift Package(Package.swift,swift-tools-version 6.0,最低 macOS 14)。下面列的是主要文件,还有别的(AI 服务、插件、菜单栏面板、安装程序)。
Sources/
AllInOneIMECore/ 纯逻辑,不依赖 AppKit
Composer.swift 两级输入状态机:拼音、韩文和印地语、草稿、@ 命令和命令列表、⌃V 和 ⌘V、语音手势、执行键
Command.swift @ 命令的定义和解析
ActionKey.swift 执行键
Config.swift config.json
Prompt.swift 提示词
Converter.swift 一次请求:读配置和凭证、调 Bedrock、解析流、缓存
CandidateParser.swift 解析模型输出的各行
BedrockClient.swift ConverseStream 客户端
EventStream.swift AWS event-stream 解码
SigV4.swift 请求签名
AWSSharedConfig.swift 读 ~/.aws/credentials 和 ~/.aws/config
RewriteStyle.swift 改写风格和示例
JargonLibrary.swift 黑话词表
InputSourceList.swift 在用户的输入法列表(AppleEnabledInputSources)里增删
LegacyData.swift 从 AIPinyin 的目录迁移数据
LanguagePack.swift 语言包:目录、已安装的语言包、校验;LanguagePackLibrary.swift:签名的索引
LatinEngine.swift 英文输入,按键盘布局组合死键
FuzzyPinyin.swift 模糊音,写成 rime_ice.custom.yaml
AppVersion.swift 版本号
Hangul.swift 韩语:两套式键位表(来自 ko-hangul 语言包)和组成音节
Hindi.swift 印地语:拉丁字母 → 天城文(来自 hi-phonetic 语言包),它的输入引擎
Language.swift 输入语言,以及一句话是用哪种语言写的
ScriptCommand.swift 脚本扩展:协议的键、Raycast 的键怎么对应过来、参数、环境变量
ScriptOutput.swift 脚本的输出:文字、summary/detail、Alfred Script Filter 列表和它们的动作
ExtensionStore.swift 扩展的文件夹、扩展包(extension.json)和偏好设置、文件缓存、用聚焦查找
ScriptScheduling.swift 状态轮流刷新、后台的名额、命令列表只在变化时重建
Engine.swift、KeyMapping.swift
AllInOneIMERime/ librime 的 Swift 封装(Rime.swift)
CRime/ librime C API 的 module map
AllInOneIME/ 输入法进程(InputMethodKit)
main.swift 入口,以及 --register / --disable / --status / --settings / --selftest / --install-pack
InputController.swift 执行 Composer 返回的效果:文本框、候选框、Bedrock、终端、剪贴板、语音
CandidatePanel.swift 候选框
SettingsWindow.swift 设置窗口(SwiftUI)
LanguagePacks.swift 下载和安装语言包
UIText.swift 界面文字(中文 / 英文)
VoiceInput.swift 麦克风和 SpeechAnalyzer
SecureInput.swift 安全输入的判断
LiveExtensions.swift 脚本扩展:在后台重建索引、状态
ScriptTasks.swift 脚本扩展的运行、后台运行、通知
FileSearch.swift @open 的搜索
TerminalLauncher.swift @claude
InputSourceRegistrar.swift 注册输入源、改输入法列表
SelfTest.swift make selftest
AllInOneIMESettings/ 「AllInOneIME 设置」启动器:用 --settings 打开输入法的设置窗口
allinoneime-cli/ 在终端里跑 @improve 的开发工具
Tests/
AllInOneIMECoreTests/ Core 的单元测试;Fixtures/ 里是 event-stream 测试数据
AllInOneIMERimeTests/ 用真实 librime 和 ThirdParty/rime-data 的测试
Resources/ 三个 Info.plist(输入法、设置、安装程序)、本地化字符串、图标、entitlements、rime/default.custom.yaml
Scripts/ 截图、图标、磁盘映像、语言包和它的索引、wiki 翻译、real-app 测试、fixture
ThirdParty/ make deps 下载的 librime 和雾凇拼音(不在仓库里)
输入法本身的开发参数见 ~/Library/Input Methods/AllInOneIME.app/Contents/MacOS/AllInOneIME --help。
| 目标 | 作用 |
|---|---|
make / make app
|
编译并打包 build/AllInOneIME.app
|
make deps |
下载并校验 librime 1.16.1 和雾凇拼音 2026.06.30,预编译词库(到 ThirdParty/) |
make build |
只编译输入法(swift build) |
make settings-app |
打包 build/AllInOneIME Settings.app
|
make installer-app |
打包 build/Install AllInOneIME.app,磁盘映像里的安装程序 |
make install |
打包两个 App,装到 ~/Library/Input Methods 和 ~/Applications,注册输入法并加进输入法列表 |
make uninstall |
停用、移出输入法列表、删掉两个 App |
make pack |
中文语言包:build/packs/zh-pinyin-<版本>.tar.xz、它的 SHA-256 和 packs.json 条目 |
make packs |
所有语言包:中文,以及 LanguagePacks/ 里的韩语和印地语(ko-hangul、hi-phonetic) |
make install-pack |
用源码目录里的词库把中文语言包装进已安装的输入法,不用下载 |
make status |
已安装输入法的状态,见 安装与排查 |
make test |
单元测试和 Rime 测试(swift test) |
make selftest |
用模拟文本框驱动输入法,真实 Rime、真实 Bedrock |
make screenshots |
先 make selftest,再生成 docs/ 和 docs/en/ 里的截图 |
make panel-images |
在屏幕上截菜单栏面板(毛玻璃、一行向左滑开):docs/panel-*.png、docs/en/panel-*.png
|
make dmg |
发布用的安装包 build/AllInOneIME-<版本>.dmg(通用版) |
make realtest |
在另一个 App 的真实文本框里,通过已安装的输入法打字测试 |
make realtest-build / make realtest-run
|
只编译 / 只运行 real-app 测试程序 |
make realtest-when-unlocked |
屏幕解锁后自动跑一次 realtest-run(临时的 launchd 任务) |
make realtest-cancel |
取消这个任务 |
make cli |
编译 allinoneime-cli
|
make icon |
从 Resources/AppIcon.png 重新生成 Resources/AppIcon.icns 和菜单栏图标 Resources/icon.tiff
|
make clean |
删掉 .build 和 build
|
make distclean |
再删掉 ThirdParty
|
变量:CONFIG(默认 release)、SIGN_IDENTITY(默认 Apple Development,找不到就 ad-hoc 签名)、OUT(selftest 的输出目录,默认 /tmp/allinoneime-selftest)、REALTEST_OUT(默认 ~/Library/Logs/AllInOneIME/realtest)。
make、make app、make selftest 和 make screenshots 都会留下 build/AllInOneIME.app。它和装好的那份 bundle ID 相同,macOS 可能启动它而不是装好的那份;用完就删掉(make install 会把它移走)。
make test:swift test,两组测试。
-
AllInOneIMECoreTests:纯逻辑,用假的拼音引擎和桩网络(URLProtocol),不联网,不需要 AWS。其中AppVersionTests检查三个 Info.plist 的版本号和AppVersion.string一致。 -
AllInOneIMERimeTests:用真实的 librime 和ThirdParty/rime-data(make test会先make deps)。
make selftest:先打包 build/AllInOneIME.app,再运行 AllInOneIME --selftest,用模拟的文本框驱动真实的输入控制器:真实 Rime、真实 Bedrock 请求(用你的 config.json 和 AWS 配置,会产生少量费用)、聚焦搜索;语音部分用 say 合成的语音测本机识别(没有 SpeechAnalyzer 时跳过)。它不碰剪贴板和麦克风,也不会真的打开文件或终端;设置窗口在临时的配置副本上测,不改你的 config.json。最后打印 SELFTEST PASSED 或 SELFTEST FAILED (n),截图写到 OUT。
make realtest:测的是已安装的输入法,所以先 make install。它另起一个带真实 NSTextView 的 App,走系统的文字输入路径打字;测试时临时切换输入法,结束后切回来。屏幕要已解锁;测试窗口会占用前台约 1 分钟,期间不要打字。结果在 ~/Library/Logs/AllInOneIME/realtest/output.txt,通过时有 REALTEST PASSED。锁屏时用 make realtest-when-unlocked,日志在 ~/Library/Logs/AllInOneIME/realtest-watch.log。
allinoneime-cli:用和输入法相同的 Core 代码在终端里跑 @improve,读同一个 config.json;参数可以覆盖它:
make cli
.build/release/allinoneime-cli --mode improve --styles concise,jargon "this is a blocker bug your team need fix it asap"
.build/release/allinoneime-cli --output es,fr,de "running 10 minutes late, start without me"
.build/release/allinoneime-cli --bench # 内置的句子,报告延迟其他参数:--provider(bedrock、anthropic、gemini 或 openai)、--profile、--region、--model、--jargon FILE、--raw(打印模型的原始输出)、--dump FILE(保存原始的 event-stream 响应,做测试数据)、--version。
make screenshots 就是先 make selftest,再运行 Scripts/make-readme-images.swift,docs/(中文)和 docs/en/(英文)各一次。selftest 渲染候选框和设置窗口,脚本在每个候选框上面加一行文本,显示行内正在输入的文字。英文图来自它们自己的场景,不是中文场景换成英文界面:打的是英文,@translate 翻译成西班牙语、法语和德语,@question 用英文提问。
| 图 |
docs/(中文) |
docs/en/(英文) |
|---|---|---|
demo.png |
2-translate-pinyin + 3-translate
|
en-translate-draft + en-translate
|
improve.png |
1b-sentence-pinyin + 4-final-light
|
en-improve-draft + en-improve
|
english.png |
7-english-light + 7b-chinese-output
|
— |
voice.png |
8-voice |
8-voice-english-en |
commands.png |
10-palette + 11-question
|
en-palette + en-question
|
open.png |
12-open + 12b-open-path
|
同左,加 -en
|
panel-dark.png |
4-final-dark |
en-improve-dark |
settings.png |
6-settings |
6-settings-en(英文输入,翻译成西班牙语、法语、德语) |
dashboard.png |
14-dashboard |
14-dashboard-en |
菜单栏面板的毛玻璃没法离屏渲染(后面什么都没有),所以 make panel-images 把带示例数据的真实面板显示在一个色彩丰富的窗口上面,再用 screencapture 截下来(AllInOneIME --showcase)。
内容来自真实的 AI 回答,每次都会有出入,提交前看一眼。之后删掉 build/AllInOneIME.app。
- Bundle ID 和输入源 ID 一直是
com.aipinyin.inputmethod.AIPinyin:macOS 按它记住已添加的输入法、麦克风权限和偏好设置,改了用户就要重新添加和授权。日志的 subsystem 也是它。 - 改了提示词的措辞,按
Prompt.swift里注释说的,把Prompt.version(@improve)或Prompt.commandVersion(@question)加一;它们是缓存键的一部分。
- 改版本号,四处一起改:
Resources/Info.plist、Resources/Settings-Info.plist和Resources/Installer-Info.plist里的CFBundleShortVersionString(和CFBundleVersion),以及Sources/AllInOneIMECore/AppVersion.swift里的AppVersion.string。AppVersionTests会检查它们是否一致。 - 英文的
README.md、CHANGELOG.md和中文的README.zh-CN.md、CHANGELOG.zh-CN.md一起更新。 - 更新英文 wiki 页面;中文页面由
wiki-zhworkflow(Scripts/translate-wiki.py)从英文翻译过来。 -
make screenshots(面板有变化时再make panel-images),然后检查docs/和docs/en/里的图:英文图里不能有中文。 - 删掉
build/AllInOneIME.app:rm -rf build/AllInOneIME.app。 -
make dmg,然后发布(标为 Latest):更新日志英文在前、中文在后,每个看得见的变化配上它的截图(英文部分用docs/en/,中文部分用docs/),链接到具体的 commit,这样截图永远不会变。