# `clusev` Host-CLI + kurze Befehle + Tab-URL — Design

**Goal:** Operatoren rufen kurze, professionelle Befehle auf (`sudo clusev update`, `clusev reset-admin`, …) statt langer `docker compose -f docker-compose.prod.yml …`-Kommandos. Alle user-sichtbaren Stellen zeigen die Kurzform; die Hilfe erklärt ausführlich, was jeder Befehl real tut. Der Help-Tab landet wie die Settings-Tabs in der URL.

**Architecture:** Ein generiertes Host-Skript `/usr/local/bin/clusev` kapselt die Prod-Stack-Kommandos (Install-Verzeichnis eingebacken). Die UI/Hilfe/Lang-Strings zeigen nur noch `clusev <sub>`. Keine Datei-Umbenennung (`docker-compose.prod.yml` bleibt intern, wird aber nirgends mehr angezeigt).

**Tech Stack:** Bash (Wrapper), Laravel 13 / Livewire 3 (Help-Komponente `#[Url]`), Blade-Hilfe-Partials (DE/EN), `install.sh` (Rendern + Installieren).

---

## Teil A — `clusev` Host-Befehl

- **Template im Repo:** `docker/clusev/clusev` (Bash) mit Platzhalter `__CLUSEV_DIR__` für das Install-Verzeichnis. Muster wie MOTD/Sentinel (Template + `install.sh` substituiert).
- **Installation:** in einer `install.sh`-Phase rendern (`__CLUSEV_DIR__` → `$(pwd)`) und mit `install -m 0755` nach `/usr/local/bin/clusev` legen. Best-effort: schlägt es fehl (z. B. read-only), nur warnen, nie den Installer abbrechen.
- **Robustheit:** das Skript nutzt eine Funktion `compose() { docker compose -f "$CLUSEV_DIR/docker-compose.prod.yml" "$@"; }` (sauberer als Wort-Splitting bei Pfaden).
- **Unterbefehle:**

| Host-Befehl | führt real aus |
|---|---|
| `sudo clusev update` | `"$CLUSEV_DIR/update.sh"` (git pull --ff-only + Rebuild + Migrate; erzwingt root) |
| `clusev reset-admin` | `compose exec app php artisan clusev:reset-admin` |
| `clusev restart` | `compose up -d` |
| `clusev logs` | `compose logs -f "$@"` |
| `clusev ps` / `clusev status` | `compose ps` |
| `clusev migrate` | `compose exec app php artisan migrate --force` |
| `clusev artisan <…>` | `compose exec app php artisan "$@"` (Power-User) |
| `clusev version` | liest die Version aus `$CLUSEV_DIR/config/clusev.php` (Host-Datei, kein Container nötig) |
| `clusev help` / `-h` / `--help` / (leer) | Usage-Übersicht (alle Befehle + Einzeiler) |

- **Verhalten:** unbekannter Befehl → Usage + Exit 64. `update` erzwingt root über `update.sh`; die übrigen Befehle brauchen nur Docker-Zugriff (Operator ist root oder docker-group). Argumente werden durchgereicht (`"$@"`).
- **Naming:** der **Host**-Befehl ist `clusev reset-admin` (Leerzeichen, Standard wie git/docker). Der zugrunde liegende artisan-Befehl bleibt `clusev:reset-admin` (unverändert).

## Teil B — Tab-URL für die Hilfe

- `app/Livewire/Help/Index.php`: `use Livewire\Attributes\Url;` + `#[Url] public string $topic = 'overview';` (genau wie `Settings\Index::$tab`). Der Default `overview` erscheint nicht als Param; andere Themen schon (`/help?topic=security`). Reload/Lesezeichen/Teilen behalten das Thema.
- Der bestehende `render()`-Clamp (unbekanntes Thema → `overview`) bleibt und schützt vor `?topic=bogus`.
- Die `mount(?string $topic)`-Methode **bleibt** (harmlos; bestehende Tests übergeben `topic` als mount-Param) — `#[Url]` ergänzt nur die Query-Bindung; der render()-Clamp validiert beides.

## Teil C — Alle user-sichtbaren Befehle umstellen

