# nervouna/inkflow architecture

> Architecture diagram of the GitHub repository nervouna/inkflow, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nervouna/inkflow
- Repository: https://github.com/nervouna/inkflow

## Overview

InkFlow is a local macOS Pinyin input method. Its main workflow routes keystrokes from the host application through the InputMethodKit controller into the Rime engine, presents candidates, and inserts the selected text. Separate capabilities support on-device dictation, optional AI suggestions and voice polishing, dictionary updates, and personal-data management. The README documents these product branches; the sampled source confirms parts of input routing, engine interaction, and voice delivery, so unsampled subsystem wiring is shown only where documented.

Main entry points: [`macOS/Sources/InputController.swift`](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/InputController.swift) (Input controller), [`Core/Sources/InkFlowRime/Engine.swift`](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/Engine.swift) (Rime engine), [`macOS/Sources/InputControllerVoice.swift`](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/InputControllerVoice.swift) (Voice input), [`Core/Sources/InkFlowRime/DictionaryCoordinator.swift`](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/DictionaryCoordinator.swift) (Dictionary updates)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_input["Input runtime"]
  node_input_controller["Input controller"]
  node_input_core["Key routing"]
  node_engine_events["Key translation<br/>[EngineEvent.swift]"]
  node_candidate_view["Candidate presentation"]
end

subgraph group_engine["Rime engine"]
  node_engine["Rime engine<br/>[Engine.swift]"]
  node_native_rime["Native Rime bridge"]
  node_domain["Input domain"]
end

subgraph group_personal["Personalization"]
  node_voice_learning["Voice learning"]
  node_custom_phrases["Custom phrases"]
  node_learning["Personal learning"]
  node_personal_data["Personal data backup"]
  node_quality["Input quality records"]
  node_quality_store[("Quality store<br/>[QualityStore.swift]")]
end

subgraph group_optional["Optional assistance"]
  node_voice["Voice input"]
  node_recognizer["Speech recognition"]
  node_ai["AI suggestions"]
  node_voice_polish["Voice polishing"]
end

subgraph group_management["Settings and maintenance"]
  node_dictionary["Dictionary updates"]
  node_dictionary_worker["Dictionary worker<br/>[main.swift]"]
  node_dictionary_store[("Dictionary state")]
  node_settings["Input settings<br/>[Settings.swift]"]
  node_installer["Installer"]
  node_input_sources["System input sources"]
end

node_host(("Host app"))
node_ai_service{{"Configured AI service"}}
node_apple_speech{{"Apple speech services"}}
node_user_data[("User data directory")]
node_github{{"GitHub"}}

node_host -->|"sends keystrokes"| node_input_controller
node_input_controller -->|"routes events"| node_input_core
node_input_core -->|"translates keys"| node_engine_events
node_engine_events -->|"processes input"| node_engine
node_input_controller -->|"reads state"| node_engine
node_input_controller -->|"presents candidates"| node_candidate_view
node_candidate_view -->|"inserts selection"| node_host
node_engine -->|"calls native API"| node_native_rime
node_engine -->|"uses preferences"| node_domain
node_input_controller -->|"reads settings"| node_settings
node_settings -->|"applies options"| node_engine
node_input_controller -->|"handles voice gestures"| node_voice
node_voice -->|"transcribes audio"| node_recognizer
node_recognizer -.->|"uses on-device recognition"| node_apple_speech
node_voice -->|"previews and inserts text"| node_host
node_voice -.->|"requests polishing"| node_voice_polish
node_voice_polish -.->|"sends transcript"| node_ai_service
node_voice -->|"coordinates learning"| node_voice_learning
node_voice_learning -->|"updates learned entries"| node_learning
node_input_controller -.->|"offers input context"| node_ai
node_ai -.->|"requests suggestions"| node_ai_service
node_ai -.->|"records adoption"| node_engine
node_input_controller -->|"manages phrases"| node_custom_phrases
node_custom_phrases -->|"loads phrases"| node_engine
node_input_controller -->|"manages learned entries"| node_learning
node_input_controller -->|"records input outcomes"| node_quality
node_quality -->|"writes records"| node_quality_store
node_quality_store -->|"persists locally"| node_user_data
node_learning -->|"stores learning data"| node_user_data
node_custom_phrases -->|"stores phrases"| node_user_data
node_personal_data -->|"backs up or restores"| node_user_data
node_input_controller -->|"exposes dictionary controls"| node_dictionary
node_dictionary -->|"dispatches work"| node_dictionary_worker
node_dictionary -->|"reads and writes state"| node_dictionary_store
node_dictionary -.->|"downloads updates"| node_github
node_installer -->|"registers and enables"| node_input_sources
node_installer -->|"installs input method"| node_host

