Add stack Update, ComfyUI model manager, and slim ComfyUI stack.

Server UI gains Update on stack cards, ComfyUI Models tab with workflow
scan and downloads, and centralized comfyui_config. Model catalog and
download scripts move from stacks/comfyui to server-ui so ComfyUI stays a
minimal Docker wrapper for easier image updates.
This commit is contained in:
tomasz-syn-grzegorza
2026-07-05 18:45:17 +00:00
parent 359afb3a59
commit 73e4fc005e
33 changed files with 3604 additions and 307 deletions
+44 -5
View File
@@ -1,7 +1,7 @@
# Server UI — CLI (terminal PTY)
**Data:** 2026-07-05
**Status:** wdrożone (bugfix FitAddon: 2026-07-05 patrz [SERVER-UI-CLI-BUGFIX.md](SERVER-UI-CLI-BUGFIX.md))
**Status:** wdrożone (bugfix FitAddon: 2026-07-05; pamięć sesji: 2026-07-05)
Zakładka **CLI** w panelu Server UI (`:8091`) — interaktywny shell bash w przeglądarce (PTY + xterm.js).
@@ -36,8 +36,17 @@ sequenceDiagram
|----------|---------|
| Ścieżka | `/api/cli/ws` |
| Auth | `?api_key=<API_KEY>` (query string) |
| Reattach | `?session_id=<uuid>` (opcjonalnie, z `sessionStorage`) |
| Protokół I/O | surowe bajty terminala (text/binary frames) |
| Resize | JSON: `{"type":"resize","cols":120,"rows":40}` |
| Zamknij sesję | JSON: `{"type":"close"}` (klient → serwer) |
### Handshake sesji (serwer → klient)
| Payload | Znaczenie |
|---------|-----------|
| `{"type":"session","id":"<uuid>"}` | Nowa sesja — ID zapisane w `sessionStorage` (`server-ui-cli-session-id`) |
| `{"type":"replay","complete":true}` | Koniec replay bufora po reattach |
### Przykład (wscat)
@@ -59,7 +68,36 @@ W [`/opt/control-plane/.env`](/opt/control-plane/.env) (opcjonalnie):
| `CLI_ENABLED` | `1` | `0` = WebSocket odrzucany |
| `CLI_SHELL` | `/bin/bash` | Shell PTY (np. `/bin/bash -l`) |
| `CLI_DEFAULT_CWD` | `$HOME` usługi | Katalog startowy |
| `CLI_MAX_SESSIONS` | `5` | Limit równoległych sesji WS |
| `CLI_MAX_SESSIONS` | `5` | Limit równoległych sesji PTY (bash) |
| `CLI_SESSION_TTL` | `300` | Sekundy utrzymania odłączonej sesji przed kill |
## Pamięć sesji
- **Przełączanie zakładek** — WebSocket i bash pozostają aktywne (bez `disconnectCli`)
- **F5 / reload** — `session_id` z `sessionStorage` → reattach do tego samego bash (bufor ~256 KB replay)
- **Połącz ponownie** — wysyła `{"type":"close"}`, czyści `sessionStorage`, nowy bash
- **Zamknięcie karty** — serwer utrzymuje PTY przez `CLI_SESSION_TTL`, potem zwalnia slot
```mermaid
sequenceDiagram
participant Browser
participant SS as sessionStorage
participant WS as WebSocket
participant Mgr as CliSessionManager
participant Bash as bash
Browser->>WS: connect api_key
WS->>Mgr: create_session
Mgr->>Bash: spawn PTY
Mgr-->>Browser: session id
Browser->>SS: zapisz session_id
Note over Browser,Bash: przełączenie zakładki — WS żyje
Browser->>Browser: F5 reload
Browser->>SS: odczyt session_id
Browser->>WS: connect session_id
WS->>Mgr: attach_session
Mgr-->>Browser: replay + live output
```
## Uprawnienia POSIX
@@ -73,7 +111,7 @@ Server UI działa jako **`tomasz-syn-grzegorza`** (`server-ui.service`):
| Plik | Rola |
|------|------|
| [`stacks/server-ui/cli_pty.py`](../stacks/server-ui/cli_pty.py) | PTY + asyncio bridge |
| [`stacks/server-ui/cli_pty.py`](../stacks/server-ui/cli_pty.py) | `CliSessionManager` — PTY, detach/attach, bufor outputu |
| [`stacks/server-ui/app.py`](../stacks/server-ui/app.py) | WebSocket `/api/cli/ws`, mount `/static` |
| [`stacks/server-ui/static/index.html`](../stacks/server-ui/static/index.html) | Zakładka CLI |
| [`stacks/server-ui/static/vendor/xterm/`](../stacks/server-ui/static/vendor/xterm/) | xterm.js + FitAddon (vendored; UMD: `new FitAddon.FitAddon()`) |
@@ -82,9 +120,10 @@ Server UI działa jako **`tomasz-syn-grzegorza`** (`server-ui.service`):
- Pełny shell przez LAN = **wysokie ryzyko** — wymagany `API_KEY` przy `SERVER_UI_HOST=0.0.0.0`
- `CLI_ENABLED=0` jako kill switch
- `CLI_MAX_SESSIONS` ogranicza liczbę równoległych bashów
- `CLI_MAX_SESSIONS` ogranicza liczbę równoległych bashów (PTY, nie połączeń WS)
- Brak whitelisty komend (właściciel serwera)
- Sesja kończy się przy zamknięciu zakładki / rozłączeniu WS (nowy bash przy reconnect)
- Jawne zamknięcie: przycisk **Połącz ponownie** lub `{"type":"close"}`
- Odłączenie WS (reload) → detach + TTL; reattach w tej samej karcie przeglądarki
## Deploy