`docker-compose.prod.yml` und lange `docker compose -f …`-Kommandos verschwinden aus der UI:

- **Version → „Aktualisierung"** (`resources/views/livewire/versions/index.blade.php` + `lang/{de,en}/versions.php` `update_hint`): der 3-Zeilen-Block (`pull` / `up -d` / `migrate --force`) → einzeiliger Hinweis + `sudo clusev update`.
- **Hilfe → Wiederherstellung** (`content/{de,en}/recovery.blade.php`): `docker compose … clusev:reset-admin` → `clusev reset-admin`.
- **Hilfe → Updates** (`content/{de,en}/updates.blade.php`): `sudo ./update.sh` → `sudo clusev update`.
- **Lang-Strings** mit reset-admin (`lang/{de,en}/system.php`, `lang/{de,en}/settings.php`): den langen Befehl → `clusev reset-admin`.
- **MOTD** (`docker/motd/00-clusev`): „Verwalten"-Zeile → `clusev ps | logs | restart`; „Reset"-Hinweis → `clusev reset-admin`.

## Teil D — Hilfe-Thema „Befehle" + ausführliche Erklärungen

- **Neues Thema** `commands` (Schlüssel) in `Help\Index::TOPICS`, Label `help.topic_commands` (DE „Befehle / CLI", EN „Commands / CLI"). Einsortiert nach `updates`.
- **Partials** `content/{de,en}/commands.blade.php`: pro Befehl eine Karte/Zeile mit
  - der **Kurzform** (`clusev <sub>`, `font-mono`),
  - einer **ausführlichen Erklärung**, was er tut und wann man ihn braucht,
  - dem **echten Kommando** darunter (das vollständige `docker compose …` bzw. `update.sh`), damit Fortgeschrittene verstehen, was im Hintergrund passiert.
- Die Erklärungen in „Updates" und „Wiederherstellung" verweisen knapp auf „Befehle".

## Teil E — Dateistruktur

- Neu: `docker/clusev/clusev` (Wrapper-Template).
- Neu: `resources/views/livewire/help/content/{de,en}/commands.blade.php`.
- Ändern: `install.sh` (Render+Install des Wrappers), `app/Livewire/Help/Index.php` (`#[Url]`, TOPICS += `commands`, render-Labels), `resources/views/livewire/help/content/{de,en}/{recovery,updates}.blade.php`, `resources/views/livewire/versions/index.blade.php`, `lang/{de,en}/help.php` (`topic_commands`), `lang/{de,en}/versions.php` (`update_hint`), `lang/{de,en}/system.php` + `lang/{de,en}/settings.php` (reset-admin-Strings), `docker/motd/00-clusev`.
- README darf die Kurzform ebenfalls erwähnen (optional, konsistent).

## Teil F — Test & Verifizierung

- **Wrapper:** `bash -n` auf das gerenderte Skript; auf der VM real `clusev help`, `clusev ps`, `clusev version` ausführen (read-only, kein Reset). `install.sh` legt `/usr/local/bin/clusev` mit Mode 0755 an.
- **Hilfe/Lang (Livewire-Test, `HelpPageTest`):** das Thema `commands` rendert (Marker `clusev`); Wiederherstellung zeigt `clusev reset-admin` und **nicht** `docker-compose.prod.yml`; `Help\Index` hat `#[Url]` auf `$topic` (Query-Param-Verhalten testbar).
- **R12 Browser (Domain):** `/help` lädt 200, Themen-Wechsel inkl. neuem „Befehle"; `?topic=commands` per Reload bleibt; DE/EN; keine Konsolenfehler/Leaks.
- **R15 Codex** über den Diff.

## Teil G — Bewusst NICHT enthalten (YAGNI)

- Keine Umbenennung der Compose-Dateien (Kollision dev/prod + Risiko auf laufenden Stacks; der Wrapper versteckt den Namen).
- Kein Bash-Completion für `clusev` (kann später kommen).
- Keine Änderung der internen Skripte (`install.sh`/`update.sh`/`watch.sh` nutzen weiter `docker compose -f …` — das ist Implementierung, nicht user-sichtbar).
