diff --git a/AGENTS.md b/AGENTS.md index 99af9a8..05fd16f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,201 +1,191 @@ -# versapad-viewer +# AGENTS.md -Eigenes kleines Tool (Grovy311-Kontext, nicht Teil der fremden jappel-Repos -VersaGUI/VersaMCU). Zeigt die Steuermatrix (4x5 Button-Grid + 4 Encoder) als -Browser-Live-Seite oder natives Tkinter-Fenster. Inzwischen mehr als ein -reiner Viewer: der Tkinter-Desktop-Viewer hat einen vollen Programmiermodus -(Action-Editor, Serial-Schreibzugriff aufs Board, Makro-Editor) bekommen — -faktisch ein schlankes Python-Pendant zu VersaGUI. Der Browser-Server -(`server.py`) blieb bewusst read-only/einfach. +## Project Goal -## Architektur +Eigenständiges Begleit-Tool für das VersaPad-Makropad (Grovy311-Kontext, +nicht Teil der fremden jappel-Repos VersaGUI/VersaMCU). Zeigt die +Steuermatrix (4×5-Button-Grid + 4 Encoder) an, synchronisiert sie live mit +dem Board und kann sie komplett neu programmieren — inzwischen ein +schlankes Python-Pendant zur offiziellen VersaGUI (C#/.NET), plus ein +MCP-Server, der dieselbe Programmierung per KI-Tool-Aufruf ermöglicht. +Nutzerorientierte Einführung: [`README.md`](README.md). + +## Aktuell unterstützte Architektur **Read-only-Schicht (JSON, beide Frontends):** -- `versapad_data.py` — Decoding fuer Anzeige: JSON laden, HID-Keycode/ - Consumer-Usage/Modifier → lesbarer Text, Grid-Geometrie (index = - spalte*5+reihe), `hid_key_choices()`/`consumer_choices()` fuer Dropdowns. -- `server.py` — stdlib `http.server`, generiert HTML bei jedem Request neu, +- `versapad_data.py` — Decoding für Anzeige: JSON laden, HID-Keycode/ + Consumer-Usage/Modifier → lesbarer Text, Grid-Geometrie + (`index = spalte*5+reihe`), `hid_key_choices()`/`consumer_choices()`. +- `server.py` — stdlib `http.server`, generiert HTML pro Request neu, Profil-Wechsel über `?profile=0|1|2`, Auto-Reload alle 4s. Rein lesend, kein Programmiermodus (bewusst einfach gehalten). -**MCP-Server (Config per KI-Tool-Aufruf statt Hand-JSON):** -- `versapad_mcp_server.py` — registriert als User-Scope-MCP-Server "versapad" - (`claude mcp add -s user versapad -- versapad_mcp_server.py`, - landet in `~/.claude.json`). Tools: `list_profiles`/`get_profile`/ - `get_macro`/`get_board_status` (lesen), `set_button_key`/`_consumer`/ - `_macro`/`_profile_switch`/`_none`/`_led`, dieselben `set_encoder_*`, - `set_macro`, `rename_profile` (mutieren nur In-Memory-State), `save_local`/ - `load_local` (↔ `versapad_config_all.json`), `load_from_board`/ - `write_to_board` (↔ echtes Board per Serial). Nutzt das MCP-SDK v2 (Paket - `mcp`, Klasse `mcp.server.mcpserver.MCPServer` — **nicht** `FastMCP` aus - `mcp.server.fastmcp`, das gibt's in dieser SDK-Version nicht mehr, wurde - umbenannt). `@mcp.tool()`-dekorierte Funktionen bleiben direkt aufrufbar - (kein `.fn`-Unterschied wie bei alten FastMCP-Versionen). - -**Binaer-/Serial-Schicht (fuer den Programmiermodus):** -- `versapad_protocol.py` — pack/unpack fuer `SDeviceConfig`(740B, alle 3 - Profile) und `SMacroTable`(512B, 32 Slots) + CRC16 (Poly 0x1021, Init - 0xFFFF), 1:1 aus den Firmware-Structs (`nvm_config.h`, `action.h`, - `macro_config.h`, `CButton.h`-LEDAnim-Enum, `nvm_config.cpp`-CRC). - **Gegen echtes Board validiert:** read → unpack → pack → byte-identisch - zum Original, inkl. CRC — siehe Git-Historie dieser Datei / Sessionlog. +**Binär-/Serial-Schicht (Programmiermodus + MCP):** +- `versapad_protocol.py` — pack/unpack für `SDeviceConfig` (740B, alle 3 + Profile) und `SMacroTable` (512B, 32 Slots) + CRC16 (Poly 0x1021, Init + 0xFFFF), 1:1 aus den Firmware-Structs. **Gegen echtes Board validiert:** + read → unpack → pack ist byte-identisch zum Original, inkl. CRC. - `versapad_serial.py` — `VersaPadLink`: liest/schreibt komplette Config + - Makros per 8-Byte-Paket-Protokoll (`CmdConfigRead/Begin/Data/Commit`, - `CmdMacroRead/Begin/Data/Commit`), Board-Identifikation per VID/PID + Makros per 8-Byte-Paket-Protokoll, Board-Identifikation per VID/PID `239A:0042`. Schreiben ist sicher im Sinne von "kann NVM nicht zerlegen" - — Firmware prueft Magic/CRC/Keycode-Bereich vor jedem Save und antwortet - sonst nur mit NACK (kein Datenmuell moeglich). -- `versapad_combined.py` — kombiniertes Ein-Datei-Format (alle 3 Profile + - Makros + **nur lokal gespeicherte** Profilnamen) statt der 3 Einzel-JSONs. - Passt besser zum Wire-Protokoll: `CONFIG_BEGIN/COMMIT` ueberträgt ohnehin - immer den kompletten 740B-Block auf einmal, nie nur ein Profil. - Default-Pfad: `~\OneDrive\Desktop\versapad_config_all.json`. + — Firmware prüft Magic/CRC/Keycode-Bereich vor jedem Save, antwortet + sonst nur mit NACK. +- `versapad_combined.py` — Ein-Datei-Format (alle 3 Profile + Makros + + **nur lokal gespeicherte** Profilnamen), Default-Pfad + `~\OneDrive\Desktop\versapad_config_all.json`. Passt zum Wire-Protokoll: + `CONFIG_BEGIN/COMMIT` überträgt ohnehin immer den kompletten 740B-Block. **UI:** -- `desktop_viewer.py` — Tkinter, flaches Design (Label-Flächen, keine - Canvas-Formen/Anti-Aliasing). Zellen nutzen `.place()` mit festen - Pixel-Positionen statt `.pack()` (mit pack sah das Grid je nach leerer/ - belegter Zelle ungleichmäßig aus). Drei unabhängige Modi: - - **Nur lesen** (Default): pollt die 3 JSONs alle 1.5s. - - **Live-Sync**: pollt per Serial das aktive Profil vom Board, schaltet - Tabs automatisch mit. Laeuft in einem Hintergrundthread, der NUR ueber - eine `queue.Queue` mit dem Main-Thread kommuniziert (`self.after()` - direkt aus einem Fremdthread aufrufen ist in Tkinter nicht threadsicher - und hat den Prozess in einer frueheren Version lautlos abstuerzen - lassen — `pyw` hat kein Konsolenfenster, der Crash war unsichtbar). - - **Programmiermodus**: Zellen anklicken → `action_dialog.py` - (`ActionEditDialog`/`MacroStepsDialog`) bearbeitet Action-Typ, HID-Taste - (Dropdown statt Tastendruck-Capture — kein WinAPI-Hook, um nicht wieder - einen AV-Fehlalarm wie bei den Fensterverstecktricks zu riskieren), - Consumer, Makro-Slot+Schritte, ProfileSwitch, LED-Farbe/Animation. - "Vom Board laden"/"Zum Board übertragen" nutzen die Binaer-Schicht. - Schaltet Live-Sync automatisch aus (ein `VersaPadLink` kann nicht von - zwei Konsumenten gleichzeitig genutzt werden). -- `action_dialog.py` — die beiden Bearbeiten-Dialoge, importiert nur - `versapad_data` (fuer Dropdown-Inhalte). +- `desktop_viewer.py` — Tkinter, flaches Design, drei unabhängige Modi + (Nur lesen / Live-Sync / Programmiermodus, siehe Kritische Domänenregeln), + Tray-Icon statt Taskleisten-Minimierung, Info-Button mit MCP-Doku. +- `action_dialog.py` — Bearbeiten-Dialoge (`ActionEditDialog`, + `MacroStepsDialog`) für den Programmiermodus. -## Quelle der Wahrheit — nicht raten +**MCP-Server:** +- `versapad_mcp_server.py` — registriert als User-Scope-MCP-Server + "versapad" (`claude mcp add -s user versapad -- versapad_mcp_server.py`). + Nutzt MCP-SDK v2 (Paket `mcp`, Klasse `mcp.server.mcpserver.MCPServer` — + **nicht** `FastMCP` aus `mcp.server.fastmcp`, das existiert in dieser + SDK-Version nicht mehr, wurde umbenannt). `@mcp.tool()`-dekorierte + Funktionen bleiben direkt aufrufbar (kein `.fn`-Unterschied wie bei + älteren FastMCP-Versionen). Tool-Liste: siehe README oder + `MCP_INFO_TEXT` in `desktop_viewer.py`. -Bei Aenderungen am Schema/Decoding/Binaerformat immer gegen die Firmware- -und GUI-Quellen abgleichen, nie aus dem Gedaechtnis rekonstruieren: +Vollständige Modulübersicht mit Zeilenreferenzen bei Bedarf direkt im Code +nachschlagen — die Dateien sind klein genug, dass eine separate +`docs/current-architecture.md` hier keinen Mehrwert hätte (siehe +Dokumentation und Verifikation unten für die Größeneinschätzung). + +## Kritische Domänenregeln + +- Geometrie: `index = spalte*5 + reihe`, Reihe 0 = oben, Reihe 4 = unten + (Firmware-Reihenfolge). Nicht raten, nicht neu herleiten. +- Encoder 0 `sw` ist auf allen 3 Profilen der Profilwechsel — nicht ohne + Rücksprache mit dem User ändern. +- Makros sind eine EINE globale 32-Slot-Tabelle, nicht pro Profil. Slot 0-19 + = MX-Button-Index, Slot 20-31 = `20 + enc*3 + act_idx`. Zwei Profile, die + denselben Slot referenzieren, spielen dieselben Schritte ab. +- Ein Makro-Schritt mit `keycode=0` beendet die Sequenz (Firmware-Konvention) + — keine Lücken vor dem letzten belegten Schritt lassen. +- Makro-Schritte erlauben nur Strg/Shift/Alt als Modifier, kein Win (passend + zum Original-`ActionDialog.cs`-Verhalten). +- Profilnamen leben NUR lokal in `versapad_config_all.json` + (`profile_names`) — die Firmware-Structs haben keinen Platz für einen + String (Header exakt 32B, jedes Profil exakt 236B, alles verplant). Sie + landen nie aufs Board, egal welcher Schreibpfad benutzt wird. +- Der COM-Port ist exklusiv. Live-Sync und Programmiermodus schalten sich + gegenseitig aus (ein `VersaPadLink` kann nicht von zwei Konsumenten + gleichzeitig genutzt werden); VersaGUI läuft als Tray-App dauerhaft im + Hintergrund weiter, auch wenn nur ihr Konfigurationsfenster geschlossen + wird — für Parallelbetrieb mit diesem Tool muss sie über ihr eigenes + Tray-Menü ("Beenden") wirklich beendet werden. +- Programmiermodus-Änderungen werden bei jeder Bearbeitung automatisch in + `versapad_config_all.json` gespeichert (nicht erst bei explizitem + "Datei speichern"). Der Nur-Lese-Modus bevorzugt dieselbe Datei, falls + vorhanden, und fällt sonst auf die klassischen `versapad_config{1,2,3}.json` + zurück — beide Ansichten müssen dieselbe Quelle zeigen, sonst wirkt eine + Bearbeitung "verschwunden". +- HID-Tasten-Auswahl im Programmiermodus ist ein Dropdown, kein + Tastendruck-Capture (bewusst — kein WinAPI-Hook, um keinen AV-Fehlalarm + wie bei den Fensterverstecktricks in anderen Projekten zu riskieren). +- Zeichentasten-Labels zeigen eine US-Layout-Näherung, nicht das tatsächlich + aktive Windows-Tastaturlayout (die echte VersaGUI löst das über + `GetKeyNameText()`, das bilden wir ohne WinAPI-Call nicht nach). +- Tk-Aufrufe (`self.after()`, Widget-Konfiguration) NIE direkt aus einem + Fremdthread (Serial-Thread, pystray-Thread) — hat in einer früheren + Version einen stillen Absturz verursacht. Threads legen Ergebnisse nur in + eine `queue.Queue`, der Main-Thread holt sie per `after()`-Polling ab. +- `.exe` (PyInstaller) läuft NICHT vom Netzlaufwerk aus (`Z:\Git\...`, + SMB-Share) — Windows blockiert das Nachladen der `_internal`-DLLs von + einem Netzwerkpfad ohne jede Fehlermeldung. Bauen scheitert dort zusätzlich + an Tcl/Tk-`tzdata`-Pfadlängen. `build_and_deploy.ps1` kopiert den + Quellcode deshalb zuerst nach `%TEMP%`, baut nur dort, deployt nach + `%LOCALAPPDATA%`. +- `--onedir`, nicht `--onefile` beim PyInstaller-Build — Single-File-Bundles + lösen öfter AV-Fehlalarme aus (sehen strukturell wie ein Packer aus). + +## Existing-Codebase-Regel + +Es gibt bereits eine Codebasis mit validierter, gegen die echte Firmware +getesteter Logik (Binärformat, CRC, Protokoll). Nicht blind neu raten oder +umschreiben. Vor größeren Änderungen am Binärformat/Protokoll immer gegen +die Firmware- und GUI-Quellen abgleichen, nicht aus dem Gedächtnis +rekonstruieren: - `VersaGUI/src/ActionDialog.cs` (HidKeyName, s_consumer, Modifier-Bits) -- `VersaGUI/src/Protocol.cs` (Paket-IDs, Chunk-Groessen) +- `VersaGUI/src/Protocol.cs` (Paket-IDs, Chunk-Größen) - `VersaMCU/src/config/nvm_config.h` + `.cpp` (SDeviceConfig-Layout, CRC) - `VersaMCU/src/config/action.h` (SAction, ActionType-Enum-Werte) - `VersaMCU/src/config/macro_config.h` + `.cpp` (SMacroTable-Layout) - `VersaMCU/src/CButton.h` (LEDAnim-Enum-Werte) - `VersaMCU/src/CMainController.cpp` (welche Commands die Firmware - tatsaechlich behandelt — Protocol.cs definiert mehr Konstanten als die - Firmware zwingend implementiert, immer hier gegenchecken) + *tatsächlich* behandelt — `Protocol.cs` definiert mehr Konstanten als + zwingend implementiert sind, immer hier gegenchecken) -Zeichentasten (A-Z, Ziffern, Satzzeichen) zeigen US-Layout-Näherung, da die -echte GUI das über `GetKeyNameText()` layoutabhängig auflöst — das bilden -wir ohne WinAPI-Call nicht nach. +Frühere falsche Annahme, die hier stand: Makros seien nur per SWD/JTAG +schreibbar. Falsch — `USB_CMD_MACRO_BEGIN/DATA/COMMIT` in +`CMainController.cpp` sind normal über USB implementiert. Korrigiert, auch +im `versapad`-Skill (`~/.claude/skills/versapad/SKILL.md`). -**Korrektur einer frueheren Annahme:** Anders als zuerst notiert, kann die -Firmware Makros sehr wohl per normaler USB-Verbindung schreiben -(`USB_CMD_MACRO_BEGIN/DATA/COMMIT` in `CMainController.cpp` sind -implementiert) — kein SWD/JTAG noetig. Der VersaPad-Skill -(`~/.claude/skills/versapad/SKILL.md`) behauptet noch das Gegenteil und -sollte bei Gelegenheit korrigiert werden. +## Implementierungsdisziplin -## Start +In Phasen arbeiten, nicht mehrere unabhängige Features in einem Rutsch ohne +Zwischenverifikation bauen. Vor jeder Änderung am Binärformat/Protokoll: +gegen ein echtes Board testen (read → unpack → pack → Vergleich auf +Byte-Identität), nicht nur gegen Beispieldaten. Vor jedem Schreibvorgang +aufs Board: erst mit unveränderten Daten testen (Identity-Write), bevor +echte Änderungen geschrieben werden. +## Naming + +Code-Identifier englisch (Python-Konvention: `pack_config`, `read_macros`, +`ActionEditDialog`). UI-Text, Kommentare und Docstrings deutsch (Projekt- +und User-Konvention). Domänenbegriffe aus der Firmware direkt übernehmen, +nicht neu erfinden: `profile`, `action`, `led`, `slot`, `macro`, `encoder`, +`chunk`. Keine generischen Namen wie `data`/`item`/`entry`, wo eine +Bedeutung existiert — Ausnahme: `data` als Feldname ist durch die Firmware +selbst vorgegeben (`SAction.data`), dort beibehalten statt umzubenennen. + +## Deferred Work + +- Volle `docs/`-Baumstruktur (siehe Dokumentation und Verifikation unten — + Projektgröße rechtfertigt das aktuell nicht, kein DB-/API-Dienst) +- Board-seitiges Umschalten des aktiven Profils per Button in der GUI — + explizit vom User abgelehnt ("lass uns weg"), Live-Sync bleibt read-only +- Profilnamen aufs Board schreiben — technisch unmöglich (kein Platz im + Firmware-Struct), bleibt lokal +- Tastendruck-Capture statt Dropdown im Programmiermodus — bewusst + vermieden (WinAPI-Hook-Risiko) +- Hintergrund-Thread für "Vom Board laden"/"Zum Board übertragen" — laufen + aktuell synchron im UI-Thread (kurzzeitiges Einfrieren möglich) +- Vorgefertigte `.exe` im Repo/als Release-Asset — bewusst nicht committet + (Build-Artefakt), Anleitung zum Selbstbauen steht in `README.md` + +Nicht an diesen Punkten arbeiten, ohne dass der User es explizit anfragt. + +## Dokumentation und Verifikation + +- `README.md` ist der Einstiegspunkt (Installation, Nutzung, Architektur- + Überblick). +- `AGENTS.md` (diese Datei) ist die agentenseitige Quelle der Wahrheit für + Domänenregeln und Architekturgrenzen — jede Session aktualisieren, die + daran etwas ändert oder etwas Wichtiges lernt. +- Größeneinschätzung nach Projekt-Dokumentationsstandard: kleines/mittleres + Tool ohne eigene Datenbank und ohne persistenten API-Dienst (der + Browser-Server ist ein einfacher lokaler Lese-Viewer, kein + Mehrbenutzer-Backend) → `README.md` + `AGENTS.md` sind Pflicht und + vorhanden, ein voller `docs/`-Baum ist nicht angemessen. + +Prüfungen vor einem Commit an Binärformat/Protokoll: +```bash +python -m py_compile *.py ``` -py server.py # Browser, http://127.0.0.1:8765 -pyw desktop_viewer.py # natives Fenster, kein Konsolenfenster -``` -Oder `run_browser.bat` / `run_desktop.bat` per Doppelklick, oder die -Desktop-Verknuepfungen "VersaPad Viewer (Browser)" / "VersaPad Viewer -(Fenster)". +Danach ein Live-Testskript gegen ein angeschlossenes Board laufen lassen +(read → unpack → pack → Bytevergleich, siehe Existing-Codebase-Regel) — +es gibt keine automatisierten Unit-Tests dafür, die Verifikation läuft +manuell/interaktiv pro Session. -**Wichtig:** `pyw`/`py` benutzen, nicht bare `pythonw`/`python` — auf hal9001 -liegt in PATH zuerst eine Hermes-Agent-venv (`...\hermes\hermes-agent\venv\ -Scripts\pythonw.exe`) ohne pyserial. `pyw`/`py` (Python Launcher) lösen -zuverlässig zur echten Python313-Installation auf. - -## Gepackte .exe (PyInstaller) — kein Terminal-Flash, kein Python-Setup nötig - -`build_and_deploy.ps1` kopiert den Quellcode zuerst nach `%TEMP%`, baut dort -mit PyInstaller (`--windowed --onedir --icon icon.ico`), und kopiert das -Ergebnis nach `%LOCALAPPDATA%\VersaPadViewer\VersaPadViewer.exe`. -Desktop-Verknüpfung "VersaPad Viewer (Fenster)" zeigt dorthin (inkl. eigenem -Icon, `IconLocation` zeigt auf die `.exe` selbst statt auf `pythonw.exe`). - -**`--onedir`, nicht `--onefile`** — Single-File-PyInstaller-Bundles lösen -öfter AV-Fehlalarme aus (sehen strukturell wie ein Packer aus); `--onedir` -(Ordner mit `.exe` + `_internal`) ist unauffälliger. Trotzdem unsigniert, -also grundsätzlich nie über Smart App Control/AV in Stein gemeißelt sicher. - -**Zwei Netzlaufwerk-Stolpersteine, deshalb baut UND deployt alles lokal:** -1. Laufzeit: die gebaute `.exe` läuft NICHT vom Netzlaufwerk aus (`Z:\Git\...`, - SMB-Share auf cj-ki) — Windows blockiert das Nachladen der - `_internal`-DLLs von einem Netzwerkpfad, der Prozess startet dann einfach - nie, ganz ohne Fehlermeldung/Crash-Log/AV-Benachrichtigung (sah zuerst wie - ein AV-Block aus, war aber keiner — verifiziert indem dieselbe `.exe` 1:1 - lokal kopiert sofort lief). -2. Buildzeit: PyInstaller scheitert beim Kopieren der Tcl/Tk-`tzdata` - (viele tief verschachtelte, lang benannte Zeitzonen-Ordner) auf dem - SMB-Share mit `FileNotFoundError: [WinError 3]` — Pfadlängen-Problem, - kombiniert mit dem eh schon langen Projektpfad (`Z:\Git\Versa Board\ - versapad-viewer\dist\...`). - -Deshalb kopiert `build_and_deploy.ps1` den Quellcode zuerst nach `%TEMP%` -und baut NUR dort — Z: wird nur zum Lesen der `.py`-Dateien angefasst. - -Bei erneutem Bauen: `.\build_and_deploy.ps1` in PowerShell ausführen -(lokal, nicht über die sandboxed Bash-Tool-Umgebung — die hat eine eigene -Dateisystem-Sicht, die nicht zuverlässig mit dem echten Windows-Dateisystem -übereinstimmt; siehe Sessionlog: ein `cp -r` über Bash landete an einem Ort, -den PowerShell/der reale Explorer nicht sah. Kopieroperationen für Dinge, -die der User/andere Prozesse sehen sollen, gehören in PowerShell, nicht in -Bash). - -## Icon + Tray (kein Taskleisten-Eintrag beim Minimieren, wie VersaGUI) - -- `icon.png`/`icon.ico` — generiert via Pillow (dunkles abgerundetes Quadrat, - blauer Block, 2x2-Punktraster; flaches Design, keine Farbverläufe/ - Anti-Aliasing-Details, siehe Speicher-Notiz zu Tkinter-Flat-Design). - `.ico` fürs Fenster-/Taskleisten-/Exe-Icon, `.png` fürs Tray-Icon (pystray - braucht ein PIL-Image, kein Multi-Res-`.ico`). -- `resource_path()` in `desktop_viewer.py` findet Assets sowohl im - Quellordner als auch im PyInstaller-Bundle (`sys._MEIPASS`). -- Minimieren (`` mit `state()=='iconic'`) ruft `withdraw()` statt - normal zu minimieren → kein Taskleisten-Eintrag, nur noch Tray-Icon. - Schließen (X) macht dasselbe (`_hide_to_tray`, nicht `_quit`) — echtes - Beenden nur über "Beenden" im Tray-Rechtsklickmenü (mirrort VersaGUIs - `TrayApp`-Menü: Öffnen/Beenden). Tray-Icon läuft über `pystray.Icon. - run_detached()` in eigenem Thread — Klicks im Tray-Menü legen nur ein - Ereignis in `self._tray_queue`, das der Main-Thread per `after()`-Polling - abholt (dieselbe Queue-statt-Direktzugriff-Regel wie beim Serial-Thread, - siehe oben — Tk-Aufrufe aus einem Fremdthread haben schon mal einen - stillen Absturz verursacht). -- Neue Abhängigkeiten: `pystray`, `pillow` (zusätzlich zu `pyserial`). -- Info-Button (ⓘ oben rechts im Header) öffnet einen Dialog mit der - MCP-Server-Doku (`MCP_INFO_TEXT`-Konstante) — rein informativ, keine Logik. - -## Dateien/Pfade (hardcoded, hal9001-spezifisch) - -- Einzel-JSONs (Read-only-Modus): `~\OneDrive\Desktop\versapad_config{1,2,3}.json` - — Profil 0 Windows / 1 Fusion 360 / 2 BricsCAD, siehe `versapad_data.CONFIG_PATHS`. -- Kombinierte Datei (Programmiermodus-Export): `~\OneDrive\Desktop\ -versapad_config_all.json` (Default, siehe `versapad_combined.DEFAULT_PATH`). - -## Offene Punkte - -- Kein automatischer Windows-Start/Tray-Icon — bewusst einfach gehalten, - bei Bedarf nachrüstbar. -- Live-Sync und VersaGUI (bzw. Programmiermodus) können den COM-Port nicht - gleichzeitig halten (exklusiver Zugriff) — zeigt dann "Port belegt", kein - Crash. VersaGUI läuft als Tray-App dauerhaft im Hintergrund weiter, auch - wenn nur das Konfigurationsfenster geschlossen wird — für Programmiermodus/ - Live-Sync muss es über das Tray-Icon → "Beenden" wirklich beendet werden. - Live-Sync wird beim Aktivieren des Programmiermodus automatisch ausgeschaltet. - Innerhalb des Programmiermodus selbst laufen "Vom Board laden"/"Zum Board - übertragen" synchron im UI-Thread (kurzzeitiges Einfrieren möglich, v.a. - bei Timeout) — bislang nicht als Hintergrund-Thread ausgelagert. - Der Browser-Server (`server.py`) hat keinen Programmiermodus. -- HID-Tasten-Auswahl im Programmiermodus ist ein Dropdown, kein - Tastendruck-Capture (bewusst, um WinAPI-Hooks/AV-Fehlalarme zu vermeiden). -- Macro-Editor erlaubt nur Strg/Shift/Alt pro Schritt (kein Win), passend - zum Original-`ActionDialog.cs`-Verhalten fuer Makro-Steps. +Committen: prägnante Commit-Message je abgeschlossenem, verifiziertem +Arbeitspaket. Nach jedem Push: alle bekannten Remotes prüfen (`origin` auf +GitHub, `jappel` auf git.jappel.io) — beide müssen synchron bleiben, siehe +Speicher-Notiz "Multi-Remote-Repos synchron halten". diff --git a/README.md b/README.md index c4de640..ebe6691 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,16 @@ Belegung an, kann sie live mit dem Board synchronisieren und komplett neu programmieren — als Ergänzung zur offiziellen [VersaGUI](https://git.jappel.io/jappel/VersaGUI) (C#/.NET), nicht als Ersatz. +Aktive Weiterentwicklung. Lesemodus, Live-Sync, Programmiermodus (inkl. +Board-Schreibzugriff) und der MCP-Server sind funktionsfähig und gegen ein +echtes Board getestet (Read-Modify-Write ist byte-identisch zum Original, +inklusive CRC). Nicht vorhanden: automatisierte Tests (Verifikation läuft +manuell gegen ein angeschlossenes Board), eine vorgefertigte `.exe` zum +Download (siehe unten, warum), und Mehrbenutzer-/Netzwerkbetrieb. Die +Standard-Dateipfade für die Config-JSONs sind aktuell für eine bestimmte +Windows-Maschine hartkodiert (`versapad_data.CONFIG_PATHS`, +`versapad_combined.DEFAULT_PATH`) — für einen anderen Rechner dort anpassen. + ## Features - **Steuermatrix-Anzeige** — 4×5-Button-Grid + 4 Encoder, farbige LED-Vorschau,