Plugin loader (mirrors Rust #29):
- plugins_store.py walks %APPDATA%\com.priler.jarvis\plugins\<name>\
for commands.yaml fragments and merges them into VA_CMD_LIST at
startup. Same schema as the project root commands.yaml. Per-pack
`disabled` flag file skips a pack without deletion. Built-in ids
win conflicts so a malicious pack can't silently override
open_browser. 9 unit tests (parity with the Rust tests).
- main.py: plugin merge runs after the root yaml load; logs the
number of extra commands picked up.
Flet GUI (#27 — first parity with the Rust Tauri GUI):
- New gui/ package: __main__.py launches via `python -m gui` (or
gui.bat). app.py routes between 7 pages (Главная / Команды /
Макросы / Расписание / Память / Плагины / Настройки) via
NavigationRail; dark theme matching the Tauri look.
- gui/services.py centralises every store-module call the pages
share — single place to swap implementations later.
- One file per page in gui/pages/, all expose `build(page)` and use
the same card layout idiom. Pages mirror the Tauri ones feature-
for-feature: home (status + counters + launcher), commands
(filterable list of all VA_CMD_LIST entries), macros (list +
delete + recording banner), scheduler (list + remove), memory
(add/forget/search), plugins (toggle/open folder), settings
(profile + LLM hot-swap).
- requirements.txt: flet>=0.85 (optional; assistant runs without).
- 3 smoke tests verify imports + build callables; skip cleanly when
Flet isn't installed.
README: documents both the GUI and the plugin layout in user-facing
terms. Tests: 42 → 54 (+9 plugins +3 GUI smoke).
ruamel.yaml is needed by tools/command_builder/yaml_writer to round-trip
commands.yaml without losing comments. pyautogui drives the new keys
action. pywebview is added now too so M2's GUI bootstrap can land
without another deps bump.
Replace the fixed 10s post-wake-word listen window with a VAD-driven
loop. Once at least 500ms of speech have been seen, 1.2s of silence
closes the window. Hard cap at 15s as a safety net.
Tunable in config.py via VAD_AGGRESSIVENESS, COMMAND_END_SILENCE_MS,
COMMAND_MIN_SPEECH_MS, COMMAND_MIN_LISTEN_MS, COMMAND_MAX_LISTEN_MS.
wake-word is now handled by vosk, so the picovoice access key is no longer
needed. config.py already had PICOVOICE_TOKEN removed in the previous commit.