This handbook briefs AI coding assistants on the vChewing (威注音) macOS repository. Use only English or zh-Hant-TW for docs/comments/reviews; zh-Hans is allowed only in filename stems ending with -CHS.
- Purpose: Native Zhuyin / Bopomofo input method for macOS with optional phonetic and stroke keyboards, simplified ↔ traditional isolation, and sandboxed distribution installers.
- Implementation: Pure Swift modules layered on AppKit/IMK. C(++)/ObjC(++) bridges exist only where Swift cannot interface directly with legacy assets.
- Primary packages:
vChewing_MainAssembly: IMK front-end (SessionCtl, InputSession, UI bridges, sandbox glue).vChewing_Typewriter: Typing FSM, Tekkon integration, user preference wiring, cassette/stroke handling.vChewing_Megrez: DAG-DP compositor (sentence assembler) with perception override hooks (POM).vChewing_Tekkon: Keyboard parsers, Zhuyin/Bopomofo composer, stroke cassette parser, phonabet utilities.vChewing_LangModelAssembly: LM instantiation facade, user phrase memory, perception override, associated phrases.- Shared dependencies (
vChewing_Shared,vChewing_SwiftExtension,vChewing_OSFrameworkImpl, etc.) supply utilities, result-builder UI DSL, notifications, and AppKit wrappers.
- Lexicon assets: Submodule
Source/Data(Swift-based tooling + generated blobs). Do not edit unless specifically asked.
- Authoritative toolchain: macOS 14.7+ (Sonoma recommended), Xcode 15.3+ with bundled Swift 5.10 or newer.
- Runtime target: macOS 12 Monterey and newer. Older macOS support lives in another repo.
- Project entry:
vChewing.xcodeproj(schemevChewing). Installer scaffolding:vChewing.pkgproj, SwiftUI installer app underInstaller/. - CLI builds:
pwsh -NoLogo -Command "xcodebuild -project vChewing.xcodeproj -scheme vChewing -configuration Release build"- Package-only builds/tests:
pwsh -NoLogo -Command "cd Packages/vChewing_Typewriter; swift build", same forswift test.
- First-time setup:
make update(fetches/generated lexicons) then build. Ensure Xcode DerivedData location is set to “Relative to Workspace” to satisfy make recipes.
Packages/vChewing_MainAssembly/.../SessionController/SessionCtl.swift: IMK entry point. All NSEvent handling funnels throughInputSession*files.Packages/vChewing_Typewriter/Sources/Typewriter/InputHandler/: FSM split across triage, composition, candidate handling, and commissions.Packages/vChewing_Megrez/Sources/Megrez/: Compositor core (0_Megrez.swift,2_PathFinder.swift, etc.).Packages/vChewing_Tekkon/Sources/Tekkon/: Keyboard parsers, composer, Zhuyin constants.Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/: LM instantiators, perception override, associated phrase derivation.Packages/vChewing_OSFrameworkImpl/: AppKit result-builder DSL for SettingsCocoa window, etc.Packages/vChewing_CandidateWindow/: The Candidate window.Source/Data: Submodule for lexicon tooling (Makefile, Swift build scripts, generatedBuild/assets).Installer/: SwiftUI installer app + pkg resources.
- Event capture: IMK
SessionCtlreceives NSEvents and marshals them intoKBEventstructures. - FSM triage:
InputHandlerin Typewriter interprets events, orchestrates Tekkon composer, updates Megrez compositor, and switchesIMEStateinstances. - Composer: Tekkon manages Zhuyin/phonetic/stroke buffers, auto-correction, cassette mode, and exposes inline display strings.
- Assembler: Megrez Compositor (sentence assembler) builds DAG segments, snapshotting perception intelligences (will be fed to the perception override module in the
LMAssemblypackage), emitsassembledSentencefor UI rendering. - Language Models:
LMAssemblymerges factory lexicons, user phrases, exclusion lists, associated phrase suggestions, and perception override data, etc. - UI update:
SessionCtlrefreshes candidate window, composition buffer, tooltips, notifications, symbol menu.
Reference algorithm.md for the deep algorithm write-up (zh-Hant).
- Language: Code comments, docs, and commit messages in English or zh-Hant. (zh-Hans only in files if filenamestem ends with
-CHS.) - UI: AppKit only. No Interface Builder nibs/storyboards. Keep UI work on the main actor. Most AppKit Window views are implemented using AppKit Result Builder DSL.
- Preferences: Extend
UserDef,PrefMgrProtocol, andPrefMgrtogether. Avoid nakedUserDefaults.standardaccess except in constrained scenarios. - User data paths: Avoid hard-coded user data paths except where necessary in package test targets.
- State machine: Prefer new
IMEStateenum cases and explicit transition APIs over boolean shortcuts. Follow existingInputSession/InputHandlerprotocol surfaces. - Conditional APIs: Guard platform-specific code (
#if canImport(Darwin)) as needed; keep Linux compatibility inTypewriterpackage and its local dependnecies. - ObjC(++)/C(+=) style: Follow Google Style Guide formatting for Objective-C(++) and C(++).
- Licensing: Preserve MIT-NTL banners. Respect LGPL for Megrez and Tekkon; avoid mixing incompatible license assets.
- Lexicon tooling: Generated data lives under
Source/Data/Build. Scripts run viamakeor Swift command-line tools; do not check in regenerated blobs unless instructed.
- Unit tests live alongside each Swift package (
swift test). Focus on deterministic cases that mirror reported issues. - Typewriter and MainAssembly packages host end-to-end style tests; consider snapshotting
PrefMgrstate before/after. - When touching Tekkon or Megrez, craft stress tests covering multi-syllable input, perception overrides, cursor edge cases.
- Use
swift test --filterto run targeted suites when debugging CI regressions.
- Commit format:
ModuleName // SubModuleName: Change.(Conventional Commit semantics kept terse.) Example:Typewriter // FSM: Fix cursor guard. - Reviews: Highlight functional impact, state machine ramifications, and test coverage. Mention regression risk if tests are missing.
- Dependencies: Prefer SwiftPM-targeted adjustments. When external patches are unavoidable, document rationale in code comments and PR description.
- Installer: Keep pkg scripts idempotent.
pkgPreInstall.sh/pkgPostInstall.shmust remain sandbox safe.
- Honor language restrictions in new text.
- Update
.stringswhen adding user-visible strings. - Gate new APIs through protocols as needed.
- Run relevant
swift testtargets. - Avoid touching
Source/Dataunless lexicon work is explicitly requested. - Align new keyboard layouts with Tekkon parsers and symbol tables.
Questions from contributors should reference this file first; escalate only when guidance is missing or conflicting.