click node_input_controller "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/InputController.swift"
click node_input_core "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/InputControllerCore.swift"
click node_engine_events "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/EngineEvent.swift"
click node_candidate_view "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/CandidatePresentation.swift"
click node_engine "https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/Engine.swift"
click node_native_rime "https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRimeNative/InkFlowRimeNative.cpp"
click node_domain "https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowDomain/InputPreferences.swift"
click node_dictionary "https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/DictionaryCoordinator.swift"
click node_dictionary_worker "https://github.com/nervouna/inkflow/blob/main/macOS/DictionaryWorker/main.swift"
click node_dictionary_store "https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/DictionaryStore.swift"
click node_settings "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/Settings.swift"
click node_voice "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/InputControllerVoice.swift"
click node_recognizer "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/AppleVoiceRecognizer.swift"
click node_voice_learning "https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowDomain/VoiceLearningCoordinator.swift"
click node_ai "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/AISuggestionCoordinator.swift"
click node_voice_polish "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/VoiceCorrectionClient.swift"
click node_custom_phrases "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/CustomPhrases.swift"
click node_learning "https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/EnginePersonalLearning.swift"
click node_personal_data "https://github.com/nervouna/inkflow/blob/main/macOS/Sources/PersonalDataBackup.swift"
click node_quality "https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/QualityRecorder.swift"
click node_quality_store "https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/QualityStore.swift"
click node_installer "https://github.com/nervouna/inkflow/blob/main/macOS/Installer/InstallerCoordinator.swift"
click node_input_sources "https://github.com/nervouna/inkflow/blob/main/macOS/Shared/InputSourceManager.swift"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_input_controller,node_input_core,node_engine_events,node_candidate_view toneBlue
class node_engine,node_native_rime,node_domain,node_user_data toneAmber
class node_voice_learning,node_custom_phrases,node_learning,node_personal_data,node_quality,node_quality_store toneMint
class node_voice,node_recognizer,node_ai,node_voice_polish toneRose
class node_dictionary,node_dictionary_worker,node_dictionary_store,node_settings,node_installer,node_input_sources,node_host,node_ai_service,node_apple_speech,node_github toneIndigo
```

## Components

### Input runtime

- [Input controller](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/InputController.swift): `macOS/Sources/InputController.swift`
- [Key routing](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/InputControllerCore.swift): `macOS/Sources/InputControllerCore.swift`
- [Key translation](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/EngineEvent.swift): `macOS/Sources/EngineEvent.swift`
- [Candidate presentation](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/CandidatePresentation.swift): `macOS/Sources/CandidatePresentation.swift`

### Rime engine

- [Rime engine](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/Engine.swift): `Core/Sources/InkFlowRime/Engine.swift`
- [Native Rime bridge](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRimeNative/InkFlowRimeNative.cpp): `Core/Sources/InkFlowRimeNative/InkFlowRimeNative.cpp`
- [Input domain](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowDomain/InputPreferences.swift): `Core/Sources/InkFlowDomain/InputPreferences.swift`

### Personalization

- [Voice learning](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowDomain/VoiceLearningCoordinator.swift): `Core/Sources/InkFlowDomain/VoiceLearningCoordinator.swift`
- [Custom phrases](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/CustomPhrases.swift): `macOS/Sources/CustomPhrases.swift`
- [Personal learning](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/EnginePersonalLearning.swift): `Core/Sources/InkFlowRime/EnginePersonalLearning.swift`
- [Personal data backup](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/PersonalDataBackup.swift): `macOS/Sources/PersonalDataBackup.swift`
- [Input quality records](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/QualityRecorder.swift): `Core/Sources/InkFlowRime/QualityRecorder.swift`
- [Quality store](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/QualityStore.swift): `Core/Sources/InkFlowRime/QualityStore.swift`

### Optional assistance

- [Voice input](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/InputControllerVoice.swift): `macOS/Sources/InputControllerVoice.swift`
- [Speech recognition](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/AppleVoiceRecognizer.swift): `macOS/Sources/AppleVoiceRecognizer.swift`
- [AI suggestions](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/AISuggestionCoordinator.swift): `macOS/Sources/AISuggestionCoordinator.swift`
- [Voice polishing](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/VoiceCorrectionClient.swift): `macOS/Sources/VoiceCorrectionClient.swift`

### Settings and maintenance

- [Dictionary updates](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/DictionaryCoordinator.swift): `Core/Sources/InkFlowRime/DictionaryCoordinator.swift`
- [Dictionary worker](https://github.com/nervouna/inkflow/blob/main/macOS/DictionaryWorker/main.swift): `macOS/DictionaryWorker/main.swift`
- [Dictionary state](https://github.com/nervouna/inkflow/blob/main/Core/Sources/InkFlowRime/DictionaryStore.swift): `Core/Sources/InkFlowRime/DictionaryStore.swift`
- [Input settings](https://github.com/nervouna/inkflow/blob/main/macOS/Sources/Settings.swift): `macOS/Sources/Settings.swift`
- [Installer](https://github.com/nervouna/inkflow/blob/main/macOS/Installer/InstallerCoordinator.swift): `macOS/Installer/InstallerCoordinator.swift`
- [System input sources](https://github.com/nervouna/inkflow/blob/main/macOS/Shared/InputSourceManager.swift): `macOS/Shared/InputSourceManager.swift`

### Other components

- **Host app**
- **Configured AI service**
- **Apple speech services**
- **User data directory**
- **GitHub**

## Connections

- Host app → Input controller: sends keystrokes
- Input controller → Key routing: routes events
- Key routing → Key translation: translates keys
- Key translation → Rime engine: processes input
- Input controller → Rime engine: reads state
- Input controller → Candidate presentation: presents candidates
- Candidate presentation → Host app: inserts selection
- Rime engine → Native Rime bridge: calls native API
- Rime engine → Input domain: uses preferences
- Input controller → Input settings: reads settings
- Input settings → Rime engine: applies options
- Input controller → Voice input: handles voice gestures
- Voice input → Speech recognition: transcribes audio
- Speech recognition → Apple speech services: uses on-device recognition
- Voice input → Host app: previews and inserts text
- Voice input → Voice polishing: requests polishing
- Voice polishing → Configured AI service: sends transcript
- Voice input → Voice learning: coordinates learning
- Voice learning → Personal learning: updates learned entries
- Input controller → AI suggestions: offers input context
- AI suggestions → Configured AI service: requests suggestions
- AI suggestions → Rime engine: records adoption
- Input controller → Custom phrases: manages phrases
- Custom phrases → Rime engine: loads phrases
- Input controller → Personal learning: manages learned entries
- Input controller → Input quality records: records input outcomes
- Input quality records → Quality store: writes records
- Quality store → User data directory: persists locally
- Personal learning → User data directory: stores learning data
- Custom phrases → User data directory: stores phrases
- Personal data backup → User data directory: backs up or restores
- Input controller → Dictionary updates: exposes dictionary controls
- Dictionary updates → Dictionary worker: dispatches work
- Dictionary updates → Dictionary state: reads and writes state
- Dictionary updates → GitHub: downloads updates
- Installer → System input sources: registers and enables
- Installer → Host app: installs input method
