Skip to content

Latest commit

 

History

History
720 lines (661 loc) · 45.1 KB

File metadata and controls

720 lines (661 loc) · 45.1 KB

CleverKeys TODO

Open Issues — Corrected from GitHub (2026-02-25)

Phase 1 — Simple Fixes (completed)

  • #51 KEYBOARD_OPACITY 81→100 (transparent background on first use)
  • #96 WordListFragment.refresh() preserves search/sort state
  • #50 Swedish language detection patterns added to LanguageDetector
  • IssueRegressionTest.kt — 57 pure JVM tests covering all open bugs

Phase 2 — Close Already-Completed Issues (user will close)

Issues already implemented, need user verification + close:

  • #21 Subkey system (long-press alternate chars) — already closed
  • #48 Context-aware predictions / inline autofill — already closed
  • #50 Swedish language detection — implemented, still open
  • #62 Password manager clipboard exclusion — already closed
  • #70 Programmatic launch via Intent — import/export intent support requested
  • #74 Haptic not disabled when Vibrate Feedback disabled — per-event controls exist
  • #81 Separate Long-Press Repeat for Backspace vs Character — config exists
  • #82 Auto-space before tapped suggestion — new auto_space_before_suggestion toggle (821f943fb)

Bugs — Confirmed Real Issues

  • #30 Per-key short swipe customization to keyboard events does nothing
    • v1.1.7.8, Android 16. Customizing P/O/K/J short swipes to keyboard events
  • #35 Overly dark darkmode — settings app should follow system light/dark
    • User wants system theme follow, not hardcoded dark
  • #55 Crashes on ancient phone — Nexus 6 / Android 11 / LineageOS
    • Keyboard exits immediately on use; likely ONNX or memory issue on old device
  • #71 Opening clipboard causes device freeze for 2-3 seconds
    • v1.2.5, Android 15. Clipboard pane open triggers device-wide stall
  • #75 Swipe behaviour broken on Swiss French QWERTZ layout
    • Pixel 8a, Android 16 LineageOS. Swiping on QWERTZ layout misbehaves
  • #77 Cannot completely disable Greek/Math toggle in custom XML layout
    • v1.2.5, Android 15. bottom_row="false" custom layout, Greek/Math key persists
  • #78 Word prediction doesn't replace typed text (flicker issue)
    • v1.2.5, Android 15. Selecting prediction doesn't replace; text flickers
  • #79 UI/Header flickering at top of screen during settings scrolling
    • v1.2.5, Android 15. Settings menu top area jitters on scroll
  • #83 "Keys per direction" not used on average length swipe
    • v1.2.5, Android 12. Short swipe keys inaccessible at normal swipe length
  • #92 Custom background color ignored in custom themes
    • v1.2.8, Android 16. Background color setting ignored, shows shade of key color
  • #96 Dictionary search resets after dis/enabling a word
    • v1.2.8, Android 16. Already fixed (WordListFragment.refresh preserves state)
  • #104 Turning off compose key breaks touchpad/arrow keys
    • v1.2.9, Android 15. Dpad broken when compose key is disabled

