Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8fa3135
Expose in-process dictionary generation for native preparation callers
nervouna Oct 4, 2026
0d0969c
Record Swift consumer parity through the Rust dictionary ABI
nervouna Oct 4, 2026
385b5e8
Use one Rust dictionary generator for preparation and the Swift worker
nervouna Oct 4, 2026
2e2e1c6
Keep Swift generator reference access within the test target
nervouna Oct 4, 2026
e80071b
Prepare target-native resources and package Rust dictionary notices
nervouna Oct 5, 2026
3d793c7
Port equivalent-span ranking and capture the Swift reference
nervouna Oct 5, 2026
a302e20
Verify 291 ranking cases against the unchanged Swift implementation
nervouna Oct 5, 2026
50f448a
Record ranking parity and add read-only Linux target inspection
nervouna Oct 5, 2026
a5c679c
Generate the context-ranking index from the Rust dictionary generator
nervouna Oct 8, 2026
5ab72b0
Port session policy to the Rust engine and compare it with the Swift …
nervouna Oct 8, 2026
faee8df
Port personal-learning management and portable personal data to the R…
nervouna Oct 8, 2026
000f233
Capture Rust engine performance with the recorded macOS headless prot…
nervouna Oct 8, 2026
bf31bc3
Export the frontend-facing C ABI of the Rust engine
nervouna Oct 8, 2026
735f8c4
Add the Fcitx5 addon skeleton over the engine C ABI
nervouna Oct 8, 2026
477d9d5
Add the Fcitx5 configuration surface and the personal-data import ent…
nervouna Oct 8, 2026
8a4c968
fix(linux): install and verify the Fcitx5 addon on ARM64 Omarchy
nervouna Oct 9, 2026
9d76112
feat(linux): package and manage user-local Fcitx5 installations
nervouna Oct 9, 2026
ce3d2e2
fix(linux): preserve recovery state across interrupted shutdowns
nervouna Oct 9, 2026
dec1f3f
fix(linux): prepare package resources in a fresh staging directory
nervouna Oct 9, 2026
d7490e5
docs(linux): record managed Omarchy installation verification
nervouna Oct 9, 2026
a385c59
fix(fcitx5): keep the engine off until import recovery succeeds and t…
nervouna Oct 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The implemented baseline. Recheck the sources linked from the [skill entrypoint]
7. **Mixed decoding is native, filtering is customized.** The supplemental dictionary imports `pinyin_simp`; Rime's `script_translator` performs segmentation and sentence generation with completion disabled. Lua emits only candidates reaching the current segment end and containing both ASCII letters and non-ASCII bytes. Public rows still require every contiguous ASCII run in the output to be an exact entry in the admitted mixed dictionary, cached only for the current input. This prevents separately admitted fragments such as `WOMEN` and `S` from reconstructing an excluded `WOMENS`. The byte test assumes the dictionary's Chinese/English contents; it is not a general Han-script detector. Partial results and pure Chinese/English results are filtered out. Unknown Latin tails are not appended as a mixed fallback. The translator qualities `-0.5` for mixed and `-1` for standalone English shape the native stream but are not the final ordering policy for equivalent page candidates.
8. **Personal mixed decoding uses real native spans.** `InkFlowRimeNative` registers `inkflow_mixed_personal` after every Rime initialization. For input up to `mixed_personal/max_input_length` (64 bytes by default), a one-row native predictive lookup prunes impossible prefixes; non-predictive lookup retains every exact, positively confirmed display variant from `inkflow_shared_english.userdb`. A real personal edge is inserted between native dictionary/syllabifier graphs of its actual surroundings; native `Poet` chooses a complete path through that edge. No input rewriting, invented syllable IDs, personal prefix completion, first-N lexicon scan, rebuild or new store is used. Mixed candidates retain component provenance and original input cursor spans. Their distinct read-only language has no corresponding Memory, so neither Chinese nor English learns the assembled sentence. The translator-lifetime reader never changes transactions during queries.
9. **Ambiguity and boundaries use native spelling evidence.** An unmarked lowercase personal code is excluded if it is one letter or a complete sequence of normal native Pinyin spellings. Actual uppercase input supplies explicit English intent; stored uppercase display alone does not. Native normal spans in the uncut input reject cuts inside reachable surrounding syllables. Abbreviation, correction and fuzzy paths are not evidence for this rejection. Both surroundings need complete native coverage. Personal display is one printable nonspace ASCII run, including aliases such as `cpp` → `C++`; adjacent public ASCII output cannot join it. Public ASCII runs remain independently admitted. All exact display variants remain distinct. Preedit derives from real input slices and native formatting, and candidate text retains exact stored display. Over-limit input uses the ordinary Chinese/public paths. This general policy replaces the former personal short-code blacklist.
10. **Compilation and Pinyin.** The dependency-only `easy_en` schema compiles literal English independently of Pinyin algebra. The mixed and primary schemas retain the `n/l` `ue`→`ve` and `j/q/x/y` `u`→`v` spelling derivations. `prepare-spelling.sh` and the dictionary update worker share `IFSpellingGenerator` to generate 32 dependency-only Chinese prisms for abbreviation, typo tolerance and three independent fuzzy pairs; all reuse the original Chinese table/user dictionary. Automatic typo aliases cannot occupy legal full syllables from the generated dictionary and the profile's normal/fuzzy equivalents. Native algebra guards the final aliases after combined typo transformations; legal-to-legal typos lose that automatic alias, while explicit fuzzy pairs remain available. The main schema includes the generated profile 2 algebra. The mixed schema has no generic abbreviation, so English words are not abbreviated. Abbreviation can add full-coverage Chinese candidates ahead of existing mixed results without changing ranking policy; test recall and exact selection instead of a fixed mixed first position. The main speller accepts upper/lower ASCII letters and declares space/apostrophe delimiters. These remain native Pinyin delimiters, not an English phrase-input API; `xi'an` continues to produce 西安.
10. **Compilation and Pinyin.** The dependency-only `easy_en` schema compiles literal English independently of Pinyin algebra. The mixed and primary schemas retain the `n/l` `ue`→`ve` and `j/q/x/y` `u`→`v` spelling derivations. `prepare-spelling.sh` and the dictionary update worker share the Rust spelling generator under `Core/Portable/dictionary/` (the worker calls it through `IFSpellingGenerator`) to generate 32 dependency-only Chinese prisms for abbreviation, typo tolerance and three independent fuzzy pairs; all reuse the original Chinese table/user dictionary. Automatic typo aliases cannot occupy legal full syllables from the generated dictionary and the profile's normal/fuzzy equivalents. Native algebra guards the final aliases after combined typo transformations; legal-to-legal typos lose that automatic alias, while explicit fuzzy pairs remain available. The main schema includes the generated profile 2 algebra. The mixed schema has no generic abbreviation, so English words are not abbreviated. Abbreviation can add full-coverage Chinese candidates ahead of existing mixed results without changing ranking policy; test recall and exact selection instead of a fixed mixed first position. The main speller accepts upper/lower ASCII letters and declares space/apostrophe delimiters. These remain native Pinyin delimiters, not an English phrase-input API; `xi'an` continues to produce 西安.
11. **Canonical English learning is isolated.** The original Chinese dictionary/translator and `pinyin_simp.userdb` remain independent. Standalone English uses Rime `Phrase`/`ShadowCandidate` selection learning in the named `inkflow_shared_english.userdb`. Records keep the exact displayed text with a lowercase normalized Latin lookup code, so `Hello` selected through `Hello` is recalled by `hello` without changing its display. Mixed decoding keeps its own user dictionary disabled and only reads exact committed records from that shared namespace; displaying or selecting a mixed candidate does not update the record. Only selecting a learnable standalone English candidate updates this namespace. Display, raw Return, cancellation, immediate undo, and ordinary Chinese selection do not learn English.
12. **Selection and editing share the existing engine/controller.** Paging, number/space selection, backspace, cursor edits, cancellation and session isolation are not separate English features. Swift stores a display-to-native permutation and applies every selection through its original native index. A selected standalone English completion learns its canonical full dictionary code, not the typed prefix. Any selected prefix bypasses final ranking; clearing or ending a composition discards its bounded preceding context. Unknown metadata preserves native order, and partial candidates remain selectable in their original slots.
13. **Explicit ASCII mode is native passthrough.** It does not consult either dictionary and remains available for excluded words. A standalone left Shift press-release toggles the requested mode; using left Shift as a modifier and pressing right Shift do not toggle. Shift and menu changes wait for the current composition to commit or cancel. ASCII punctuation is literal and does not overwrite the persisted Chinese punctuation preference. The compilation-only English/mixed/spelling schemas do not add separate selectable input sources.
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,14 @@ jobs:
run: bash Core/Portable/dictionary/test.sh

