From b535d025f30aac27540090522e68833a8028d5fc Mon Sep 17 00:00:00 2001 From: Bossiara13 <236771060+DmitryBykov-ISPO@users.noreply.github.com> Date: Thu, 23 Apr 2026 02:13:47 +0300 Subject: [PATCH] docs: command builder README + user-facing README section + run_builder.bat --- README.md | 21 ++++++++++ run_builder.bat | 6 +++ tools/command_builder/README.md | 68 +++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 run_builder.bat create mode 100644 tools/command_builder/README.md diff --git a/README.md b/README.md index 7e41728..1cb8006 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,27 @@ sound_off: - {type: system, op: volume_mute} ``` +## Конструктор команд + +GUI для добавления команд в `commands.yaml` без ручной правки YAML. + +Запуск: + +``` +python -m tools.command_builder +``` + +Или из корня репо `run_builder.bat` (под Windows). Открывается окно pywebview с пошаговым мастером: фразы → тип действия → параметры → предпросмотр YAML и сохранение. На шаге «Действие» доступна вкладка «Подсказать (LLM)» — модель Groq предложит готовый блок по описанию на русском. + +После сохранения команды Jarvis нужно перезапустить, чтобы она подхватилась. + +Требования: + +- Windows 10/11 с установленным WebView2 Runtime (обычно уже стоит вместе с Edge — иначе [скачать у Microsoft](https://developer.microsoft.com/microsoft-edge/webview2/)). +- Зависимости из `requirements.txt` (включая `pywebview`, `ruamel.yaml`, `pyautogui`). + +Подробности для разработчиков — [tools/command_builder/README.md](tools/command_builder/README.md). TODO: добавить скриншот окна. + ## Лицензия CC BY-NC-SA 4.0 — см. [LICENSE.txt](LICENSE.txt). Авторство оригинала — Abraham Tugalov / Priler. Изменения в этом форке — Bossiara13 (Dmitry Bykov), 2026. diff --git a/run_builder.bat b/run_builder.bat new file mode 100644 index 0000000..03cd254 --- /dev/null +++ b/run_builder.bat @@ -0,0 +1,6 @@ +@echo off +if exist .venv\Scripts\python.exe ( + .venv\Scripts\python.exe -m tools.command_builder +) else ( + python -m tools.command_builder +) diff --git a/tools/command_builder/README.md b/tools/command_builder/README.md new file mode 100644 index 0000000..a50c70d --- /dev/null +++ b/tools/command_builder/README.md @@ -0,0 +1,68 @@ +# Конструктор команд (developer notes) + +GUI-надстройка для редактирования `commands.yaml` без ручной правки YAML. Запускается отдельным процессом, не зависит от рантайма Jarvis. + +## Запуск + +``` +python -m tools.command_builder +``` + +или из корня репо `run_builder.bat`. + +## Стек + +- `pywebview` (бэкенд EdgeWebView2 на Windows) — оборачивает локальный HTML. +- Frontend — vanilla JS + CSS, без сборки. Vendored `js-yaml` только для предпросмотра YAML на стороне UI. +- `ruamel.yaml` — чтение/запись `commands.yaml` с сохранением комментариев и форматирования. +- `pyautogui` — рантайм для action-типа `keys`. + +## Структура + +``` +tools/command_builder/ + __main__.py точка входа python -m + app.py pywebview bootstrap + Python bridge (js_api) + schema.py dataclass-схема action-блоков и валидация + yaml_writer.py atomic write + .bak бэкап перед каждой записью + llm_suggest.py Groq/OpenAI SDK 1.x, response_format=json_object + web/ frontend + tests/ pytest для schema + writer +``` + +## Bridge API (методы класса `Bridge` в `app.py`) + +Все методы возвращают сериализуемые структуры. Ошибки идут как `{"ok": false, "error": "..."}`. + +| метод | назначение | +|-------|-----------| +| `list_existing_commands()` | список ключей верхнего уровня в `commands.yaml` | +| `list_exes()` | basename'ы `*.exe` из `custom-commands/` | +| `list_sound_names()` | разрешённые имена для `play_sound` (из `schema.VALID_SOUND_NAMES`) | +| `preview_sound(name)` | проигрывает звук в фоновом потоке через `simpleaudio` | +| `slugify(phrase)` | транслит для генерации `cmd_id` | +| `validate_draft(json_str)` | прогон через `command_from_dict` | +| `save_command(json_str)` | append/upsert + бэкап (`overwrite: true` чтобы перезаписать) | +| `llm_suggest(prompt)` | Groq → JSON → провалидированный action-блок | + +## Расширение схемы (новый тип action) + +1. В `schema.py`: добавить dataclass с полем `type` и методом `to_dict()`. Включить в Union `Action`. Расширить `action_from_dict()`. +2. В `tests/test_schema.py`: добавить roundtrip + negative-case тесты. +3. В `web/app.js`: + - карточка в `#action-grid` (`index.html`); + - ветка в `renderActionForm()`; + - ветка в `updateAction()`; + - ветка в `renderInlineEditor()` для использования внутри multi.steps. +4. В `main.py` → `run_action()`: обработчик нового `type`. +5. В `llm_suggest.py` → `_ACTION_SCHEMA_DOC`: описание для LLM. + +## Бэкапы + +`yaml_writer.append_command` / `upsert_command` перед записью копируют `commands.yaml` в `commands.yaml.bak` (через `shutil.copy2`). При запуске `app.py` вызывается `_check_yaml_health()` — если основной файл не парсится, в stderr печатается путь к `.bak` для ручного восстановления. + +## Тесты + +``` +.venv\Scripts\python.exe -m pytest tools/command_builder/tests/ +```