{"id":49721681,"url":"https://github.com/radislabus-star/lay-public","last_synced_at":"2026-05-23T02:12:12.976Z","repository":{"id":356179009,"uuid":"1231379943","full_name":"radislabus-star/lay-public","owner":"radislabus-star","description":"Double Shift RU/EN layout rescue for GNOME, KDE, Wayland and X11","archived":false,"fork":false,"pushed_at":"2026-05-16T22:59:32.000Z","size":2138,"stargazers_count":64,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-17T00:31:02.650Z","etag":null,"topics":["gnome","kde","keyboard","keyboard-layout","linux","linux-desktop","plasma","russian","rust","wayland","x11"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/radislabus-star.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-06T22:55:15.000Z","updated_at":"2026-05-16T22:59:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/radislabus-star/lay-public","commit_stats":null,"previous_names":["radislabus-star/lay-public"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/radislabus-star/lay-public","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radislabus-star%2Flay-public","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radislabus-star%2Flay-public/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radislabus-star%2Flay-public/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radislabus-star%2Flay-public/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/radislabus-star","download_url":"https://codeload.github.com/radislabus-star/lay-public/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/radislabus-star%2Flay-public/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33379721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T01:21:08.577Z","status":"online","status_checked_at":"2026-05-23T02:00:05.530Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gnome","kde","keyboard","keyboard-layout","linux","linux-desktop","plasma","russian","rust","wayland","x11"],"created_at":"2026-05-09T02:20:48.689Z","updated_at":"2026-05-23T02:12:12.968Z","avatar_url":"https://github.com/radislabus-star.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# lay\n\n**Спасатель неправильной RU/EN раскладки для Linux**\n\n**Double Shift RU/EN layout rescue for Linux desktops**\n\n**Статус проекта: alpha.** `lay` уже можно использовать каждый день, но это\nранняя версия: автокоррекция, KDE/X11 backend и edge cases в разных\nприложениях ещё активно оттачиваются.\n\nНапечатал слово не в той раскладке? Нажми **Shift два раза** и продолжай писать.\n\nУстановить:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/radislabus-star/lay-public/main/scripts/install-remote.sh | bash\n```\n\nОбновить уже установленный `lay`:\n\n```bash\ncd ~/projects/lay \u0026\u0026 bash update.sh\n```\n\n[![Rust](https://img.shields.io/badge/Rust-1.75+-orange?logo=rust)](https://www.rust-lang.org/)\n[![GNOME](https://img.shields.io/badge/GNOME-45--47%2C%2050-4A86CF?logo=gnome)](https://gnome.org/)\n[![Wayland](https://img.shields.io/badge/Wayland-native-blue)](https://wayland.freedesktop.org/)\n[![Status](https://img.shields.io/badge/status-alpha-yellow)](#status-alpha)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green)](#license)\n\n\u003c/div\u003e\n\n## Русский\n\n### Что такое lay\n\n\u003e **Status: alpha.** Проект живой и рабочий, но пока не обещает идеальную\n\u003e автокоррекцию во всех приложениях и desktop-окружениях. Основной стабильный\n\u003e сценарий сейчас — ручное исправление RU/EN раскладки по double Shift.\n\n`lay` — локальный клавиатурный помощник для Linux-пользователей, которые часто\nпишут в двух раскладках, прежде всего **русской и английской**.\n\nГлавная задача программы — быстро исправлять текст, набранный не в той\nраскладке, прямо в активном приложении. Без копирования через буфер обмена, без\nоблачного сервиса и без обязательной LLM-модели.\n\nГлавный сценарий простой:\n\n```text\nНапечатал: Ghbdtn\nНажал:     Shift Shift\nПолучил:   Привет\n```\n\n![lay demo](docs/publicity/demo.gif)\n\n`lay` не пытается “угадать всё за тебя”. Базовое поведение ручное и\nпредсказуемое: ошибся раскладкой, нажал двойной Shift, последнее слово\nперепечаталось в другой раскладке.\n\nДополнительно есть осторожная помощь при наборе после пробела: исправление\nявных RU/EN layout-ошибок, простых опечаток и точных пользовательских замен.\nАвтопомощь должна быть консервативной: если уверенности мало, текст лучше не\nтрогать.\n\nОсновная проверенная среда сейчас **GNOME Wayland**, но проект уже не\nGNOME-only. Внутри: Rust, evdev/uinput и backend-слой для переключения\nраскладки. GNOME backend использует маленькое расширение GNOME Shell;\nKDE/Plasma использует отдельный tray и `qdbus6`; X11 backend использует native\nXKB через `x11rb`.\n\nВнутренняя архитектура теперь разделена на общее ядро, decoder и\ndesktop-интеграции. `lay::core` содержит конвертацию раскладки, LEM/ngram\nscoring, decoder-контракты и правила определения backend; `lay::decoder`\nрешает, что делать с хвостом текста: оставить, перепечатать физические клавиши\nили заменить минимальный BAD-диапазон. GNOME Shell extension остаётся отдельной\nоболочкой для GNOME-трея, DBus bridge и активации раскладки. KDE/Plasma\nиспользует отдельный `lay-kde-tray`, который читает тот же config и управляет\nтем же daemon.\n\n### Возможности\n\n- Двойной Shift исправляет последнее слово, набранное не в той раскладке.\n- Работает прямо в приложениях, без копирования текста через буфер обмена.\n- Поддерживает GNOME Wayland через маленькое Shell-расширение.\n- Поддерживает KDE/Plasma через отдельный tray и backend на `qdbus6`.\n- Поддерживает X11 через native XKB backend на `x11rb`.\n- Есть быстрый CLI для конвертации текста из терминала.\n- Есть аккуратная помощь при наборе после пробела.\n- Есть точная автоподмена по пользовательскому словарю.\n- Есть режим `ptah_alexs`: жёсткая привязка раскладки к выбранным окнам.\n- Основной режим локальный: без облака, без сетевых запросов и без модели.\n- Есть optional multi-tap Shift scope: `2/3/4` тапа могут выбирать `1/2/3`\n  слова. Режим выключен по умолчанию.\n\n### Языки, раскладки и словари\n\nСейчас `lay` рассчитан на пару раскладок **RU/EN**.\n\nЧто поддержано:\n\n- физическая конвертация US ↔ RU;\n- русские и английские Hunspell-словари, если они есть в системе;\n- встроенные локальные правила для RU/EN layout-ошибок;\n- char n-gram и LEM-скоринг для коротких RU/EN кандидатов;\n- пользовательские точные правила в `~/.config/lay/replacements.json`;\n- пользовательский защитный список в `~/.config/lay/protected_words.txt`.\n\nЧто пока не обещается:\n\n- украинская, немецкая, французская и другие пары раскладок;\n- полноценный грамматический автокорректор;\n- универсальная замена Punto/xneur для всех языков и desktop-окружений;\n- IME/preedit-подсказки прямо внутри поля ввода.\n\nЕсли нужна другая пара раскладок, лучше открыть issue и приложить конкретные\nпримеры: что набрано, что должно получиться, какая раскладка и какой desktop.\n\n### Сценарии использования и настройки\n\n`lay` можно оставить почти как простой Punto/Caramba-style переключатель, а\nможно постепенно включать дополнительные слои. Все основные настройки доступны\nиз трея и сохраняются в `~/.config/lay/config.json`.\n\n#### 1. Исправить последнее слово вручную\n\nСамый безопасный сценарий:\n\n```text\nghbdtn -\u003e привет\n```\n\nНабрал слово не в той раскладке, нажал Shift два раза, `lay` удаляет последнее\nслово, переключает раскладку и перепечатывает те же физические клавиши в другой\nраскладке.\n\nЭто ручной режим. Он нужен даже тогда, когда автопомощь выключена или не\nуверена.\n\n#### 1a. Только double Shift, без автокоррекции\n\nЕсли нужна максимально предсказуемая утилита без вмешательства после пробела,\nоставь включённым только ручное исправление:\n\n```json\n{\n  \"typing_assist\": false,\n  \"auto_replace\": false,\n  \"auto_switch_layout\": false\n}\n```\n\nВ трее это соответствует выключенным пунктам:\n\n- `Помощь при наборе`;\n- `Автоподмена`;\n- `Авто-layout после пробела`.\n\nDouble Shift при этом продолжит работать. Это хороший режим для тех, кто хочет\nтолько Caramba/Punto-style rescue и не хочет никакой автоматической правки.\n\n#### 2. Исправлять 1, 2 или 3 слова\n\nВ трее есть настройка области исправления. Она отвечает за то, сколько слов\nслева от курсора `lay` может взять в работу при double Shift.\n\n- `1 слово`: максимально предсказуемый режим.\n- `2 слова`: удобно для смешанных фраз, например `good ntrcn -\u003e good текст`.\n- `3 слова`: полезно, если несколько слов подряд набраны в другой раскладке.\n\nОбласть и “мозг” исправления разделены. Два или три слова не означают LLM.\nСначала работают быстрые локальные правила, словари, LEM/ngram scoring и\nзащита хороших слов.\n\n#### 3. Smart или Replay\n\n`Replay` — прямой режим: взять хвост и физически перепечатать его в другой\nраскладке.\n\n`Smart` — режим по умолчанию: `lay` смотрит на слова отдельно и старается не\nтрогать те части хвоста, которые уже выглядят нормальными.\n\nПример:\n\n```text\ngood ntrcn -\u003e good текст\n```\n\nЗдесь `good` остаётся на месте, а исправляется только `ntrcn`. Это быстрее и\nменьше ломает смешанный RU/EN текст.\n\n#### 4. Помощь при наборе после пробела\n\n`Помощь при наборе` включается в трее. Она срабатывает после пробела и\nисправляет только короткий завершённый хвост, если сигнал достаточно сильный.\n\nЧто может исправлять:\n\n- явное слово в другой раскладке;\n- простую перестановку соседних букв;\n- пропущенную или лишнюю букву;\n- случайно склеенные или разорванные слова;\n- точную пользовательскую замену из словаря.\n\nЧто важно: это не “творческий автокорректор”. Если вариантов несколько или\nуверенность слабая, нормальное поведение — ничего не менять.\n\n#### 5. Автоподмена\n\n`Автоподмена` — это точные правила, а не угадывание. Они лежат в:\n\n```text\n~/.config/lay/replacements.json\n```\n\nТакой режим хорош для повторяющихся личных ошибок и коротких устойчивых замен.\nЕсли правило слишком широкое и начинает мешать, его лучше убрать из словаря, а\nне усложнять код исключениями.\n\n#### 6. LEM-арбитр\n\nLEM — локальный скоринг вариантов. Он не генерирует текст, а сравнивает готовые\nкандидаты и выбирает более естественный вариант, если разница уверенная.\n\nВ трее можно включать/выключать LEM для 2 и 3 слов. Это помогает в смешанных\nRU/EN фразах, где простое “перевернуть всё” было бы неправильным.\n\n#### 7. Жёсткая раскладка по окну: ptah_alexs\n\n`ptah_alexs` — режим для окон, где раскладка должна быть фиксированной.\n\nПример:\n\n- терминал всегда EN;\n- чат всегда RU;\n- конкретное приложение не трогать.\n\nЭто не “запомнить последнюю раскладку окна”, а жёсткое правило: при фокусе\nвыбранного окна `lay` ставит нужную раскладку.\n\n#### 8. Прямые хоткеи RU / EN\n\nМожно включить отдельные клавиши, которые не исправляют слово, а просто\nпереключают язык напрямую:\n\n- одна клавиша всегда ставит RU;\n- другая всегда ставит EN.\n\nЭто удобно, если хочется не циклическое переключение, а точный “поставь русский”\nили “поставь английский”.\n\n#### 9. KDE, GNOME, X11\n\nОдна и та же логика `lay-daemon` работает через разные desktop backend'ы:\n\n- GNOME: Shell extension + DBus bridge;\n- KDE/Plasma: `qdbus6` и отдельный KDE tray;\n- X11: native XKB через `x11rb`.\n\nЕсли backend выбран как `auto`, `lay` пытается определить окружение сам. Если\nнужно зафиксировать явно:\n\n```json\n{\n  \"layout_backend\": \"gnome\"\n}\n```\n\nили:\n\n```json\n{\n  \"layout_backend\": \"kde\"\n}\n```\n\nили:\n\n```json\n{\n  \"layout_backend\": \"x11\"\n}\n```\n\n#### 10. Экспериментальный IME backend\n\nОбычный production-путь использует `uinput`: `lay` стирает хвост и печатает\nнужный текст как виртуальная клавиатура. Это работает широко, но у такого\nподхода есть естественные края: приложение может не успеть принять Backspace,\nа compositor может ещё держать физический Shift.\n\nВ проекте есть экспериментальный IBus/IME bridge. Его цель другая: не\nсинтезировать клавиши, а попросить input method удалить committed tail и\nвставить replacement через `delete_surrounding_text + commit_text`.\n\nВключается явно:\n\n```json\n{\n  \"text_backend\": \"ime\"\n}\n```\n\nВажно:\n\n- по умолчанию используется `\"text_backend\": \"uinput\"`;\n- IME bridge требует активный IBus engine `Lay IME RU` или `Lay IME US`;\n- если bridge недоступен или нет фокуса, daemon откатывается на uinput;\n- режим считается экспериментальным и нужен для испытаний GNOME Wayland\n  приложений, где uinput иногда даёт крайние эффекты.\n\n#### 11. Если не хватает настройки\n\nПроект уже достаточно настраиваемый, но клавиатурные привычки у всех разные.\nЕсли не хватает режима, backend'а, хоткея или защиты для конкретного сценария,\nлучше завести короткий issue на GitHub:\n\n```text\nhttps://github.com/radislabus-star/lay-public/issues\n```\n\nХороший issue содержит:\n\n- что было набрано;\n- что ожидалось;\n- что получилось;\n- GNOME/KDE/X11 и версия системы;\n- включены ли `Помощь при наборе`, `Автоподмена`, `Smart`, LEM.\n\n### Статус\n\nЭто ранняя публичная beta-версия.\n\nОсновная проверенная среда: Ubuntu/GNOME Wayland с RU/EN раскладками.\nРасширение заявляет поддержку GNOME Shell 45, 46, 47 и 50.\n\nKDE Plasma и X11 backend также проверены в нашей тестовой VM. Это уже рабочие\nпути, но покрытие по чужим дистрибутивам и версиям Plasma/X11 пока меньше, чем\nпо GNOME:\n\n- `layout_backend = \"gnome\"`: GNOME Shell extension + DBus bridge.\n- `layout_backend = \"kde\"`: `qdbus/qdbus6 org.kde.keyboard /Layouts setLayout`\n  и отдельный `lay-kde-tray`.\n- `layout_backend = \"x11\"`: native XKB через `x11rb`; shell-tools\n  `xkb-switch`, `xkblayout-state` и `setxkbmap` остаются только fallback.\n- `text_backend = \"uinput\"`: стабильный способ удаления/вставки через\n  виртуальную клавиатуру.\n- `text_backend = \"ime\"`: экспериментальный IBus bridge для\n  `delete_surrounding_text + commit_text`; включается вручную и падает обратно\n  на uinput, если bridge не готов.\n\nДругие версии GNOME, дистрибутивы, Sway, Hyprland и раскладки кроме RU/EN могут\nпотребовать доработок.\n\nЕсли присылаешь баг-репорт или пример набора, сначала убери приватный текст.\n\n### Похожие проекты и ниша lay\n\n`lay` не пытается объявить себя единственным правильным способом работы с\nраскладками. В Linux уже есть родственные проекты и подходы:\n\n- **xneur** — классический авто-переключатель для X11-сценариев. Исторически\n  важный проект, но текущий `lay` изначально строился вокруг GNOME Wayland,\n  evdev/uinput и ручного double Shift.\n- **easy-switcher** — близкая по боли утилита для переключения/исправления\n  раскладки. `lay` делает упор на локальное replay-поведение, RU/EN smart-tail\n  и tray-настройки для GNOME/KDE.\n- **NSkbd**, **Tapper**, **Mahou** и похожие инструменты закрывают соседние\n  сценарии: хоткеи, layout switching, Windows-подходы или более широкую\n  автоматику.\n- **Punto / Caramba Switcher** — понятный пользовательский ориентир: быстро\n  исправить слово, набранное не в той раскладке. `lay` берёт именно этот\n  рефлекс, но адаптирует его под Linux desktops и ограничения Wayland.\n\nГлавная ниша `lay`: лёгкий локальный RU/EN helper, где ручной double Shift\nостаётся главным и предсказуемым действием, а автопомощь можно включать только\nнастолько, насколько она не мешает.\n\n### Установка\n\nОбычная установка ставит всё сразу: Rust-бинарники, user systemd-сервис\n`lay-daemon` и GNOME Shell extension.\n\nКороткая установка одной командой:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/radislabus-star/lay-public/main/scripts/install-remote.sh | bash\n```\n\nОна поставит базовые зависимости, Rust, скачает `lay` в `~/projects/lay` и\nзапустит `install.sh`.\n\nУстановщик умеет ставить системные пакеты через `apt`, `pacman`, `dnf` и `yum`.\nНа неподдерживаемом дистрибутиве он не угадывает пакеты сам: поставь Rust,\ngit/curl/build tools, XCB, `wl-clipboard` и `xclip` вручную, затем запусти\n`bash install.sh`.\n\nРучной вариант:\n\n```bash\ngit clone https://github.com/radislabus-star/lay-public.git ~/projects/lay\ncd ~/projects/lay\nbash install.sh\n```\n\nПосле установки выйди из сессии и зайди снова. Это нужно, чтобы применились\nгруппа `input`, GNOME extension или KDE tray.\n\nПотом набери слово не в той раскладке и нажми **Shift два раза**.\n\n### Обновление\n\nЕсли `lay` уже установлен стандартным способом в `~/projects/lay`, обновление\nодной командой:\n\n```bash\ncd ~/projects/lay \u0026\u0026 bash update.sh\n```\n\nСкрипт сначала проверяет удалённую ветку. Если новых коммитов нет, он пишет,\nчто версия актуальна, и ничего не пересобирает. Если обновления есть, делает\n`git pull --ff-only`, пересобирает release-бинарники, обновляет GNOME extension\nи перезапускает `lay-daemon`.\n\nДля KDE/X11 используется та же команда. GNOME extension там не нужен, но\n`update.sh` всё равно обновит бинарники и перезапустит `lay-daemon`. В KDE он\nтакже обновит KDE tray. Трей в KDE запускается через desktop autostart:\n`~/.config/autostart/lay-kde-tray.desktop`, поэтому после перезагрузки он\nпоявляется вместе с графической сессией.\n\nТо же действие есть в трее:\n\n- GNOME: `Проверить обновления`;\n- KDE: `Проверить обновления`.\n\nКнопка открывает терминал, показывает ход проверки/установки и пишет лог сюда:\n\n```text\n~/.local/state/lay/update.log\n```\n\n### X11 diagnostics\n\nЕсли проверяешь X11 backend на новой реальной X11-сессии,\nсначала собери короткий отчёт:\n\n```bash\nlay-test-input x11-diagnostics\n```\n\nКоманда не создаёт виртуальную клавиатуру и ничего не печатает в активное окно.\nОна показывает выбранный backend, `XDG_SESSION_TYPE`, `DISPLAY`, состояние\nnative XKB через `x11rb` и доступность fallback tools: `xkb-switch`,\n`xkblayout-state`, `setxkbmap`.\n\nДля GitHub issue можно сразу получить готовый блок отчёта:\n\n```bash\nlay-test-input x11-report\n```\n\nДля ручного smoke-test выстави:\n\n```json\n{\n  \"layout_backend\": \"x11\"\n}\n```\n\nПосле этого перезапусти демон:\n\n```bash\nsystemctl --user restart lay-daemon\n```\n\nПроверка: набрать `ghbdtn`, нажать Shift два раза, ожидаемый результат —\n`привет`.\n\n### Что нового\n\nПоследние изменения публичной ветки:\n\n- `0.1.192` — `protected_words.txt` теперь защищает и ASCII-токены, включая\n  короткие слова вроде `vs`, а раздел `Коррекция` в GNOME tray снова вынесен\n  отдельным пунктом, а не спрятан внутрь `Арбитра`. `Pause` также доступен\n  как основной триггер исправления, а не только как прямой RU/EN хоткей.\n- `0.1.191` — live-автозамена получила контекстный `layout_en_to_ru` слой:\n  одиночное `'nj` и смешанный текст вроде `worked 'nj` теперь исправляются в\n  `это`, но технические хвосты вроде `git`, `wi-fi`, `status;` не запускают\n  рискованную автоподмену. Добавлен короткий regression-набор из четырёх\n  смешанных предложений, где каждое второе слово набрано в противоположной\n  раскладке.\n- `0.1.190` — начат архитектурный разнос ядра: lexical data вынесены из\n  production-правил в `data/lexicon`, добавлен platform-neutral `engine`\n  для manual correction, а GNOME daemon начал использовать этот общий слой.\n  Также усилен общий split/scoring для склеенных коротких русских слов без\n  добавления частных слов в runtime-код. Normal-режим автозамены стал\n  осторожнее: спорные грамматические догадки оставлены для experimental.\n- `0.1.189` — after-space автозамена больше не теряется при быстром наборе:\n  daemon запускает проверку сразу на нажатии пробела, удерживая физический\n  ввод на время замены, чтобы пробел в конце сохранился.\n- `0.1.188` — автозамена снова строго after-space: `?`/`!` сами по себе не\n  запускают typing assist. Если физический Shift ещё зажат после `Shift+7`,\n  daemon ждёт отпускания Shift и только потом печатает исправление своим\n  виртуальным вводом.\n- `0.1.187` — typing assist научился чинить текущее слово после завершающих\n  `?`/`!` без ожидания следующего пробела. Это закрывает класс ошибок вроде\n  случайного внутреннего регистра `улУЧШИТЬ?` → `улучшить?`, но незавершённое\n  слово без пунктуации по-прежнему не трогается во время набора. В `0.1.188`\n  этот эксперимент отменён: реальная автозамена ждёт пробел.\n- `0.1.186` — релиз стабилизации typing assist после боевых логов:\n  автозамена стала осторожнее с опасными догадками, Enter-autocorrect теперь\n  реально управляется настройкой, добавлен откат и журнал последних действий,\n  исправлены ложные правки вроде небезопасного `ь -\u003e ъ`, съедания пробела после\n  автозамены и разрезания слов по коротким предлогам (`из водитель`-подобные\n  случаи).\n- `0.1.185` — добавлен компактный журнал последних действий и режим\n  осторожности коррекции. В трее появились `Последние действия` и выбор\n  `Строго / Норма / Эксп.`, а manual smart-replace теперь сохраняет полный\n  undo-контекст для отката результата.\n- `0.1.184` — исправлен layout после минимальной замены текущего хвоста.\n  Сценарии вроде русского `;`, набранного как `Shift+4`, теперь заменяются на\n  `$` и оставляют активную раскладку по вставленному хвосту, а не по всей\n  окружающей русской фразе.\n- `0.1.183` — auto-undo переведён на общий `TextReplacement` insert helper.\n  Откат автозамены теперь использует тот же путь вставки текста и\n  восстановления курсора, что typing assist, Enter-autocorrect и manual\n  smart-replace.\n- `0.1.182` — общий helper для успешного layout replay. IME-replay,\n  GNOME-native replay и обычный uinput replay теперь одинаково обновляют\n  replay-toggle buffer и learning-log, поэтому эти пути меньше рискуют\n  разъехаться при следующих правках.\n- `0.1.181` — manual smart-replace теперь тоже записывает learning и\n  replay-memory через общий helper. IME/GNOME-native/uinput ветки больше не\n  дублируют этот код; расширенный fallback для запоминания вставленного хвоста\n  остаётся только в uinput-пути, где он уже был нужен для обратимого\n  double-Shift.\n- `0.1.180` — общий helper для layout switch/restore после text edit. Ветки\n  typing assist и Enter-autocorrect больше не держат четыре копии одной\n  логики: если включено автопереключение, оставляем layout под исправленный\n  текст; если выключено — возвращаем исходную раскладку.\n- `0.1.179` — daemon получил общий uinput edit executor для\n  `TextReplacement`: typing assist, Enter-autocorrect и manual smart-replace\n  теперь используют один путь вставки текста и восстановления курсора. Также\n  общий helper записывает feedback/undo/replay-memory после assisted-правок,\n  чтобы эти ветки не расходились по поведению.\n- `0.1.178` — manual smart decoder теперь возвращает готовый\n  `TextReplacement` plan вместе с решением. Daemon больше не пересобирает\n  минимальную замену отдельно: один decoder-контракт решает, что менять и какой\n  хвост стирать/вставлять. Regression-тесты проверяют, что в mixed 2/3-word\n  случаях заменяется только BAD-хвост, например `good ntrcn`, `hello good ntrcn`\n  и `делай KDE`.\n- `0.1.177` — decoder получил явный ranked-candidate слой: scoped-tail\n  кандидаты ранжируются через LEM/ngram, победитель применяется только при\n  достаточном margin, а tests теперь покрывают 2/3 слова, `KDE -\u003e ЛВУ` в\n  русском контексте и отключение ranked-пути без LEM-флага.\n- `0.1.176` — начат переход на явный decoder/edit-plan слой: manual\n  double-Shift, typing assist и Enter-autocorrect теперь используют общий\n  decision contract. Добавлен regression corpus для обратимого single-word\n  toggle, mixed RU/EN пар и пробельных границ. Backend-слой получил\n  capability-контракт для будущего атомарного IME/text replace.\n- `0.1.170` — README переписан в продуктовый стиль без авторской истории;\n  добавлен большой раздел сценариев использования и настроек. Публичные\n  README/HOW_IT_WORKS синхронизированы со статусом поддержки: проект больше не\n  описывается как GNOME Wayland only, KDE Plasma и X11 отмечены как проверенные\n  backend'ы с меньшей матрицей покрытия, чем GNOME.\n- `0.1.169` — добавлен GitHub Actions CI для публичных PR: форматирование,\n  Rust-тесты, clippy, проверка GNOME extension, KDE tray/shell syntax,\n  release build и LEM probe.\n- `0.1.168` — переключатели в меню трея больше не закрывают меню при клике;\n  при перестройке меню открытый раздел восстанавливается. Идея взята из PR\n  #13, реализация перенесена вручную без merge.\n- `0.1.167` — расширена runtime-регрессия для ведущих CLI-токенов: теперь\n  тестом покрыты и `-b`, и `+x`-подобные случаи, чтобы следующий текст после\n  такого токена нормально начинал новый WordBuffer.\n- `0.1.166` — `lay-test-input x11-report` печатает готовый GitHub-ready блок\n  для проверки экспериментального X11 backend: distro/session/backend/tools и\n  поля ручного smoke-test.\n- `0.1.165` — CLI-флаги и похожие токены, начинающиеся с ведущего `-` или\n  `+`, больше не попадают в WordBuffer как голая буква. Это закрывает ложную\n  автоподмену `git checkout -b`, где `b` могло восприниматься как отдельное\n  русское `в`.\n- `0.1.164` — синхронизирован `HOW_IT_WORKS.md` с текущей архитектурой:\n  KDE adapter уже существует, X11 описан как native XKB через `x11rb`, а не\n  как tools-first backend.\n- `0.1.163` — расширен потоковый mixed-corpus regression test: проверяется,\n  что пары вида `я язык`, `в версии`, `и идея`, `с системой` не разрезаются\n  typing assist после пробела.\n- `0.1.162` — typing assist больше не отрывает повторяющуюся первую букву у\n  следующего слова после односимвольных служебных слов. Регрессия закрывает\n  живой сценарий `я язык НАПИШИ`, который не должен превращаться в `я зык`.\n- `0.1.161` — typing assist больше не разрезает валидное слово `язык` в\n  `я зык`. Для разрезания после одиночного `я` правая часть теперь должна быть\n  действительно самостоятельным частым словом, а не generated-only формой.\n- `0.1.160` — добавлены регрессии на грамматически валидные формы вроде\n  `нужна`, `она нужна`, `важна`, `важно`: typing assist не должен менять одну\n  нормальную словоформу на другую без уверенного сигнала.\n- `0.1.159` — typing assist больше не склеивает короткий русский предлог слева\n  с нормальным кириллическим словом справа. Добавлена регрессия на `про сою`,\n  чтобы это не возвращалось как `просою`.\n- `0.1.158` — optional Smart/LLM arbiter получил настраиваемые backend/url:\n  `ollama`, `direct`, `openai`, `anthropic`. API-ключи читаются только из env,\n  не из `config.json`. По умолчанию backend остаётся `off`.\n- `0.1.157` — `lay-test-input` теперь устанавливается в `~/.local/bin` и умеет\n  печатать `x11-diagnostics`: backend, X11 env, native `x11rb` XKB status и\n  fallback tools. Это нужно для нормальных отчётов по экспериментальному X11.\n- `0.1.156` — optional multi-tap Shift scope включён в runtime за выключенным\n  по умолчанию флагом: `2/3/4` тапа выбирают `1/2/3` слова. Default double\n  Shift остался мгновенным. Также добавлена регрессия на `изменю параметры`,\n  чтобы typing assist не склеивал валидные русские слова.\n- `0.1.155` — зафиксирован design contract для optional multi-tap Shift scope:\n  `2/3/4` тапа соответствуют `1/2/3` словам, runtime-фича пока выключена.\n- `0.1.154` — typing assist больше не автопереключает shell/CLI флаги вроде\n  `-f`, `-r`, `-c`, `-n` и `--color=auto` в кириллицу после пробела.\n- `0.1.153` — добавлена проверка совместимости старого `config.json` без\n  новых force-layout полей: режим остаётся выключенным и получает безопасные\n  значения по умолчанию.\n- `0.1.152` — добавлены опциональные прямые хоткеи языка: отдельная клавиша\n  может всегда включать RU, другая всегда включать EN. По умолчанию выключено;\n  работает через тот же backend, что и double Shift: GNOME/KDE/X11.\n- `0.1.151` — X11 backend теперь сначала использует native XKB через\n  `x11rb`, без запуска `setxkbmap` на каждое исправление. Старые\n  `xkb-switch`/`xkblayout-state`/`setxkbmap` оставлены как fallback.\n- `0.1.150` — исправлены ложные auto-layout с русскими дефисными словами\n  вроде `что-то`; GNOME indicator больше не создаёт timestamp-id вида\n  `lay-177...`; установщик получил поддержку зависимостей для `apt`,\n  `pacman`, `dnf` и `yum`.\n- `0.1.149` — KDE tray теперь ставится через desktop autostart\n  `~/.config/autostart/lay-kde-tray.desktop`. Это чинит ситуацию, когда после\n  рестарта KDE daemon работает, а значок Lay в трее не появляется.\n- `0.1.147` — после ручного double Shift следующий пробел больше не запускает\n  автопомощник на только что перевёрнутом слове. Это исправляет сценарий\n  `и -\u003e b`, где автоподмена могла сразу вернуть `b` в `в`.\n- `0.1.146` — smart-scope больше не переворачивает завершённую одиночную\n  кириллическую букву слева от текущего слова. Исправлен случай вроде\n  `й Сщсф -\u003e й Coca`.\n- `0.1.145` — добавлен optional host VM guard для тестирования KDE в VM:\n  хостовый daemon можно автоматически гасить, пока открыт VM viewer, чтобы\n  double Shift не обрабатывался одновременно хостом и гостем.\n- `0.1.144` — daemon перестал слушать служебные виртуальные клавиатуры\n  `lay-virtual-keyboard` и `ydotoold virtual device`, чтобы убрать фантомные\n  повторы при тестах и desktop-интеграции.\n\n### Extension ZIP\n\nДля ручной установки GNOME-расширения или отправки на extensions.gnome.org можно\nсобрать ZIP:\n\n```bash\nbash scripts/package-extension.sh\n```\n\nАрхив появится в:\n\n```text\ndist/gnome-extension/lay@radislabus-star.github.io-\u003cversion\u003e.zip\n```\n\nУстановить только расширение можно так:\n\n```bash\ngnome-extensions install --force dist/gnome-extension/lay@radislabus-star.github.io-\u003cversion\u003e.zip\ngnome-extensions enable lay@radislabus-star.github.io\n```\n\nНо для полной работы double Shift всё равно нужен `lay-daemon`, поэтому для\nобычных пользователей предпочтителен `bash install.sh`.\n\n### Требования\n\n- Linux\n- GNOME Shell 45, 46, 47 или 50 либо KDE Plasma 6\n- Wayland-сессия для GNOME/KDE или X11-сессия для X11 backend\n- Rust 1.75+\n- доступ к `/dev/input` через группу `input`\n- доступный `/dev/uinput` для обратной печати\n- IBus и `python3-gi`, если включаешь экспериментальный `text_backend = \"ime\"`\n\nДля KDE backend нужен `qdbus` или `qdbus6`; для KDE tray нужен PyQt6.\nУстановщик ставит эти пакеты в Plasma-сессии и поддерживает Ubuntu/Debian,\nArch/Manjaro и Fedora/RHEL-like системы через `apt`, `pacman`, `dnf` или `yum`.\nX11 backend использует pure-Rust `x11rb` для прямых XKB-запросов. Если native\nXKB недоступен, daemon пробует старые fallback tools: `xkb-switch`,\n`xkblayout-state` и `setxkbmap`.\n\nУстановщик может добавить текущего пользователя в группу `input` и поставить\nudev-правило для `/dev/uinput`, но группа начинает работать только после нового\nвхода в систему.\n\n### CLI\n\n`lay` можно использовать и из терминала:\n\n```bash\nlay \"Ye djn ghbvth\"\n# Ну вот пример\n\nlay \"руддщ цщкдв\"\n# hello world\n\necho \"ghbdtn\" | lay\n# привет\n\nlay --clipboard\n```\n\nCLI удобен для быстрых проверок, скриптов и конвертации буфера обмена.\n\n### Демон\n\n`lay-daemon` — фоновый сервис, который делает двойной Shift рабочим в обычных\nприложениях.\n\nПолезные команды:\n\n```bash\nsystemctl --user status lay-daemon --no-pager\nsystemctl --user restart lay-daemon\nsystemctl --user stop lay-daemon\njournalctl --user -u lay-daemon -n 120 --no-pager\n```\n\n### GNOME-расширение\n\nДемон читает физические клавиши и перепроигрывает keycode-события, но на GNOME\nWayland переключение раскладки требует интеграции с GNOME Shell.\n\nИсходники расширения:\n\n```text\nextension/lay@radislabus-star.github.io/\n```\n\nУстановленная копия:\n\n```text\n~/.local/share/gnome-shell/extensions/lay@radislabus-star.github.io/\n```\n\n### KDE/Plasma tray\n\nВ KDE используется отдельный frontend:\n\n```text\nscripts/lay-kde-tray.py\n~/.config/autostart/lay-kde-tray.desktop\n```\n\nУстановленная команда:\n\n```bash\n~/.local/bin/lay-kde-tray --status\n```\n\nПосле установки KDE tray стартует через desktop autostart вместе с Plasma.\nОтдельный `lay-kde-tray.service` больше не используется как основной механизм\nавтозапуска.\n\nTray читает и пишет тот же файл:\n\n```text\n~/.config/lay/config.json\n```\n\nЧерез меню KDE можно включать/выключать daemon, `Smart correction`, область\n1/2/3 слова, `Typing assist`, `Auto-replace`, `Auto-switch layout`,\n`Remember corrections` и LEM-арбитр.\n\nЕсли ты тестируешь KDE внутри виртуальной машины с хоста, где тоже установлен\n`lay`, включи host VM guard. Он временно останавливает **хостовый** daemon,\nпока запущен VM viewer, чтобы double Shift не обрабатывался дважды:\n\n```bash\nsystemctl --user enable --now lay-host-vm-guard.service\n```\n\nДемон внутри гостевой KDE при этом должен быть включён: именно он видит\nгостевую раскладку и печатает обратно в приложения VM.\n\n### Меню в трее\n\nМеню держит основной сценарий коротким:\n\n- `Помощь при наборе`: осторожная правка после пробела.\n- `Автоподмена`: точные пользовательские правила и typo-правки.\n- `Запоминать правки`: opt-in лог подтверждённых исправлений.\n- `Режим`: Replay или Smart.\n- `Область`: сколько слов брать для ручного double Shift.\n- `Арбитр`: LEM и auto-layout настройки.\n- `ptah_alexs`: жёсткая раскладка по окну.\n- `Коррекция`: включение/выключение слоёв помощника.\n- `Триггер`, `Тайминг`, `Daemon`, `О программе`: сервисные настройки.\n\nВ публичном режиме нет кнопки для открытия сырого debug-лога.\n\n### Как это работает\n\nПри двойном Shift:\n\n```text\nфизическая клавиатура -\u003e evdev -\u003e lay-daemon\n                                  |\n                                  v\n                           буфер текущего слова\n                                  |\n                                  v\n                        Backspace x длина слова\n                                  |\n                                  v\n                 desktop backend переключает раскладку\n                 GNOME extension или KDE qdbus6\n                                  |\n                                  v\n                    uinput повторяет исходные keycode\n```\n\nТо есть `lay` не вставляет “готовое слово” из облака или буфера. Он повторяет\nте же физические клавиши уже под другой раскладкой. Поэтому `Ghbdtn` становится\n`Привет`.\n\nОбщая логика живёт в библиотеке:\n\n```text\nsrc/core.rs       общий facade для frontend-ов\nsrc/config.rs     единая схема config для daemon/tray/frontend-ов\nsrc/correction.rs общий результат исправления: replay или вставка текста\nsrc/decoder.rs    общий decision layer: manual/typing-assist/enter-autocorrect\nsrc/desktop.rs    определение GNOME/KDE/X11 backend и layout-id helpers\nsrc/dict.rs       RU/EN keyboard mapping\nsrc/keyboard.rs   keycode-события, word split, replay-decision, US/RU mapping и text→uinput runs\nsrc/word_buffer.rs история текущего/предыдущих слов, replay-toggle и feedback для обучения\nsrc/lem.rs        арбитр кандидатов\nsrc/ngram.rs      локальный scorer естественности\nsrc/text_edit.rs  минимальный план замены текста без лишней перепечатки\nsrc/text_backend.rs выбор uinput/IME способа применения готовой правки\n```\n\nDesktop-специфичная часть остаётся отдельно: GNOME использует Shell extension,\nKDE/Plasma использует `lay-kde-tray`, а daemon выбирает backend для\nпереключения раскладки.\n\n### Помощь при наборе\n\nДополнительно `lay` умеет после пробела запускать консервативный помощник.\nЭто отдельная функция, не основной double-Shift сценарий.\n\nПомощник специально осторожный:\n\n- проверяет только завершённые слова;\n- исправляет только уверенные локальные ошибки;\n- использует точные правила, словари и char n-gram scorer;\n- не переписывает стиль и не генерирует новый текст;\n- если не уверен, ничего не делает.\n\nПримеры задуманных исправлений:\n\n```text\nошисбя -\u003e ошибся\nя вно  -\u003e явно\nплозо  -\u003e плохо\n```\n\nВключается и выключается в трее:\n\n```json\n{\n  \"typing_assist\": true,\n  \"auto_switch_layout\": true\n}\n```\n\n`auto_switch_layout` управляет автоматическими layout-правками после пробела:\nесли слово уверенно похоже на набор в неправильной раскладке, helper заменит\nего и оставит активной раскладку исправленного текста. Ручной double Shift\nпереключает раскладку всегда.\n\n### Прямое включение RU / EN\n\nDouble Shift исправляет уже набранный хвост. Отдельно можно включить режим, где\nодна клавиша всегда ставит русскую раскладку, а другая всегда ставит английскую.\nЭто не toggle, а именно принудительное состояние.\n\nПо умолчанию режим выключен:\n\n```json\n{\n  \"force_layout_hotkeys\": false,\n  \"force_ru_key\": \"single-rctrl\",\n  \"force_en_key\": \"single-ralt\"\n}\n```\n\nВ трее это находится в разделе `Прямой язык`. Настройка не меняет основной\ndouble Shift и использует текущий `layout_backend`.\n\n### Автоподмена\n\nТочные автоподмены лежат здесь:\n\n```text\n~/.config/lay/replacements.json\n```\n\nПример:\n\n```json\n{\n  \"подлючись\": \"подключись\",\n  \"Надйи\": \"Найди\"\n}\n```\n\nЭто именно точные правила. Нечёткие исправления относятся к typing assist, а не\nк словарю автоподмены.\n\n### Режим ptah_alexs\n\n`ptah_alexs` — это не память последней раскладки окна. Это жёсткая политика:\nкогда конкретное окно получает фокус, `lay` ставит назначенную раскладку.\n\nПример:\n\n```text\nTerminal -\u003e EN\nBrowser  -\u003e не трогать\n```\n\nЕсли терминал получил фокус, `lay` снова поставит EN, даже если раньше внутри\nнего случайно включали RU. Правила задаются из трея: `ptah_alexs -\u003e Текущее\nокно -\u003e EN/RU/keep`.\n\nКонфиг хранится локально:\n\n```json\n{\n  \"ptah_alexs_mode\": true,\n  \"ptah_alexs_rules\": [\n    {\"kind\": \"app_id\", \"value\": \"org.gnome.Terminal.desktop\", \"layout\": \"us\", \"label\": \"Terminal\"}\n  ]\n}\n```\n\n### Приватность\n\nК клавиатурным инструментам нужно относиться подозрительно. `lay-daemon` видит\nклавиатурные события, поэтому модель данных сделана максимально скучной и\nлокальной.\n\nПо умолчанию `lay` никуда не отправляет набранный текст. Нормальный путь\ndouble Shift не требует сети, облачных API или удалённой модели.\n\nОпциональный learning log локальный. Он должен хранить пары подтверждённых\nисправлений, а не полный поток набора. По умолчанию он выключен и включается в\nтрее через `Данные -\u003e Запоминать правки`:\n\n```text\n~/.local/share/lay/corrections.jsonl\n```\n\nДиагностический вывод тоже выключен по умолчанию. Разработчик может включить\nего явно через `lay-daemon --debug-log` или `LAY_DEBUG_LOG=1`.\n\nGNOME-расширение публикует session-local DBus bridge, чтобы `lay-daemon` мог\nпереключать раскладку и делать fallback-вставку текста. Это не является\nsecurity boundary против других процессов того же desktop-пользователя.\n\nОстановить демон можно в любой момент:\n\n```bash\nsystemctl --user stop lay-daemon\n```\n\n### Smart/LLM режим\n\nЕсть экспериментальный `--smart` режим, где локальная модель может быть\nарбитром между уже подготовленными кандидатами.\n\nЭто не главный путь продукта, не обязательная часть double Shift и не включено\nдля обычного исправления раскладки.\n\n`Ещё -\u003e LLM` в трее влияет только на `lay-daemon`. CLI использует модельную\nлогику только если передан `--smart`.\n\nОбычная сборка не компилирует direct GGUF backend и не грузит модель при\nстарте. Для экспериментов с Ollama:\n\n```bash\nLAY_LLM_BACKEND=ollama lay --smart \"fyukbqcrbq\"\n```\n\nOllama endpoint можно переопределить:\n\n```bash\nLAY_LLM_BACKEND=ollama \\\nLAY_OLLAMA_URL=http://localhost:11434/api/generate \\\nlay --smart \"fyukbqcrbq\"\n```\n\nВнешние API тоже поддержаны, но только явно. Ключи держи в переменных\nокружения, не в `config.json`:\n\n```bash\nLAY_LLM_BACKEND=openai \\\nLAY_OPENAI_API_KEY=... \\\nLAY_MODEL=gpt-4o-mini \\\nlay --smart \"fyukbqcrbq\"\n\nLAY_LLM_BACKEND=anthropic \\\nLAY_ANTHROPIC_API_KEY=... \\\nLAY_MODEL=claude-3-5-haiku-latest \\\nlay --smart \"fyukbqcrbq\"\n```\n\nЧасть настроек можно положить в `~/.config/lay/config.json`; секреты всё равно\nостаются только в env:\n\n```json\n{\n  \"llm_backend\": \"off\",\n  \"llm_model\": \"smollm:135m\",\n  \"llm_ollama_url\": \"http://localhost:11434/api/generate\",\n  \"llm_openai_url\": \"https://api.openai.com/v1/chat/completions\",\n  \"llm_anthropic_url\": \"https://api.anthropic.com/v1/messages\",\n  \"llm_timeout_secs\": 3\n}\n```\n\nДля optional direct GGUF backend:\n\n```bash\ncargo build --release --features direct-llm\nLAY_LLM_BACKEND=direct LAY_GGUF_MODEL=/path/to/model.gguf lay --smart \"fyukbqcrbq\"\n```\n\n### Разработка\n\n```bash\ncargo test\ncargo build --release\n```\n\nN-gram helpers:\n\n```bash\ncargo run --bin lay-ngram-corpus -- check-cache\ncargo run --bin lay-ngram-corpus -- check --corpus corpus/ru_50mb.txt\n```\n\nУстановка текущей сборки локально:\n\n```bash\nbash install.sh\n```\n\n### Roadmap\n\n- Uninstall-команда и более дружелюбный release-пакет.\n- Короткий demo GIF/video для double Shift.\n- Больше регрессионных тестов из реальных принятых/отклонённых исправлений.\n- Ещё более понятные privacy-настройки.\n- Расширить матрицу проверок KDE/X11 на чужих системах и версиях Plasma.\n- Исследование Sway/Hyprland.\n- Другие раскладки после стабилизации RU/EN.\n\n## English\n\n`lay` is a lightweight keyboard helper for Linux users who type in two layouts,\nespecially **RU/EN**.\n\nThe main workflow:\n\n```text\nTyped:   Ghbdtn\nPress:   Shift Shift\nResult:  Привет\n```\n\n`lay` is primarily tested on GNOME Wayland, but it is no longer GNOME-only. It\nuses Rust, evdev/uinput, and a layout backend layer. GNOME uses a small Shell\nextension; KDE/Plasma uses a separate tray plus `qdbus6`; X11 uses native XKB\nthrough `x11rb`. The normal path is local-first: no cloud service, no network\ncall, and no model required.\n\nQuick install:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/radislabus-star/lay-public/main/scripts/install-remote.sh | bash\n```\n\nManual install:\n\n```bash\ngit clone https://github.com/radislabus-star/lay-public.git ~/projects/lay\ncd ~/projects/lay\nbash install.sh\n```\n\nAfter installation, log out and log back in so the `input` group, `/dev/uinput`\npermissions, and GNOME extension are picked up.\n\nUpdate an existing git install:\n\n```bash\ncd ~/projects/lay \u0026\u0026 bash update.sh\n```\n\nExtension ZIP for manual install or extensions.gnome.org upload:\n\n```bash\nbash scripts/package-extension.sh\ngnome-extensions install --force dist/gnome-extension/lay@radislabus-star.github.io-\u003cversion\u003e.zip\ngnome-extensions enable lay@radislabus-star.github.io\n```\n\nThe extension alone is only the GNOME Shell bridge and tray UI. The full\ndouble-Shift workflow also needs `lay-daemon`, so normal users should use\n`bash install.sh`.\n\nSupported/tested target:\n\n- Linux\n- GNOME Shell 45, 46, 47, or 50\n- KDE Plasma 6 through the KDE tray/backend\n- GNOME/KDE Wayland sessions, plus X11 through the X11 backend\n- Rust 1.75+\n- RU/EN layouts and dictionaries\n\nValidated with smaller coverage than GNOME:\n\n- KDE backend via `qdbus/qdbus6 org.kde.keyboard /Layouts setLayout`.\n- X11 backend via native XKB (`x11rb`), with `xkb-switch`, `xkblayout-state`,\n  and `setxkbmap` kept as fallback tools.\n- `ptah_alexs` window policy mode for GNOME: force a selected window/app to RU,\n  EN, or keep.\n\nUseful CLI examples:\n\n```bash\nlay \"Ye djn ghbvth\"\n# Ну вот пример\n\nlay \"руддщ цщкдв\"\n# hello world\n\necho \"ghbdtn\" | lay\n# привет\n```\n\nLanguage scope: current automatic correction is intentionally RU/EN-focused.\nOther layout pairs are not promised yet. If you need another language pair,\nplease open an issue with concrete typed/expected examples and your desktop\nenvironment.\n\nManual-only mode: disable `typing_assist`, `auto_replace`, and\n`auto_switch_layout` if you want only the predictable double-Shift rescue\nwithout automatic corrections after Space.\n\nPrivacy summary: `lay-daemon` reads keyboard events locally to provide the\ndouble-Shift workflow. By default it does not send typed text anywhere, does not\nrequire a remote model, and does not keep a full keylog. Optional learning logs\nare local and disabled by default.\n\nExperimental Smart/LLM mode exists, but it is not the default product path.\nExternal providers are used only when `LAY_LLM_BACKEND=openai` or\n`LAY_LLM_BACKEND=anthropic` is set explicitly and the matching API key is\npresent in env. The default build does not compile direct GGUF support; use\n`--features direct-llm` and explicit `LAY_LLM_BACKEND=direct` only for local\nmodel experiments.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradislabus-star%2Flay-public","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fradislabus-star%2Flay-public","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fradislabus-star%2Flay-public/lists"}