Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .github/workflows/maintenance-tui.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Maintenance TUI

on:
push:
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: Maintenance TUI (${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, macos-14, windows-2022]

steps:
- name: Check out repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Install .NET 10 SDK
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d # v5.0.0
with:
dotnet-version: 10.0.x

- name: Install Python
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: "3.13"

- name: Restore locked projects
shell: pwsh
run: |
dotnet restore scripts/lib/maintenance-tui/src/HomeBaseline.MaintenanceTui/HomeBaseline.MaintenanceTui.csproj --locked-mode
dotnet restore scripts/lib/maintenance-tui/tests/HomeBaseline.MaintenanceTui.Tests/HomeBaseline.MaintenanceTui.Tests.csproj --locked-mode

- name: Build maintenance TUI
shell: pwsh
run: dotnet build scripts/lib/maintenance-tui/src/HomeBaseline.MaintenanceTui/HomeBaseline.MaintenanceTui.csproj --configuration Release --no-restore

- name: Test maintenance TUI
shell: pwsh
run: dotnet test scripts/lib/maintenance-tui/tests/HomeBaseline.MaintenanceTui.Tests/HomeBaseline.MaintenanceTui.Tests.csproj --configuration Release --no-restore

- name: test-maintenance-tui-wrappers (macOS and Ubuntu)
if: runner.os != 'Windows'
shell: bash
run: python3 -m unittest scripts.tests.test_maintenance_tui_wrappers -v

- name: test-maintenance-tui-wrappers (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: python -m unittest scripts.tests.test_maintenance_tui_wrappers -v

- name: Run full maintenance regressions (macOS and Ubuntu)
if: runner.os != 'Windows'
shell: bash
run: python3 -m unittest discover -s scripts/tests -p 'test_*.py'

- name: Run full maintenance regressions (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: python -m unittest discover -s scripts/tests -p 'test_*.py'

- name: Validate Bash syntax
if: runner.os != 'Windows'
shell: bash
run: bash -n scripts/maintain-agentic-workspace.sh

- name: Inventory packages
shell: pwsh
run: dotnet list scripts/lib/maintenance-tui/tests/HomeBaseline.MaintenanceTui.Tests/HomeBaseline.MaintenanceTui.Tests.csproj package --include-transitive

- name: Audit vulnerable packages
shell: pwsh
run: dotnet list scripts/lib/maintenance-tui/tests/HomeBaseline.MaintenanceTui.Tests/HomeBaseline.MaintenanceTui.Tests.csproj package --vulnerable --include-transitive
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,12 @@ scripts/config/*repository-registry.local.json
**/.DS_Store
docs/.vscode/settings.json
docs/learning-units/.vscode/settings.json

# Feature 018: lokale .NET-TUI-Ausgaben und Laufzeit-Cache
# Feature 018: local .NET TUI output and runtime cache
scripts/lib/maintenance-tui/**/bin/
scripts/lib/maintenance-tui/**/obj/
scripts/lib/maintenance-tui/.build/
scripts/lib/maintenance-tui/.cache/
**/__pycache__/
**/*.pyc
2 changes: 1 addition & 1 deletion .specify/feature.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"feature_directory": "specs/017-preset-profile-worktree-hardening"
"feature_directory": "specs/018-agentic-workspace-tui"
}
85 changes: 80 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1497,8 +1497,36 @@ explicit approval.*

### Ein Wartungsbefehl pro Betriebssystem / One maintenance command per OS

Fuer die normale Gesamtwartung ist nur noch der passende Orchestrator noetig.
Ohne Optionen legt er zuerst Kontroll-Evidence an. Danach schliesst die
Für die normale Gesamtwartung ist nur noch der passende Orchestrator nötig.
Ein argumentloser Aufruf in einem vollständig interaktiven Terminal öffnet
zuerst eine Wartungs-TUI, also eine textbasierte Benutzungsoberfläche im
Terminal. Die sichere Vorauswahl ist **Vorschau (Dry-run)**. Ein
argumentloser Aufruf mit umgeleiteter Ein- oder Ausgabe behält dagegen den
bisherigen unbeaufsichtigten Wartungsvertrag. Jeder vorhandene
Wartungsparameter bleibt ebenfalls headless, also ohne vorgeschaltete
Interaktion.

Die TUI sammelt nur eine typisierte Auswahl, zeigt den entsprechenden Befehl
und startet genau einmal den unveränderten Bash- oder PowerShell-Orchestrator.
Vor einem schreibenden Lauf ist eine Bestätigung erforderlich, deren Standard
`Nein` ist. Die TUI erteilt keine Commit-, Push-, Merge-, Secret-,
Provider- oder Administratorrechte. Sie übernimmt auch keine
Wartungsentscheidung aus dem Skript.

*For normal maintenance, only the matching orchestrator is needed. An
argument-free invocation in a fully interactive terminal first opens a
terminal user interface (TUI). Its safe default is **Dry-run**. An
argument-free invocation with redirected input or output preserves the
existing unattended maintenance contract. Every existing maintenance option
also remains headless.*

*The TUI collects one typed selection, displays the equivalent command, and
starts the unchanged Bash or PowerShell orchestrator exactly once. A mutating
run requires confirmation with a default of `No`. The TUI grants no commit,
push, merge, secret, provider, or administrator authority and does not replace
an engine decision.*

Nach dem Start legt die Engine zuerst Kontroll-Evidence an. Danach schließt die
**Remote-Freshness-Barriere** alle begrenzten Fetch-Versuche fuer Level 0 und
jedes aktive Git-Ziel ab. Erst dann darf das Skript sichere Behind-only-Ziele
per Fast-forward aktualisieren, `~/` synchronisieren, die lokale GSDB-Registry
Expand All @@ -1509,9 +1537,9 @@ registriert noch in die Propagation aufgenommen. Vor dem ersten echten Lauf
auf einem weiteren System sind `--check-only` / `-CheckOnly` und anschliessend
die Vorschau empfohlen.

*Normal full maintenance now needs only the matching orchestrator. Without
options it creates control evidence, completes bounded fetch attempts for
Level 0 and every active Git target, and closes the Remote Freshness Barrier.
*After engine start, control evidence is created first. The Remote Freshness
Barrier then completes bounded fetch attempts for Level 0 and every active Git
target.
Only then may it fast-forward safe behind-only targets, synchronize `~/`,
maintain the GSDB registry, check maintenance-package distribution, and
maintain the machine toolchain. One finding does not hide the remaining fleet
Expand All @@ -1521,18 +1549,65 @@ check-only and then preview before the first actual run.*

```bash
# macOS / Linux
bash scripts/maintain-agentic-workspace.sh # TUI im interaktiven Terminal / TUI in an interactive terminal
bash scripts/maintain-agentic-workspace.sh --tui # TUI ausdrücklich / explicit TUI
bash scripts/maintain-agentic-workspace.sh --plain-ui # lineare Auswahl / line-oriented assistant
bash scripts/maintain-agentic-workspace.sh --check-only
bash scripts/maintain-agentic-workspace.sh --dry-run
bash scripts/maintain-agentic-workspace.sh --allow-admin-prompts
```

```powershell
# Windows
pwsh -NoProfile -File scripts/maintain-agentic-workspace.ps1 # TUI im interaktiven Terminal
pwsh -NoProfile -File scripts/maintain-agentic-workspace.ps1 -Tui
pwsh -NoProfile -File scripts/maintain-agentic-workspace.ps1 -PlainUi
pwsh -NoProfile -File scripts/maintain-agentic-workspace.ps1 -CheckOnly
pwsh -NoProfile -File scripts/maintain-agentic-workspace.ps1 -WhatIf
pwsh -NoProfile -File scripts/maintain-agentic-workspace.ps1
```

`--tui` / `-Tui`, `--plain-ui` / `-PlainUi` und
`--no-tui` / `-NoTui` sind gegenseitig ausgeschlossen. Die ersten beiden
dürfen nur mit einer Home-Verzeichnis-Angabe kombiniert werden, weil die
Wartungsoptionen erst in der Oberfläche gewählt werden. `--no-tui` /
`-NoTui` ist der öffentliche Headless-Schalter und zugleich der interne
Rekursionsschutz.

Fehlen Terminalfähigkeiten oder das .NET-10-SDK, schlägt ein Locked Restore
fehl oder kann der benutzereigene Cache nicht sicher veröffentlicht werden,
wechselt die Oberfläche **vor** dem Engine-Start sichtbar in einen linearen
ASCII-Assistenten. Nach Engine-Start gibt es keinen zweiten Versuch und keinen
UI-Fallback. Ein versionierter, append-only JSONL-Ereigniskanal liefert
lediglich Live-Hinweise. Der atomar finalisierte Bericht und der
Prozess-Exitcode bleiben maßgeblich. Cache und Ereignisse liegen privat unter
`~/.home-baseline/` und werden nicht eingecheckt.

Ein erstes `Ctrl+C` wird genau einmal an den laufenden Engine-Prozess
weitergegeben und als kontrollierter Abbruch behandelt; weitere Signale starten
weder einen zweiten Prozess noch eine automatische Bereinigung. Bei einem
ungültigen Ereignis zeigt die Oberfläche dauerhaft
`EVENT_STREAM_DEGRADED` und liest den kanonischen Abschluss aus Bericht und
Exitcode. Die Schlussansicht nennt mindestens Mutationsbarriere,
Repository-Zählung, Preset-Phase, Bericht, Log und nächste Aktion als
kopierbaren Text.

*The three UI selectors are mutually exclusive. Enhanced and plain UI may only
carry a home-directory override because maintenance options are selected in
the interface. Missing terminal capability, .NET 10, locked restore, or a safe
user cache causes a visible plain fallback before engine start. There is no
second attempt or fallback after engine start. Versioned append-only JSONL
events are advisory live information; the atomically finalized report and
process exit remain canonical. Cache and events stay private below
`~/.home-baseline/` and are never committed.*

*The first `Ctrl+C` is forwarded to the running engine exactly once and is
handled as a controlled interruption; later signals start neither another
process nor automatic cleanup. Invalid event input permanently shows
`EVENT_STREAM_DEGRADED`, while the canonical report and exit code determine the
outcome. The final view exposes the mutation barrier, repository counts, preset
phase, report, log, and next action as copyable text.*

Mit `--scripts-only` / `-ScriptsOnly` bleibt die Maschinen-Toolchain
unveraendert. Wartungspaket-Drift wird standardmaessig nur gemeldet und nur mit
`--repair-drift` / `-RepairDrift` lokal korrigiert. Dieser Reparaturmodus
Expand Down
86 changes: 86 additions & 0 deletions docs/accessibility/maintenance-tui.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Barrierefreiheit der Wartungs-TUI / Maintenance TUI Accessibility

## Ziel / Goal

Die Wartung muss ab dem ersten Ausbildungsjahr mit Tastatur,
Screenreader, Braille-Zeile, Textbrowser und `NO_COLOR` verständlich bleiben.
WCAG 2.2 Level AA wird auf die anwendbaren Terminalkriterien übertragen.

*Maintenance must remain understandable from the first apprenticeship year
with keyboard, screen reader, Braille display, text browser, and `NO_COLOR`.
WCAG 2.2 Level AA is applied where its criteria fit a terminal interface.*

## Anwendbare Anforderungen / Applicable Requirements

| Thema | Umsetzung und Evidence |
|---|---|
| Tastaturbedienung | Jeder Prompt ist sequenziell erreichbar; keine Maus erforderlich |
| Fokus und Reihenfolge | Eingabe folgt der sichtbaren linearen Reihenfolge; der aktuelle Prompt enthält eine Textfrage |
| Farbe | `NO_COLOR` wird respektiert; Status besitzt immer ein sichtbares Wort |
| Vergrößerung und Breite | Enhanced ab 100, Compact ab 40, darunter lineare Darstellung |
| Bewegung | Live-Aktualisierung höchstens 10 Hz; keine Information nur durch Animation |
| Fehler | Fehlercode, deutsche Erklärung, englische Entsprechung und nächste Aktion |
| Zeit | Keine zeitbegrenzte Auswahl; Prozessabbruch bleibt kontrolliert |
| Sprache | Deutsch zuerst, Englisch danach, CEFR B2; TUI und Dry-run werden beim ersten Auftreten erklärt |
| Kopierbarkeit | Status, Exitcode, Berichtspfad, Logpfad und nächste Aktion bleiben Text |

## Textmodell / Text Model

Jeder Abschluss enthält mindestens:

```text
Status: <STATUS>
Exitcode / exit code: <NUMBER>
Bericht / report: <PATH>
Log / log: <PATH>
Nächste Aktion / next action: <TEXT>
```

Farbe, Tabellenrahmen, Position oder Fortschrittsanzeige dürfen diese Angaben
nicht ersetzen. Fremde Meldungen werden maskiert, damit Zeichen wie
`[red]` weder Inhalt verbergen noch Terminal-Markup einschleusen.

*Color, table borders, position, or progress display cannot replace the
textual fields. Foreign messages are escaped so strings such as `[red]`
cannot hide content or inject terminal markup.*

## Fallback

`TERM=dumb`, umgeleitete Streams, fehlende Terminalfähigkeit oder ein nicht
verfügbarer TUI-Build führen sichtbar zur linearen ASCII-Auswahl. Die
Sicherheitsregeln, auswählbaren Modi, Bestätigung und Exitcodes bleiben
identisch. Ein Eventfehler degradiert die laufende Anzeige dauerhaft zu
linearem Text und zeigt `EVENT_STREAM_DEGRADED`, beendet oder wiederholt aber
nicht die Wartung. Das erste `Ctrl+C` wird genau einmal weitergegeben; weitere
Signale starten keinen zweiten Prozess. Die Schlussansicht bleibt vollständig
kopierbar und nennt Mutationsbarriere, Repository-Zählung, Preset-Phase,
Bericht, Log und nächste Aktion.

*Unsupported terminal capability selects the linear ASCII path. Event failure
permanently shows `EVENT_STREAM_DEGRADED` without ending or repeating
maintenance. The first `Ctrl+C` is forwarded exactly once, later signals cannot
start a second process, and the complete final summary remains copyable.*

## Prüfnachweise / Verification

- Tastatur- und Auswahltests ohne Maus
- `NO_COLOR`- und ASCII-Status-Snapshots
- Breiten `39`, `79` und `120`
- deutsche und englische Textprüfung
- Spectre-Testkonsole mit sichtbarer Textalternative
- Bash-Fallback unter `TERM=dumb`
- macOS-, Ubuntu- und Windows-Ausführung im CI

Nicht anwendbar sind Zeigerzielgröße, Dragging und grafische Reflow-Kriterien,
weil die Oberfläche keine Maussteuerung oder zweidimensionale
Informationsabhängigkeit besitzt. Diese Entscheidung ist neu zu prüfen, sobald
Mausbedienung oder eine grafische Oberfläche hinzukommt.

*Pointer target size, dragging, and graphical reflow are not applicable
because the interface has no mouse control or two-dimensional information
dependency. Re-evaluate this decision if mouse input or a graphical surface is
added.*

<!-- EN: docs/accessibility/maintenance-tui.md
[DE-Zusammenfassung: WCAG-2.2-AA-Anwendung, Textmodell und Fallback der Wartungs-TUI.]
-->
Loading
Loading