Zwei Befunde des Commanders (01.09.2026):
1. "Momentan ist alles nach links gerueckt, nichts skaliert mit der
fenstergroesse und es ist alles gequetscht."
Ursache gefunden: <main> hatte WEDER Zentrierung NOCH Maximalbreite,
die Karten darin aber einen harten Deckel von max-w-2xl (672 px). In
einem 1280er Fenster klebte damit alles am linken Rand und rechts
stand nichts. Behoben:
* <main> und Kopfzeile teilen sich mx-auto max-w-[1600px] mit
mitwachsendem Innenabstand — der Inhalt ist mittig und nutzt die
Breite.
* Der 672-px-Deckel der Einstellungs-Spalte ist weg. Drei
Encoder-Felder stehen jetzt nebeneinander statt untereinander.
* Die Sektionswahl der Einstellungen wird im schmalen Fenster zur
Zeile ueber den Karten (lg:flex-row), statt eine 176-px-Spalte vom
ohnehin knappen Platz abzuziehen.
* Info-Kacheln der Laufwerks-Karte: zwei Spalten schmal, vier breit.
* Startgroesse 1000x700 -> 1280x820, Mindestmass 720x480 -> 860x560.
2. "waere sogar richtig cool wenn du den rahmen wegbekommst"
frame:false, und die Kopfzeile IST jetzt die Titelleiste:
Minimieren / Maximieren / Schliessen sitzen oben rechts in
Windows-Massen (46x32), gezogen wird an der Kopfzeile, Doppelklick
maximiert. Groesse aendern bleibt moeglich — Electron setzt fuer
rahmenlose Fenster unter Windows weiter WS_THICKFRAME (thickFrame,
Standard true), die Kanten ziehen also wie gewohnt.
Schliessen nimmt GENAU den Weg des alten Fensterkreuzes
(fenster.close() -> der bestehende close-Horcher versteckt nur):
Rippy lebt im Tray weiter, ein laufender Rip merkt davon nichts
(Paragraph 4.1 Punkt 3).
Die Ziehflaeche ist .ziehbar in stil.css; alles Bedienbare darin
traegt .nicht-ziehbar, sonst verschluckt der Griff den Klick.
fensterMaximiert im HauptStatus entscheidet ueber das Knopf-Symbol
und wird auch bei Doppelklick/Tastenkuerzel nachgefuehrt (maximize-
und unmaximize-Horcher).
Nachgemessen mit dem Smoke-Beweis: beweise/ui-513-uebersicht.png (kein
Rahmen, eigene Knoepfe, Inhalt ueber die volle Breite) und
beweise/ui-513-einstellungen.png (drei Encoder nebeneinander).
230 Tests gruen, Typpruefung sauber. Version 5.1.3.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Beweise — die Messungen zu KONZEPT-WINDOWS.md § 3
Diese zwei Skripte sind die Grundlage für die Entscheidung, Rippy v5 in TypeScript/Node zu bauen. Sie beantworten die einzige Frage, an der das ganze Konzept hängt:
Kann Node überhaupt alles, was Rippy am Laufwerk braucht?
Wäre die Antwort nein gewesen, wäre das Konzept wertlos gewesen. Deshalb sind sie zuerst gelaufen — vor der ersten Zeile Konzept.
AGENTS.md Regel D: „Externe Schnittstellen NIE aus dem Kopf."
Nachstellen
npm install koffi
node laufwerk.js
Gemessen am 30.08.2026 mit Node v24.19.0, koffi 3.1.6, an einem HL-DT-ST BD-RE BU40N (USB) mit eingelegter Blu-ray.
laufwerk.js — Win32-Laufwerkszugriff
Ruft dieselben Steuercodes auf wie src/rippy/drives/win_ioctl.py im
Docker-Zweig. Nur lesend — kein Auswerfen, kein Verriegeln.
1. GetLogicalDrives + GetDriveTypeW -> optische Laufwerke: [ 'G' ]
2. CreateFileW \\.\G: (Zugriff 0) -> offen
CreateFileW \\.\G: (GENERIC_READ) -> offen
3. IOCTL_STORAGE_QUERY_PROPERTY -> Hersteller: HL-DT-ST | Modell: BD-RE BU40N
| Rev: 1.03 | Serial: 0025114C0149
4. IOCTL_STORAGE_CHECK_VERIFY2 -> Medium eingelegt
5. IOCTL_CDROM_DISK_TYPE -> Win32-Fehler 50
6. IOCTL_DISK_GET_LENGTH_INFO -> 33.759.690.752 Bytes (33,76 GB) => Blu-ray
Punkt 5 ist kein Fehlschlag. Fehler 50 ist ERROR_NOT_SUPPORTED — genau
das, was der Python-Treiber an diesem Laufwerk auch sieht (SAVEPOINT.md,
v4.0-rc11, Abschnitt „Das Laufwerk"). Node verhält sich identisch. Die Lehre
steht im alten Code und gilt weiter: Die Disc-Einordnung darf sich nicht auf
IOCTL_CDROM_DISK_TYPE verlassen — die Größe ist der verlässliche Weg.
Punkt 2 zeigt die Unterscheidung, die in rc11 teuer war: Zugriff 0 fragt das
Gerät, GENERIC_READ fragt das Medium. Bei einer gestörten Disc
scheitert das zweite und das erste geht weiter — wer nur eins probiert, hält
ein antwortendes Laufwerk für tot.
leine.js — die Prozess-Leine (Job Object)
Stellt den Befund aus SAVEPOINT.md v4.0-rc10 nach: Windows räumt
Kindprozesse nicht auf. Ein hart beendeter Rippy hinterlässt ein
makemkvcon, das das Laufwerk festhält, und jeder spätere Rip scheitert.
Das Skript setzt eine Arbeitsgruppe mit JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
startet ein langlebiges Kind und lässt sich dann hart abschießen —
taskkill /F ohne /T, also genau das, was bei einem Absturz und beim
Drüber-Installieren passiert.
1. CreateJobObjectW -> Arbeitsgruppe angelegt
2. SetInformationJobObject -> KILL_ON_JOB_CLOSE gesetzt
3. AssignProcessToJobObject -> dieser Prozess hängt in der Gruppe
4. Kindprozess gestartet, PID 16040
vor dem Abschuss: Eltern lebt: True Kind lebt: True
taskkill /F /PID 29488 -> ERFOLGREICH
danach: Eltern lebt: False Kind lebt: False
Nachstellen (PowerShell):
$p = Start-Process node -ArgumentList "leine.js" -PassThru -RedirectStandardOutput out.txt
Start-Sleep 3
$kind = (Select-String -Path out.txt -Pattern 'KIND-PID=(\d+)').Matches[0].Groups[1].Value
taskkill /F /PID $p.Id
Start-Sleep 2
Get-Process -Id $kind -ErrorAction SilentlyContinue # muss LEER sein
sqlite-main.js + sqlite-kern.js — node:sqlite in Electron
Beantwortet die Frage, die in der ersten Fassung des Konzepts als ⚠️ offen
stand: Electron baut sein Node mit eigenen Flags — ist node:sqlite dort
überhaupt vorhanden?
Gemessen am 30.08.2026 mit Electron 44.0.0, und zwar im
utilityProcess — dem Kontext, in dem Rippy v5 seine Datenbank betreiben
wird (kern/speicher/db.ts), nicht bloß im Node-Modus der Binary:
KERN-ANTWORT: {"ok":true,"wert":"geht","node":"24.18.1"}
Kern beendet mit 0
Antwort: ja. Die im Konzept vorgesehene Rückfallebene better-sqlite3
wird nicht gebraucht. (Zur Einordnung: In Node 24.19.0 pur war dieselbe
Messung zuvor ebenfalls grün.)
Nachstellen:
npm install electron@44 --no-save
node node_modules/electron/install.js
./node_modules/electron/dist/electron.exe sqlite-main.js
Die zweite Zeile ist kein Versehen — siehe nächster Abschnitt.
npm 11 blockiert Install-Skripte — und das trifft Electron selbst
npm warn allow-scripts koffi@3.1.6 (install: node ./cnoke.cjs -P . --prebuild --release)
koffi lädt trotzdem — es bringt vorgebaute Binärdateien mit. Electron
trifft die Sperre härter: Sein Install-Skript lädt die eigentliche
Programmdatei herunter; wird es geblockt, liegt nach npm install ein
Paket ohne dist/electron.exe da, und nichts startet. Am 30.08.2026
beim sqlite-Beweis selbst hineingelaufen; node node_modules/electron/install.js
holt die Binary nach. Beides gehört in die Bau-Anleitung, sonst sucht eines
Tages jemand an der falschen Stelle.