Features — Low/Medium Effort

  • #35 (also feature) Settings dark mode should follow system theme
  • #59 Clipboard delete option + individual item delete + copy timestamps
  • #67 Script error — build_all_languages.py references missing get_wordlist.py
    • python3 build_all_languages.py --lang fr fails; get_wordlist.py not in repo
  • #72 Capitalize suggestions for "I" and proper nouns
    • I and contractions (I'll, I'm, I'd) + names should retain capitalization
  • #84 Smart Punctuation with configurable time threshold
    • Only apply smart punctuation within a time interval; precise formatting needed
  • #87 Long swipes should map to short swipes when swipe typing disabled
    • Currently long swipes treated as taps when swipe typing off; should be short swipes
  • #93 Custom Themes: add hex color input field
    • Sliders are hard to use for precise color matching; hex input requested
  • #94 Copy version info on long press of Version Information modal
    • For easier bug reporting — long press to copy version to clipboard
  • #97 Request to disable/remove English dictionary
    • Polish user: English dictionary suggests wrong words; wants to disable it
  • #99 Unclear/outdated documentation of build_langpack.py
    • Hungarian user tried to build langpack; docs incomplete/outdated
  • #107 Clipboard: Add a Copy button to store text in system clipboard
  • #108 Clipboard: Move re-copied text to top of list (72adabb9f)
  • #109 Improve the look of the autofill suggestion style (72adabb9f)
  • #113 Paste shortcut works in Termux — Ctrl+V fallback for terminal apps (72adabb9f)
  • #110 Cancel autocorrect on backspace
    • Undo-autocorrect exists but not triggered by backspace key specifically

Features — High Effort / Community

  • #26 Docs: clarify language support + update README comparison table
    • README implies broader language support than actual; needs accuracy
  • #31 Next word prediction / Cyrillic layout prediction
    • T9/prediction only works for English; Cyrillic layouts get no suggestions
  • #49 Turkish language support — dictionary + keyboard layout
  • #52 MessageEase layout contribution + gesture tuning concepts
    • Community layout contribution; novel gesture/UX interaction patterns
  • #58 Scaling number keyboard — number pad wastes space, should resize
  • #61 Switch between more than 2 languages actively
  • #68 Greek dictionary — suggestion to use HeliBoard dictionaries
  • #69 Two finger swiping — unique feature request (Nintype-style)
  • #80 Clipboard Suggestion Strip + UI navigation improvements
  • #88 Arabic language support
  • #90 Custom size for keyboard/row — bottom_row="false" sizing bug
  • #101 Autocorrect/gesture recognition training game
    • FUTO-style training mode to improve neural model in safe environment
  • #111 Expanded comparison table for Urik keyboard

Deferred

  • #89 Google Play Store Release — requires Play Store account + compliance

GIF Panel — COMPLETE

  • All 9 implementation steps done. File-picker import working. User has tested and confirmed GIF pack import/removal/display functional.

Completed (2026-02-27)

  • #108 clipboard dedup reorder (72adabb9f):
    • Duplicate clipboard entries now move to top instead of being silently ignored
    • Updates timestamp + expiry on existing row (no delete/reinsert)
  • #113 Termux paste (72adabb9f):
    • Paste key sends Ctrl+V key event in terminal apps (Termux, ConnectBot, etc.)
    • Uses TerminalUtils.isTerminalApp() for detection
    • Added getCurrentEditorInfo() to KeyEventHandler.IReceiver interface
  • #109 autofill chip style (72adabb9f):
    • Larger text (14sp title, 11sp subtitle), 8dp horizontal padding
    • Max chip width uses display width (was hardcoded 740px)
    • Chip background: lighter gray (#353535), subtle border, 20dp corner radius
  • #82 auto_space_before_suggestion (823f2f16e):
    • New boolean toggle: controls leading space before tapped suggestions
    • When disabled: "this:" + tap "english" → "this:english" (no leading space)
    • Swipe auto-inserts always add leading space (preserves word separation)
    • Both code paths gated (SuggestionHandler.kt + InputCoordinator.kt)
    • Settings UI: toggle in Word Prediction section, searchable
  • GIF panel merged to main (6d4e6ca6d):
    • Merged feature/gif-panel-clean branch (39 commits)
    • 866 pure JVM tests pass (790 main + 76 GIF)

Completed (2026-02-25)

  • 56 new instrumented tests (5e4762c33):
    • TypingSimulationTest: +25 tests (REAL_WORD_CONTRACTION_BASES + extended autocorrect)
    • DictionaryDataSourceTest: +19 tests (disabled filtering, shared cache, toggle coherence)
    • VocabularyRankingTest: +12 tests (contraction scoring, trie, paired base handling)
    • TypingSimulationTest refactored to shared singleton predictor (OOM-resilient)
    • ew-cli: 650 tests, 2 OOM flakes (unrelated), 0 real failures
  • 3 UX fixes (b13402e88):
    • Contraction swipe ranking: Promoted contraction vocabulary entries from tier 1 (0.6f freq, 1.0× boost) to tier 2 (0.88f freq, 1.3× boost). Existing binary dict synthetic entries also upgraded. Variant fallback raised to 0.85f. Words like "don't", "doesn't", "she'll" now compete fairly with common words.
    • Disabled words in ACTIVE tab: Added enabled == true filter in WordListFragment.loadWords() and filter() for ACTIVE tab only. Disabled words now only appear in the DISABLED tab as expected.
    • Dictionary Manager slow load: Shared MainDictionarySource cache (50k words + prefix index) across instances via companion object static cache. First open still loads from disk; subsequent opens are instant. Added invalidateCache() method for language changes.
  • Prior session fix (f29fa33eb): Replaced contraction_pairings.json file I/O with curated REAL_WORD_CONTRACTION_BASES constant set (11 words) to avoid false positives ("hes"/"shes"/"intl" are not real English words)

Completed (2026-02-24)

  • 5 prediction/dictionary bug fixes (7c509a3d):
    • Bug 4: Dictionary Manager toggle not updating UI — stale cachedWords in MainDictionarySource.getAllWords(). Fix: DictionaryWord.enabledvar, update cache in-place on toggle (no 50k-word reload)
    • Bug 5: Contraction frequency N+1 perf regression in OptimizedVocabulary.ktgetWordsWithPrefix() called per contraction during scoring. Fix: build contractionFrequencyCache at load time, O(1) lookup in hot path
    • Bug 21: Custom word "Boston" overridden by disabled "boston" in tap typing — isWordDisabled() unconditional. Fix: track customAndUserWords set, exempt from disabled check (custom word wins over disabled)
    • Bug 22: Paired contractions missing for tap-typing (its → it's) — SuggestionHandler only called getNonPairedMapping(). Fix: add pairedContractions map to ContractionManager, inject paired variants
    • Bug 23: Autocorrect not applying contractions (im → I'm) — contraction aliases added to dictionary made autoCorrect() skip them. Fix: track contractionAliases map, check before dictionary containsKey
  • TypingSimulationTest.kt: 37 instrumented end-to-end tests — ALL PASSING on ew-cli
    • Paired contraction lookup (its, well, were, hell)
    • Non-paired contraction mapping (dont, cant, im, wont)
    • Autocorrect contraction expansion with I-capitalization
    • Dictionary toggle cache coherence (toggle + re-fetch without reload)
    • Custom word override of disabled dictionary entries
    • End-to-end typing scenarios (contraction-heavy sentences)
    • Prediction pipeline integration (scores, ordering, empty input)
    • Verified: 675 total instrumented tests, 0 failures (Pixel7 API 34)
  • 3 additional fixes discovered during ew-cli testing (4ba4609, baedaea):
    • Test wiring: TypingSimulationTest missing predictor.setConfig(config) call
    • Contraction aliases: binary dict contains synthetic "dont"/"cant" entries — now uses contraction_pairings.json as real-word authority instead of dict check
    • Paired classification: loadMappings() now loads JSON paired data after binary to fix misclassification of "well"/"were"/"hell" in binary derivation

Completed (2026-02-17)

  • Dictionary pipeline spec + skill: Full architecture documentation
    • docs/specs/english-dictionary-pipeline.md — build flow, contraction system, quality issues
    • .claude/skills/dictionary-pipeline.md — build commands, key files, pitfalls
    • Traced en_enhanced.bin lineage: V1 (upstream 49k) → V3 (curated 52k, 15 typos removed)
    • Identified remaining misspellings: teh, wich, hav still in V3 dictionary
    • Identified vestigial files: en_enhanced.txt (V1, not loaded), contractions_en.json (duplicate)
  • Docs fix: README + wiki langpack commands were broken (missing --input/--dict)
    • Verified all 3 build commands actually run on Termux/ARM64
  • Misspelling detection pipeline: scripts/detect_misspellings.py
    • Multi-stage: whitelist(NLTK 239k + pyspell 160k + hunspell + British + contractions + possessives) → edit-distance-1 matching → zipf frequency gap ≥1.5 → foreign language filter (15 langs)
    • V3 scan results: ~347 wrong plurals, ~592 review candidates in scripts/misspelling_review.txt
    • Consulted Gemini 2.5 Pro via PAL for approach guidance (phonetic + frequency + multi-source whitelist)
    • Updated spec and skill with pipeline documentation

Completed (2026-02-11)

  • #48 autofill fix: 3 changes for inline autofill on password fields
    • Removed password mode block in SuggestionBar.setInlineAutofillView() (was silently blocking all autofill)
    • Added android:supportsInlineSuggestions="true" to method.xml
    • Added error logging for null inflate results in InlineAutofillUtils.kt
  • #50 docs fix: Fixed README.md and wiki language-packs.md (missing --name argument)
  • Comprehensive test expansion: 132 new tests (4 files)
    • TerminalUtilsTest.kt: 28 MockK tests for #70 terminal app detection
    • KeyRepeatLogicTest.kt: 22 MockK tests for #81 backspace-only logic truth table
    • AutoSpaceLogicTest.kt: 25 pure JVM tests for #82 auto-space decision logic
    • IssueRegressionTest.kt: 57 pure JVM tests covering all open issue config defaults
    • Fix #51: KEYBOARD_OPACITY 81→100 (fully opaque default)
    • Fix #96: WordListFragment.refresh()/toggleWord()/deleteWord() preserve search state
    • Fix #50: Swedish character frequency + common word patterns in LanguageDetector
    • LanguageDetectorTest: 4 new Swedish detection instrumented tests
    • ConfigDefaultsTest updated for new opacity default
    • All 781 pure JVM + 176 MockK tests pass
    • Total tests: ~1,561 (781 pure + 176 mock + ~604 instrumented)
  • Persistent memory file: memory/issue-action-plan.md with full phase plan
  • Tier 2 instrumented tests: 58 new tests on emulator.wtf (542 → 600 total)
    • SwipeMLDataStoreTest (36): SQLite CRUD, async store/load, search, pagination, statistics, batch operations, SwipeMLData model (JSON round-trip, validation, dedup, normalization)
    • ClipboardDatabaseTest (39): add/retrieve, expiry, pin/todo management, size limits, export/import round-trip, ClipboardEntry model, ordering, storage stats
    • LanguageDetectorTest enhanced (18 → 30): detectLanguageWithConfidence, detectLanguageFromWordsWithConfidence, unsupported language checks, DetectionResult data class
  • Production bug fix: PersonalizationManager.applyFrequencyDecay
    • Fixed ConcurrentHashMap.Entry.setValue UnsupportedOperationException on API 34
    • Replaced removeIf+setValue with explicit iterate+put/remove pattern
  • OOM test failures fixed: WordPredictorTest + SwipePredictionTest (12 failures → 0)
    • WordPredictorTest: reflection-based 57-word test dictionary injection
    • SwipePredictionTest: OOM guard on NeuralSwipeTypingEngine construction
  • Total test coverage: ~898 local (770 pure + 128 mock) + 600 instrumented = ~1,498 tests

Completed (2026-02-10)

  • Major feature instrumented tests: 94 new tests on emulator.wtf (427 → 521 total)
    • SuggestionRankerTest (20): scoring formula, ranking, merge/dedup, language context, prefix boost
    • PersonalizationManagerTest (23): word frequency, bigrams, predictions, decay bug documentation
    • ContractionManagerTest (23): binary/JSON loading, lookup, possessives, language contractions
    • EditorInfoHelperTest (22): action extraction, label/resource mapping, swap enter flag
    • UserAdaptationManagerTest (22): singleton, selection tracking, multipliers, persistence
    • BackupRestoreManagerTest (12): config/dict export-import round-trip, metadata, screen mismatch
  • Instrumented gap-fill tests: 36 new tests on emulator.wtf (391 → 427 total)
    • PrivacyManagerInstrumentedTest (13): org.json audit trail, exportSettings JSON, full lifecycle
    • DirectBootInstrumentedTest (11): PreferenceManager paths, device-protected storage, copy_preferences all types, checkNeedMigration, DirectBootManager singleton/callback/cleanup
    • DebugLoggingManagerInstrumentedTest (12): BroadcastReceiver register/unregister, debug mode toggle via broadcast, sendDebugLog with real Intent, listener notification, full lifecycle
    • Fixed EmojiSearchTest: testGetEmojiNameForUnknownReturnsNull was wrong — isEmoticon heuristic classifies ASCII strings >2 chars as emoticons, returning "emoticon" not null
    • All 13 MockK-excluded paths now covered by instrumented tests on real Android
  • MockK-based test suite: 128 tests for Android-dependent code (699 → 827 total)
    • PrivacyManagerTest (43): consent, data collection, anonymization, retention, audit trail
    • DirectBootManagerTest (15): singleton lifecycle, unlock detection, DE preferences
    • DirectBootAwarePreferencesTest (4): copy to protected storage, API level branching
    • DebugLoggingManagerTest (9): debug state, listener management, close safety
    • AutocapitalisationTest (12): state machine (started/typed/event_sent/selection/pause)
    • DictionaryManagerTest (14): user word CRUD, legacy migration, language switching, JSON format
    • VibratorCompatTest (11): master/per-event haptic toggles, feedback constants, vibrator fallback
    • SwipePrunerTest (20): already existed, moved from pure to mock runner
    • Added runMockTests Gradle task (JavaExec + android.jar on classpath)
    • Added runAllTests task combining pure (699) + MockK (128) = 827 total
    • Key techniques: Unsafe reflection for SDK_INT on Java 21, mockkStatic with function refs for @JvmStatic, direct field assignment for @JvmField var, Objenesis constructor bypass
    • Excluded paths (require Robolectric): BroadcastReceiver anonymous subclasses, Intent constructors, org.json stubs, PreferenceManager AAR dependency
  • Comprehensive test suite upgrade: 5-agent team, 287 new tests (412 → 699 total)
    • GestureTest: state machine directions, edge cases
    • ModmapTest: modifier key mapping (Shift/Fn/Ctrl)
    • ComposeKeyPureTest: compose key sequence constants
    • KeyValueParserTest: 73 tests for key definition parsing (named keys, keyevents, macros, flags)
    • CoordinateNormalizerTest: coordinate normalization, key sequence extraction, QWERTY bounds
    • TrajectoryFeatureCalculatorTest: velocity/acceleration from trajectory points
    • NeuralPredictionPureTest: 32 tests salvaged from Robolectric (data classes, quality tiers)
    • IntegrationPureTest: 14 tests salvaged from Robolectric (pipeline integration)
    • onnx/PrefixBoostTrieTest: binary trie loading, prefix boost, failure links
    • onnx/BroadcastSupportTest: tensor shape broadcasting rules
    • SwipePrunerTest: written but excluded from pureTestClasses (requires android.util.Log + MockK)
    • Fixed 12 test failures: parser syntax mismatches, reflection exception wrapping, dedup logic
    • All 699 tests pass on ARM64 via ./gradlew runPureTests

Completed (2026-02-09)

  • Website, Wiki & CI review and fixes: 3-agent review + 4-agent fix team
    • Wiki: Added 6 missing pages to wiki-config.json (FAQ, quick-settings, password-fields, smart-punctuation, user-dictionary, profiles)
    • Wiki: Created docs/wiki/layouts/profiles.md from orphaned HTML (was missing source)
    • Wiki: Regenerated all 42 wiki HTML pages + updated search-index.json (was 36, now 42)
    • Workflows: Deleted redundant setup-pages.yml (conflicted with deploy-web-demo.yml)
    • Workflows: Pinned aquasecurity/trivy-action@0.28.0 (was @master, security risk)
    • Workflows: Added permissions blocks to build.yml and build-apk.yml
    • Specs: Fixed generate-specs.js template (meta viewport, table rendering, code blocks)
    • Specs: Regenerated all 12 spec HTML pages with improved quality
    • Homepage: Synced content with README.md, improved demo placeholder
    • Deploy: Updated workflow to copy search-index.json and all wiki assets
  • Intent action type review fixes: addressed 13 issues from 3-agent code review
    • CRITICAL: Fixed setData/setType mutual clearing → setDataAndType()
    • CRITICAL: Fixed executeCommand always returning true (discarded when result)
    • Added null-safe Gson deserialization (IntentDefinition.parseFromGson) for Unsafe bypass
    • Added INTENT_PREFIX constant to IntentDefinition (DRY with KeyValueParser)
    • Fixed URI validation: scheme check instead of useless try/catch on Uri.parse()
    • Extended package validation to SERVICE and BROADCAST targets
    • Fixed single-quote escaping in XmlAttributeMapper TEXT round-trip
    • Fixed CommandPaletteDialog label max (hardcoded 8 → MAX_DISPLAY_LENGTH=4)
    • IntentEditorDialog: removed unused imports, .values()→.entries, variable shadowing fix, added contentDescription for accessibility, deduplicate extras before add
    • Compilation verified on ARM64 Termux (1186 classes, 0 errors)
  • Intent feature unit tests: comprehensive pure JVM test coverage
    • Created ShortSwipeIntentTest.kt with 55 tests covering all non-Android functionality
    • IntentDefinition.parseFromGson: null-safety, default values, malformed JSON handling
    • IntentDefinition.PRESETS: validation of all 11 preset intents
    • ActionType: fromString case-insensitivity, enum values, display info
    • ShortSwipeMapping: constants, factory methods, getIntentDefinition(), storage keys
    • XmlAttributeMapper.toXmlValue: TEXT quotes, COMMAND mapping, KEY_EVENT prefix, INTENT JSON escaping
    • ShortSwipeCustomizations: round-trip storage format conversion
    • AvailableCommand: fromString, groupedByCategory, display properties
    • All tests follow existing patterns (Truth assertions, @Test annotations, pure JVM)
    • Registered in build.gradle pureTestClasses list for ARM64 runner
  • Spec updated with INTENT action type: docs/specs/short-swipe-customization.md
    • Added IntentDefinition data class, IntentTargetType enum, parseFromGson docs
    • Added intent validation rules (action/package, installed check, URI scheme)
    • Added execution flow (setDataAndType pitfall, dispatch by target type)
    • Added 11 intent presets table, XML round-trip format, factory/accessor methods
    • Updated architecture diagram, key files table, ActionType enum, storage format example
  • Cleanup: restored squoosh submodule to committed pointer, added .tmp-*.sh to .gitignore

Completed (2026-02-04)

  • Intent action type for short swipe customization: complete feature implementation
    • Added ActionType.INTENT enum with full serialization support
    • IntentDefinition data class with 11 common presets (browser, share, dial, email, settings, camera, maps, search, termux command)
    • IntentEditorDialog with edit mode, preset selection via FlowRow chips
    • KeyValueParser intent: syntax for XML import/export round-trip
    • Intent validation: package existence check, URI validation, activity resolution
    • canExecuteIntent() for UI validation before saving
    • getIntentDefinition() helper on ShortSwipeMapping
    • XmlAttributeMapper uses quoted JSON: intent:'json'
    • All 357 tests pass

Completed (2026-02-02)

  • BeamSearchEngine testability refactor: extracted DecoderSessionInterface, OrtDecoderSession adapter
    • BeamSearchEngine now fully ONNX-free (all tensor ops behind interface)
    • Shared processLogitsForBeam() eliminates seq/batch duplication
    • Replaced android.util.Log with debugLogger callback
    • 12 beam search tests: scoring, trie masking, batched parity, temperature, dedup
  • calculateMatchQuality fix: non-edit-distance mode now uses maxLen denominator
    • "cat" vs "caterpillar" was 1.0 (wrong), now 3/11 ≈ 0.27 (correct)
  • selectMiddleIndices exposed: internal visibility + 5 weighted distribution tests
  • Pipeline integration tests: 7 tests chaining SwipeResampler → BeamSearchEngine → VocabularyTrie → VocabularyUtils → AccentNormalizer
  • Gradle runPureTests task: JavaExec-based JVM test runner, no proot needed
    • Usage: ./gradlew runPureTests [-PtestClass=ClassName]
  • ONNX Runtime aarch64 native libs: tested, blocked by glibc dependency (libdl.so.2 not available on Termux/bionic). Real inference benchmarks require Android instrumented tests.
  • ✅ Test suite: 357 tests across 12 classes, all passing

Completed (2026-01-29)

  • ✅ Settings UI: moved Batch Processing, Greedy Search, ONNX Threads from main settings to NeuralSettingsActivity
  • ✅ Settings UI: replaced Advanced Neural Settings expander with "Full Neural Settings" button
  • ✅ Settings UI: replaced Reset Defaults with Cancel button in NeuralSettingsActivity
  • ✅ Wiki audit: completed full pass of ALL ~35 wiki pages against source code
  • ✅ Wiki audit: fixed ALL 39 HTML bottom nav buttons (broken relative paths)
  • ✅ Wiki audit: fixed installation page (minSdk 21 not 26, ~25MB not 65MB, correct permissions)
  • ✅ Wiki audit: added Obtainium and F-Droid installation instructions
  • ✅ Wiki audit: fixed first-time-setup default height (30%/40% not 100%)
  • ✅ Wiki audit: fixed neural-settings (ONNX threads default 2 not "auto", max length 20 not "varies")
  • ✅ Wiki audit: fixed common-issues (removed nonexistent "Export Debug Info", removed "Android 16")
  • ✅ Wiki audit: fixed basic-typing (suggestion bar best-match-on-left, removed nonexistent long-press)
  • ✅ Wiki audit: fixed smart-punctuation (double-space location → Gesture Tuning)
  • ✅ Wiki audit: updated neural-settings page for removed Advanced section → Full Neural Settings button
  • ✅ Wiki audit: verified all remaining pages against source code (typing, gestures, customization, settings, clipboard, troubleshooting, layouts, FAQ)
  • ✅ Spec files: created neural-settings-spec.md with source references
  • ✅ Spec files: updated installation-spec, setup-spec, haptics-spec, appearance-spec with source location tables
  • ✅ Deep line-by-line wiki audit (batches 7-10, 35+ pages re-verified):
    • swipe-typing.md: fixed suggestion bar layout (Center/Left/Right → left-to-right by confidence)
    • swipe-typing.md: fixed "Encoder-only" → "Encoder-decoder transformer"
    • autocorrect.md: removed fabricated "tap prediction twice to never autocorrect"
    • special-characters.md: major rewrite — removed fabricated long-press popup section entirely
    • emoji.md: fixed tooltip duration 2.5s → 2s (code: 2000ms)
    • short-swipes.md: fixed long press comparison ("Popup menu" → "Key repeat")
    • extra-keys.md: removed fabricated "Drag to reorder", "Key Order/Size" settings
    • per-key-actions.md: removed fabricated "Reset Customizations Only", "Export Profile"
    • neural-settings.md: fixed "Max Sequence Length" → "Max Word Length", encoder-decoder
    • clipboard-history.md: fixed Per-Key Customization path (added "Activities >")
    • shortcuts.md: removed fabricated "Long-press settings key", "Long-press paste", "Double-tap paste"
    • text-selection.md: fixed TrackPoint activation ("Long swipe from spacebar" → "Long-press nav key")
    • performance.md: removed fabricated "key popup" reference
    • backup-restore.md: fixed all paths to include "Activities >" prefix
    • reset-defaults.md: fixed "Export/Import Settings" → "Export/Import Config"
    • multi-language.md: removed "Long-press or" from subkey access

Completed (2026-01-22)

  • ✅ Emoji long-press tooltip (PopupWindow, positioned above pressed emoji)
  • ✅ Emoji name lookup with Unicode fallback for unmapped emojis
  • ✅ Emoticon search keywords (shrug, lenny, tableflip, kaomoji, etc)
  • ✅ Emoticon grid overlap fix (padding, minHeight, grid spacing)
  • ✅ Flag emoji name mappings (260+ countries, shows "japan" not "regional indicator")
  • ✅ Emoticon name mappings (100+ smileys/kaomoji, shows "shrug" not "emoticon")
  • ✅ Cleanup: removed debug logs from KeyboardReceiver, unused tooltip XML files
  • ✅ Updated wiki (emoji.md) and spec (suggestion-bar-content-pane.md)
  • ✅ Created skills: emoji-panel.md, content-pane-layout.md
  • ✅ Created release-process.md skill (F-Droid API, fastlane changelogs, version codes)
  • ✅ Released v1.2.6 - Emoji Panel Polish (tooltip, name mappings, gap fixes)
  • ✅ Fixed clipboard history limit slider (0-500, 0 = unlimited) (#85)
  • ✅ GitHub issues triage (memory/issue-triage-2026-01-22.md)
  • ✅ Clipboard tabs: History (📋), Pinned (📌), Todos (✓) with icon-only UI
  • ✅ Close buttons for emoji/clipboard panes (#80)
  • ✅ Database migration v2: added is_todo column
  • ✅ Backwards-compatible todo export/import (export_version 2)
  • ✅ Fixed emoji close button triggering wrong event
  • ✅ Clipboard pagination (100 items per page, search all items)
  • ✅ Fixed clipboard import (fresh expiry, correct count indices)
  • ✅ Option to disable auto-space after suggestion (#82)
  • ✅ Separate backspace key repeat option (#81)
  • ✅ Respect Greek/Math disabled in numeric layer (#77)
  • ✅ Password manager clipboard exclusions: KeePassDX Libre, Chrome, Edge, Firefox (#86)
  • ✅ Android 13+ IS_SENSITIVE flag support (user setting, defaults on) (#86)
  • ✅ Created ew-cli testing skill (.claude/skills/ew-cli-testing.md)
  • ✅ Settings toggles now update Config immediately (fixes #81, #82 taking effect)
  • ✅ Added SettingsToggleTest for #81, #82, #86 verification
  • ✅ Fixed auto-space after tap suggestion (#82) - bug was in SuggestionHandler.kt
  • ✅ Fixed autocapitalization toggle not updating Config immediately
  • ✅ Added missing "Capitalize I Words" toggle UI (#72)
  • ✅ Fixed swipe capitalization after period (_mods not updated in set_shift_state)
  • ✅ Debug settings defaults: show_raw_output and show_raw_beam_predictions now OFF
  • ✅ Fixed raw predictions appearing at front of suggestions (now stay at end)
  • ✅ Added SettingsToggleTest tests for debug defaults, autocapitalization, I-words
  • ✅ All ew-cli instrumented tests passing
  • ✅ Fixed swipe predictions not applying user word case preservation (proper nouns)
  • ✅ Created wiki-documentation.md skill for consistent docs
  • ✅ Created user-dictionary wiki + spec pair (proper noun case preservation)
  • ✅ Fixed Android user dictionary case preservation (both sync/async loading paths)
  • ✅ Test keyboard fields use KeyboardCapitalization.Sentences (splash + settings)
  • ✅ Splash screen animation pauses when keyboard opens (eliminates input lag)
  • ✅ Smart punctuation respects manual spacebar (only attaches if space was auto-inserted)
  • ✅ Created smart punctuation wiki + spec pair (user guide + technical spec)
  • ✅ Fixed swipe capitalization at swipe START (captures shift state when swipe begins)
  • ✅ Smart punct adds space after sentence-ending punct (. ! ?) for autocap trigger
  • ✅ Fixed Capitalize I Words for swipe (use globalConfig in InputCoordinator/SuggestionHandler)
  • ✅ Renamed "Prediction Tap" to "Suggestion Tap" in haptic settings
  • ✅ Fixed master vibration toggle not updating Config.haptic_enabled immediately
  • ✅ Added SWIPE_COMPLETE haptic trigger when swipe word is auto-inserted
  • ✅ Moved vibration/haptic settings to Accessibility section
  • ✅ Fixed vibration not triggering (vibrate_custom must be true for duration to work)
  • ✅ v1.2.8 released (includes all v1.2.6 changes for F-Droid)
  • ✅ Verified Direct Boot safety: swipe_on_password_fields, dictionary loading all use DirectBootAwarePreferences

Completed (2026-01-27)

  • ✅ Wiki hallucination fixes (batch 4 - 6 pages from subagent audit):
    • privacy.md: removed fabricated Personal Dictionary/Usage Patterns sections
    • privacy.md: fixed clipboard settings (50 items, not 24h duration)
    • language-packs.md: removed fabricated download UI and server browsing
    • language-packs.md: corrected to file import via Backup & Restore
    • autocorrect.md: fixed settings path to Word Prediction section
    • autocorrect.md: removed fabricated "Suggest Contact Names" setting
    • user-dictionary.md: removed fabricated "Long-Press on Suggestion" method
    • common-issues.md: fixed all settings paths to actual section names
    • common-issues.md: removed fabricated "Prediction Bar Height" setting
    • performance.md: removed fabricated "Background Processing" setting
    • performance.md: removed fabricated "Prediction Count" setting
  • ✅ Final verification audit (batch 5 - 3 pages):
    • adding-layouts.md: removed fabricated "Language Packs" activity
    • per-key-actions.md: fixed path "Customization" → "Activities"
    • extra-keys.md: fixed path to "Activities > Extra Keys"
  • ✅ Comprehensive line-by-line audit (batch 6 - 10 fixes from deep verification):
    • short-swipes.md: fixed path "Settings > Customization" → "Settings > Activities > Per-Key Customization"
    • short-swipes.md: fixed location "Input Behavior" → "Gesture Tuning" for Enable Short Swipes
    • clipboard-history.md: fixed default capacity "25 items" → "50 items"
    • timestamp-keys.md: fixed path "Settings → Layout → Extra Keys" → "Settings → Activities → Extra Keys"
    • timestamp-keys.md: fixed path "Settings → Per-Key Customization" → "Settings → Activities → Per-Key Customization"
    • language-packs.md: fixed 3 paths missing "Activities" level for Backup & Restore
    • adding-layouts.md: removed fabricated "Language Packs activity" reference
    • backup-restore.md: fixed fabricated "View Collected Data" path → "Privacy & Data section"
    • themes.md: fixed path "Settings > Backup & Restore" → "Settings > Activities > Backup & Restore"
  • ✅ All 69 wiki pages audited, all settings paths verified against SettingsActivity.kt

Completed (2026-01-26)

  • ✅ Added "Calibrate Per-Key Gestures" as third setup box on launcher screen
  • ✅ Updated calibration activity text: "trigger up to 8 subkey actions per key based on direction"
  • ✅ Created FAQ document (docs/wiki/FAQ.md) covering common questions
  • ✅ Added Help & FAQ section to Settings (bottom, collapsible with expandable FAQ items)
  • ✅ Added "Open Full Wiki" button linking to https://tribixbite.github.io/CleverKeys/wiki
  • ✅ Made FAQ searchable via Settings search
  • ✅ Fixed 240px overflow in calibration slider (50dp → 60dp)
  • ✅ Added shared PerKeyCustomizationButton composable (DRY between Settings/Calibration)
  • ✅ Corrected FAQ content with verified code behavior:
    • Q subkey: NORTHEAST not north
    • Spacebar cursor: proportional to distance
    • TrackPoint: long-press nav keys, not spacebar
    • Emoji: switch_emoji event, layout-dependent
    • Removed non-existent long-press popup references
  • ✅ Wiki audit: identified extensive hallucinations in multiple pages (accessibility, themes, backup-restore, layouts)
  • ✅ Further FAQ corrections:
    • TrackPoint: only nav key (between spacebar and enter), not generic "nav keys"
    • Language switch: primary/secondary toggle, not switch_forward/switch_backward
    • Emoji: SW on Fn key, not Ctrl
    • Added clipboard FAQ (Fn swipe, History/Pinned/Todos tabs)
  • ✅ Calibration step persistence: shows checked forever after first click
  • ✅ Wiki hallucination fixes (batch 1 - 5 pages):
    • FAQ.md synced with SettingsActivity (DRY)
    • installation.md: Android 5.0 not 8.0
    • accessibility.md: rewrote with actual features (haptics/sound only)
    • backup-restore.md: removed fabricated auto-backup, QR, cloud features
    • themes.md: corrected to 35+ themes
  • ✅ Wiki hallucination fixes (batch 2 - 7 pages):
    • appearance.md: removed fabricated presets, animation, pop-up settings
    • input-behavior.md: removed fabricated auto-cap modes, delete behavior
    • cursor-navigation.md: removed fabricated Home/End on 'A' key
    • first-time-setup.md: fixed Haptics→Accessibility, beam max 10→20
    • swipe-typing.md: removed Neural Profile, Prediction Count
    • custom-layouts.md: removed fabricated visual editor (it's text-based XML)
    • adding-layouts.md: removed fabricated "Programmer" layout
  • ✅ Wiki hallucination fixes (batch 3 - 6 pages):
    • haptics.md: section name Haptics→Accessibility
    • neural-settings.md: removed Show Suggestions, Neural Profiles
    • trackpoint-mode.md: fixed trigger to nav key (not arrow keys)
    • emoji.md: removed fabricated long-press Enter/comma access
    • clipboard-history.md: fixed NW→SW, removed long-press features
    • short-swipes.md: fixed numbers direction N→NE

Pre-Release Audit (v1.3.0-rc — feature/gif-panel-clean)

Feature Changelog Since v1.2.9

New Features:

  1. GIF Panel (Offline) — Full offline GIF system with no INTERNET permission
    • File-picker import of ZIP packs (SAF/ACTION_OPEN_DOCUMENT)
    • V4→V5 schema: FTS4 search, pack management, gif_pack_membership table
    • Category browsing (17 emotion categories + Recently Used + All)
    • GIF search via keyboard, compound word fallback (eyeroll → eye* roll*)
    • Tap inserts Giphy URL, long-press shows copy/share PopupWindow
    • Pagination (100 items/page) matching clipboard pattern
    • Settings UI: enable toggle, grid columns, import/remove/list packs
    • Share intent filter for ZIP files
    • 7 new source files: Gif, GifCategory, GifDatabase, GifAssetManager, GifPackManager, GifGridView, GifGroupButtonsBar
  2. Intent Action Type for Short Swipes — Launch Android intents from swipe gestures
    • IntentDefinition data class with 12 presets (browser, share, termux, maps, etc.)
    • IntentEditorDialog with preset chips + full custom editing
    • Termux: background + visible tab presets with SESSION_ACTION
    • Toast feedback on all dispatch failures
    • KeyValueParser intent:'json' syntax for XML round-trip
  3. Discord GIF Pack Pipeline — Build packs from real Discord usage data
    • build_discord_pack.py: metadata→convert→thumbnail→pack.db→ZIP
    • backfill_metadata.py: Tenor URL resolution + media_url slug parsing
    • Category-based pack builder (build_all_packs.py) with 7 groups
    • Byte-based splitting (~100 MB per pack for GitHub downloads)

Bug Fixes:

  • Fix: Gif.matchesQuery() case-insensitive (was only lowering query, not searchText)
  • Fix: PopupWindow isFocusable=false (prevents content pane disappearing on long-press)
  • Fix: GIF search routing through KeyEventReceiverBridge
  • Fix: FTS5→FTS4 migration (FTS5 not available on all Android builds)
  • Fix: Termux intent SESSION_ACTION + background/visible presets
  • Fix: Intent dispatch toast feedback on all failure paths

Test Coverage:

Infrastructure:

  • BeamSearchEngine testability refactor (ONNX-free, DecoderSessionInterface)
  • Pipeline integration tests with fake decoder
  • calculateMatchQuality length mismatch fix

Regression Risk Matrix (Manual Testing)

Area Risk What to Test Why
GIF panel open/close HIGH Enable GIFs → tap GIF key → panel opens → tap again → closes New panel may interfere with emoji/clipboard panel state
GIF import HIGH Settings → Import Pack → select ZIP → verify count Core new feature, ATTACH DATABASE could fail on edge cases
GIF search HIGH Open GIF panel → type search → results update New search routing through KeyEventReceiverBridge
GIF long-press MED Long-press GIF → popup menu → Copy/Share PopupWindow focus steal fixed but needs device testing
GIF pagination MED Scroll to bottom → "Next" button → page 2 loads Offset-based queries, boundary conditions
GIF pack remove MED Settings → remove pack → verify GIFs gone DELETE + VACUUM + file cleanup chain
Keyboard typing HIGH Normal typing, swipe typing, autocorrect Any regression in core typing is critical
Short swipe intents MED Configure Termux intent → swipe → command runs New executor paths with toast feedback
Emoji/clipboard panels MED Open emoji → close → open clipboard → close GIF panel shares ViewFlipper with these
Content pane switching HIGH GIF → emoji → clipboard → close → type → reopen Panel state machine with 3 panels + keyboard
Settings search LOW Search "GIF" → settings appear New searchable entries added
Profile export/import LOW Export profile → import on fresh install Intent mappings in export format
FTS4 search quality MED Search "laughing" → relevant results FTS4 compound word tokenization
Pack ZIP validation LOW Import corrupt/invalid ZIP → graceful error Error handling in GifPackManager
Memory under load MED Import large pack (5000+ GIFs) → browse → type Coil image loading + RecyclerView recycling

Test Commands

# Build and install release APK
cd ../cleverkeys-gif-module && ./build-on-termux.sh

# Run all pure JVM tests (857 tests)
./gradlew runPureTests

# Run single test class
./gradlew runPureTests -PtestClass=GifTest

In Progress

  • 🔄 Subkey System Unification (Option D) - awaiting user answers to clarifying questions
    • See: memory/subkey-unification-research.md
  • 🔄 GIF Panel (Offline) — merged to main, pending device testing
    • Spec: docs/specs/gif-panel-spec.md
    • Release: https://github.com/tribixbite/CleverKeys/releases/tag/CleverKeys-GIF (prerelease)
    • Architecture: No INTERNET permission. ZIP pack import via file picker (SAF).
    • Schema: V5 with FTS4, gif_pack_membership table
    • All 9 implementation steps complete + bug fixes applied
    • Discord community pack: 6 ZIPs (575 MB, 5,232 GIFs) on GitHub pre-release
    • Remaining:
      • Test import of discord-community packs on device
      • Build release APK and install on device
      • Manual regression testing (see Regression Risk Matrix above)
      • Verify: search "eyeroll", long-press popup, pagination controls
      • Rebuild Giphy packs with updated pipeline (compound word indexing)
      • Publish packs to GitHub Releases
      • Legal review of GIF content redistribution

Completed (2026-01-25)

  • ✅ Subkey system investigation: XML subkeys, ShortSwipeCustomizationActivity, ExtraKeys
  • ✅ Created research doc with Options A-D analysis
  • ✅ Documented 5 clarifying questions for Option D implementation

Completed (2026-01-24)

  • ✅ French contraction frequency ordering (qu'est can now appear before quest if higher frequency)
  • ✅ Full AndroidX migration (ExtraKeysPreference, ListGroupPreference)
  • ✅ Added ONNX JVM runtime for unit tests (onnxruntime:1.20.0)

Completed (2026-01-23)

  • ✅ Fixed French contractions showing both forms (quest + qu'est)
  • ✅ Fixed CI test failures (ComposeKeyTest, OnnxPredictionTest)
  • ✅ Partial AndroidX migration (PreferenceManager classes)
  • ✅ Fixed 3 broken wiki links

Completed (2026-01-20)

  • ✅ Swedish language pack (sv_enhanced.bin, sv.bin, sv_unigrams.txt)
  • ✅ Emoticons category in emoji picker (#76) - 119 text emoticons
  • ✅ Tests for resolved issues (#41 emoji search, #71 clipboard, #72 I-words)
  • ✅ Tests for swipe sensitivity presets (Low/Medium/High/Custom)
  • ✅ Emoticons display fix (length-based text scaling for kaomoji)
  • ✅ Emoji/clipboard toggle behavior (tap to open/close)
  • ✅ Gap fix: ViewFlipper swaps suggestion bar/content pane with dynamic height
  • ✅ App-switch reset: Content pane state resets when keyboard hides

Code TODOs

SettingsActivity.kt:3434

Error Reports toggle has no backend

  • Toggle is hidden in UI
  • Need async file logging implementation
  • Low priority

Investigations

English Words in French-Only Mode

  • Issue: English words appear when Primary=French, Secondary=None
  • Diagnostic: Logging added in commit 83ea45f7
  • Debug: adb logcat | grep "getVocabularyTrie\|loadPrimaryDictionary"
  • Files: OptimizedVocabulary.kt, SwipePredictorOrchestrator.kt

Long Word Prediction

  • Fix applied: Length normalization in beam search (22fc3279)
  • Verify: Swipe "dangerously" in SwipeDebugActivity
  • Check: Confidence values are length-normalized

Features

Settings UI Polish

  • Standardize units across distance settings (px vs dp vs %)
  • Move Vibration settings to Accessibility section (v1.2.8)
  • Move Smart Punctuation to Auto-Correction section

Web Demo P2

  • Lazy loading for 12.5MB models
  • PWA/Service Worker for offline support

Legacy Code Cleanup

  • Migrate deprecated android.preference.* to androidx.preference.* (v1.2.10)

Documentation

  • Consolidate duplicate specs (top-level → wiki/specs)
  • See docs/DOCS_AUDIT.md for full analysis

Reference

Build

./build-on-termux.sh          # Full build + install
./gradlew compileDebugKotlin  # Compilation check

Test

# Instrumented (emulator.wtf) — 600 tests, 0 failures
ew-cli --app build/outputs/apk/debug/CleverKeys-v1.2.9-x86_64.apk \
       --test build/outputs/apk/androidTest/debug/CleverKeys-debug-androidTest.apk \
       --device model=Pixel7,version=34

# Local JVM (Gradle — preferred)
./gradlew runPureTests                           # 781 pure JVM tests
./gradlew runMockTests                           # 176 MockK tests (needs android.jar)
./gradlew runAllTests                            # all ~957 tests
./gradlew runPureTests -PtestClass=ClassName     # single class (pure)
./gradlew runMockTests -PtestClass=ClassName     # single class (mock)

Key Files

Purpose File
Settings Config.kt
Settings UI SettingsActivity.kt
Swipe prediction SwipePredictorOrchestrator.kt
Word prediction WordPredictor.kt
Gesture handling Pointers.kt

Archive: memory/archive/todo/ Docs: docs/TABLE_OF_CONTENTS.md