Repository navigation
Development
A Swift package (Package.swift, swift-tools-version 6.0, macOS 14 or later).
Sources/
AllInOneIMECore/ pure logic, no AppKit
Composer.swift two-level input state machine: pinyin, draft, @ commands and the command list, ⌃V and ⌘V, voice gestures, action key
Command.swift @ command definitions and parsing
ActionKey.swift action key
Config.swift config.json
Prompt.swift prompts
Converter.swift one request: reads config and credentials, calls Bedrock, parses the stream, caches
CandidateParser.swift parses the lines of the model's output
BedrockClient.swift ConverseStream client
EventStream.swift AWS event-stream decoding
SigV4.swift request signing
AWSSharedConfig.swift reads ~/.aws/credentials and ~/.aws/config
RewriteStyle.swift rewrite styles and their examples
JargonLibrary.swift 黑话 (jargon) list
InputSourceList.swift adds to / removes from the user's input source list (AppleEnabledInputSources)
LegacyData.swift migrates data from AIPinyin's folders
AppVersion.swift version number
Engine.swift, KeyMapping.swift, Language.swift
AllInOneIMERime/ Swift wrapper for librime (Rime.swift)
CRime/ module map for the librime C API
AllInOneIME/ the input method process (InputMethodKit)
main.swift entry point, plus --register / --disable / --status / --settings / --selftest
InputController.swift performs the effects Composer returns: text field, candidate panel, Bedrock, Terminal, clipboard, voice
CandidatePanel.swift candidate panel
SettingsWindow.swift settings window (SwiftUI)
UIText.swift interface text (Chinese / English)
VoiceInput.swift microphone and SpeechAnalyzer
SecureInput.swift secure input detection
FileSearch.swift search for @open
TerminalLauncher.swift @claude
InputSourceRegistrar.swift registers the input source, edits the input source list
SelfTest.swift make selftest
AllInOneIMESettings/ "AllInOneIME Settings" launcher: opens the input method's settings window with --settings
allinoneime-cli/ dev tool that runs @improve in Terminal
Tests/
AllInOneIMECoreTests/ unit tests for Core; Fixtures/ holds event-stream test data
AllInOneIMERimeTests/ tests with the real librime and ThirdParty/rime-data
Resources/ the two Info.plist files, localized strings, icons, entitlements, rime/default.custom.yaml
Scripts/ screenshots, icons, real-app test, fixture generation
ThirdParty/ librime and rime-ice, downloaded by make deps (not in the repo)
For the input method's own development options, see ~/Library/Input Methods/AllInOneIME.app/Contents/MacOS/AllInOneIME --help.
| Target | What it does |
|---|---|
make / make app
|
Builds and packages build/AllInOneIME.app
|
make deps |
Downloads and verifies librime 1.16.1 and rime-ice 2026.06.30, precompiles the dictionaries (into ThirdParty/) |
make build |
Builds the input method only (swift build) |
make settings-app |
Packages build/AllInOneIME Settings.app
|
make install |
Packages both apps, installs them in ~/Library/Input Methods and ~/Applications, registers the input method and adds it to the input source list |
make uninstall |
Disables it, removes it from the input source list, deletes both apps |
make status |
Status of the installed input method; see Installation and Troubleshooting |
make test |
Unit tests and Rime tests (swift test) |
make selftest |
Drives the input method with a simulated text field, with real Rime and real Bedrock |
make screenshots |
Runs make selftest, then generates the screenshots in docs/
|
make realtest |
Typing test through the installed input method, in a real text field of another app |
make realtest-build / make realtest-run
|
Only builds / only runs the real-app test program |
make realtest-when-unlocked |
Runs realtest-run once, automatically, after the screen is unlocked (a temporary launchd job) |
make realtest-cancel |
Cancels that job |
make cli |
Builds allinoneime-cli
|
make icon |
Regenerates Resources/AppIcon.icns and the menu bar icon Resources/icon.tiff from Resources/AppIcon.png
|
make clean |
Deletes .build and build
|
make distclean |
Also deletes ThirdParty
|
Variables: CONFIG (default release), SIGN_IDENTITY (default Apple Development; ad-hoc signing if it isn't found), OUT (the selftest's output folder, default /tmp/allinoneime-selftest), REALTEST_OUT (default ~/Library/Logs/AllInOneIME/realtest).
make, make app, make selftest and make screenshots all leave build/AllInOneIME.app behind. It has the same bundle ID as the installed copy, so macOS may launch it instead of the installed one; delete it when you're done (make install moves it away).
make test: swift test, two sets of tests.
-
AllInOneIMECoreTests: pure logic, with a fake pinyin engine and a stubbed network (URLProtocol); no network access, no AWS needed. Among them,AppVersionTestschecks that the versions in the two Info.plist files matchAppVersion.string. -
AllInOneIMERimeTests: uses the real librime andThirdParty/rime-data(make testrunsmake depsfirst).
make selftest: packages build/AllInOneIME.app, then runs AllInOneIME --selftest, which drives the real input controller with a simulated text field: real Rime, real Bedrock requests (with your config.json and AWS configuration; this costs a little), Spotlight search; the voice part tests on-device recognition with speech synthesized by say (skipped without SpeechAnalyzer). It doesn't touch the clipboard, the microphone or the sentence mode setting, and doesn't actually open files or Terminal; the settings window is tested on a temporary copy of the config, leaving your config.json unchanged. At the end it prints SELFTEST PASSED or SELFTEST FAILED (n), and writes the screenshots to OUT.
make realtest: tests the installed input method, so make install first. It starts a separate app with a real NSTextView and types through the system's text input path; it switches input sources for the test and back afterwards, and restores the sentence mode switch too. The screen must be unlocked; the test window holds the foreground for about a minute, so don't type meanwhile. Results are in ~/Library/Logs/AllInOneIME/realtest/output.txt, with REALTEST PASSED when it passes. When the screen is locked, use make realtest-when-unlocked; its log is ~/Library/Logs/AllInOneIME/realtest-watch.log.
allinoneime-cli: runs @improve in Terminal with the same Core code as the input method, reading the same config.json; options override it:
make cli
.build/release/allinoneime-cli --styles 简洁,黑话 "我今天有点不舒服"
.build/release/allinoneime-cli --output zh "this bug is blocker"
.build/release/allinoneime-cli --bench # 10 built-in sentences, reports latency(简洁,黑话 are the Concise and Jargon styles; 我今天有点不舒服 means "I'm not feeling well today".)
Other options: --profile, --region, --model, --jargon FILE, --raw (prints the model's raw output), --dump FILE (saves the raw event-stream response, for test data), --version.
make screenshots is make selftest followed by swift Scripts/make-readme-images.swift "$(OUT)" docs. The selftest renders the candidate panel and the settings window, and the script combines them into the images the README uses:
| Image | Source |
|---|---|
docs/demo.png |
1b-sentence-pinyin.png + 4-final-light.png
|
docs/english.png |
7-english-light.png + 7b-chinese-output.png
|
docs/voice.png |
8-voice.png |
docs/commands.png |
10-palette.png + 11-question.png
|
docs/open.png |
12-open.png + 12b-open-path.png
|
docs/panel-dark.png |
4-final-dark.png |
docs/settings.png |
6-settings.png |
The English screenshots are in docs/en, also made by make screenshots.
The content comes from real Bedrock answers and differs each time, so look it over before committing. It needs a working Bedrock setup and the speech models (if a render is missing, the script exits with an error). Delete build/AllInOneIME.app afterwards.
- The bundle ID and input source ID stay
com.aipinyin.inputmethod.AIPinyin: macOS uses it to remember the added input method, microphone access and preferences, so changing it would make users add and authorize it again. It is also the log subsystem. - When you change the wording of a prompt, increment
Prompt.version(@improve) orPrompt.commandVersion(@question) as the comments inPrompt.swiftsay; they are part of the cache key.
- Change the version in all three places together:
CFBundleShortVersionStringinResources/Info.plistandResources/Settings-Info.plist, andAppVersion.stringinSources/AllInOneIMECore/AppVersion.swift.AppVersionTestsinmake testchecks that the three match. - Update
CHANGELOG.md. - Update
README.mdandCHANGELOG.md(English) together with the ChineseREADME.zh-CN.mdandCHANGELOG.zh-CN.md. - Update the English wiki pages along with the Chinese ones.
-
make screenshots, then check the images indocs/and the English screenshots indocs/en. - Delete
build/AllInOneIME.app:rm -rf build/AllInOneIME.app.