scripts:
name: Remote runner tests
name: Script and frontend helper tests
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- name: Test scripts/mac-remote.py
run: python3 -B scripts/tests/test_mac_remote.py
- name: Test Linux installer and frontend helpers
run: |
python3 -B Linux/scripts/test_install.py
bash Linux/fcitx5/test.sh
8 changes: 7 additions & 1 deletion Core/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ let package = Package(
.executableTarget(name: "AIAdoptionLearningTests", dependencies: ["InkFlowDomain", "InkFlowRime", "InkFlowCoreTestSupport"], path: "Tests/AIAdoptionLearningTests", swiftSettings: strictSwiftSettings, linkerSettings: buildRimeRuntime),
.executableTarget(name: "RankingTests", dependencies: ["InkFlowRankingTestSupport"], path: "Tests/RankingTests", swiftSettings: strictSwiftSettings, linkerSettings: buildRimeRuntime),

.target(name: "InkFlowDomain", swiftSettings: strictSwiftSettings),
.target(name: "InkFlowDictionary", path: "Sources/InkFlowDictionary",
publicHeadersPath: "include",
cSettings: [.unsafeFlags(["-I\(repository.path)/build/dictionary/include"])],
linkerSettings: [.unsafeFlags(["-L\(repository.path)/build/dictionary/cargo/release"]),
.linkedLibrary("inkflow_dictionary"), .linkedLibrary("resolv"), .linkedLibrary("iconv")]),
.target(name: "InkFlowDomain", dependencies: ["InkFlowDictionary"], path: "Sources/InkFlowDomain",
swiftSettings: strictSwiftSettings),
.target(name: "CRime", dependencies: ["InkFlowRimeNative"], publicHeadersPath: "include",
cSettings: strictCSettings + [.unsafeFlags(["-I\(dependencyRoot)/include"])],
linkerSettings: rimeLinkerSettings),
Expand Down
121 changes: 121 additions & 0 deletions Core/Portable/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Core/Portable/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ build = "build.rs"

[lib]
path = "src/lib.rs"
crate-type = ["rlib", "cdylib", "staticlib"]

[dependencies]
serde_json = "=1.0.151"
unicode-normalization = "=0.1.25"
unicode-segmentation = "=1.13.3"
Loading
Loading