J.A.R.V.I.S-py/gui/app.py
Bossiara13 59a1258dcc feat: Wave 3 — plugin loader + Flet GUI (parity with Rust fork)
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).
2026-05-16 13:27:04 +03:00

81 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Flet GUI router and shell.
Provides:
- Top navigation bar with the 6 pages (Главная / Команды / Макросы / Расписание / Память / Плагины / Настройки)
- Page swap on click, no full reload
- Dark theme matching the Tauri GUI vibe
Each page lives in `gui/pages/<name>.py` and exposes `build(page) -> Control`.
"""
import flet as ft
from gui.pages import home, commands, macros, scheduler, memory, plugins, settings
PAGES = [
("Главная", home.build),
("Команды", commands.build),
("Макросы", macros.build),
("Расписание", scheduler.build),
("Память", memory.build),
("Плагины", plugins.build),
("Настройки", settings.build),
]
def _make_app(page: ft.Page):
page.title = "J.A.R.V.I.S. — Python GUI"
page.theme_mode = ft.ThemeMode.DARK
page.window.width = 940
page.window.height = 720
page.padding = 0
page.bgcolor = "#0a1419"
content_holder = ft.Container(expand=True, padding=20)
def go(idx: int):
nav.selected_index = idx
title, builder = PAGES[idx]
try:
content_holder.content = builder(page)
except (RuntimeError, ValueError, OSError) as exc:
content_holder.content = ft.Text(
f"Не удалось открыть «{title}»:\n{exc}",
color="red",
)
page.update()
nav = ft.NavigationRail(
selected_index=0,
label_type=ft.NavigationRailLabelType.ALL,
min_width=80,
min_extended_width=180,
bgcolor="#0d1b21",
destinations=[
ft.NavigationRailDestination(icon=ft.Icons.HOME, label="Главная"),
ft.NavigationRailDestination(icon=ft.Icons.LIST_ALT, label="Команды"),
ft.NavigationRailDestination(icon=ft.Icons.PLAY_CIRCLE_OUTLINE, label="Макросы"),
ft.NavigationRailDestination(icon=ft.Icons.SCHEDULE, label="Расписание"),
ft.NavigationRailDestination(icon=ft.Icons.MEMORY, label="Память"),
ft.NavigationRailDestination(icon=ft.Icons.EXTENSION, label="Плагины"),
ft.NavigationRailDestination(icon=ft.Icons.SETTINGS, label="Настройки"),
],
on_change=lambda e: go(int(e.control.selected_index)),
)
layout = ft.Row(
controls=[
nav,
ft.VerticalDivider(width=1, color="#1f3540"),
content_holder,
],
expand=True,
)
page.add(layout)
go(0)
def run():
ft.app(target=_make_app)