feat(v5): Etappe W-6 — Setup, Selbst-Update, Erst-Einrichtung, Lizenzen
Ampel / ampel (push) Successful in 1m22s

electron-builder → NSIS: EIN RippySetup-<version>.exe, pro Benutzer,
ohne Adminrechte, eigenes Icon (PNG-basiertes ICO selbst gebaut).
extraResources: die MITGELIEFERTEN Werkzeuge (HandBrakeCLI GPL-2,
flac.exe MIT libFLAC.dll — die Ohne-DLL-Falle aus § 9) samt
Lizenztexten und Quellverweisen (bau/lizenzen, Entscheid 9); vendor/
liegt nicht im Git (74 MB), Befuellung steht in BAUEN.md. Der Kern
findet die mitgelieferten Werkzeuge ueber RIPPY_VENDOR (resourcesvendor) VOR allen anderen Suchwegen.

haupt/update.ts (§ 6.8): electron-updater gegen das oeffentliche Gitea
(festes Tag 'aktuell' als Rueckfallebene, Entscheid 6) — NUR https
(http wird ABGELEHNT; Regel-Tests), NIE waehrend eines Rips (der Haupt
kennt die aktiven Vorgaenge), Fehlschlaege still aber ablesbar
(letzte erfolgreiche Pruefung im Status), installiert beim naechsten
Start. haupt/autostart.ts: HKCU-Run ueber app.setLoginItemSettings,
Toggle in den Einstellungen. Erst-Einrichtung (§ 6.9) im Programm:
5 Schritte, NUR ein Fehler blockiert (kein Laufwerk = Warnung,
MakeMKV-Pflicht mit Klartext-Weg).

GEBAUT UND GEMESSEN (30.08.2026):
- dist-setup/RippySetup-5.0.0-w0.exe — 130,8 MB, SHA-256
  07D39D6BAB74A47C21AA53D847FB5A5DB6990AE9FA1CBC7BE814B51050883115,
  plus .blockmap.
- MESSUNG: Die Update-Auskunft heisst bei Vorab-Versionen nach dem
  KANAL (w0.yml) — erst ein Release ohne Suffix erzeugt latest.yml
  (steht jetzt in BAUEN.md).
- Das GEPACKTE Programm (win-unpacked, asar + resources) besteht den
  Smoke: SMOKE OK, und der Screenshot zeigt die Erst-Einrichtung —
  das Bild eines frischen Rechners.

Bewusst offen (SAVEPOINT): die automatische MakeMKV-Beschaffung
(beschaffen.ts — Download+Installer-Start braucht einen Live-Test);
das Setup NENNT den Weg klar. 185 Tests gruen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-08-30 19:03:40 +02:00
co-authored by Claude Fable 5
parent 2d9cef22b3
commit 9fa3df500d
21 changed files with 4319 additions and 8 deletions
+31
View File
@@ -12,10 +12,12 @@ import { app, dialog, ipcMain, Notification, type BrowserWindow } from 'electron
import { writeFile } from 'node:fs/promises'
import { join } from 'node:path'
import type { HauptStatus, KernNachricht } from '../gemeinsam/nachrichten'
import { autostartAktiv, autostartSetzen } from './autostart'
import { fensterErstellen } from './fenster'
import { KernVerwaltung } from './kernstart'
import { leineSetzen, type LeineStatus } from './leine'
import { trayErstellen, trayHinweis } from './tray'
import { updateEinrichten, updateStand } from './update'
const smokeModus = process.argv.includes('--smoke')
@@ -44,6 +46,10 @@ function start(): void {
let fenster: BrowserWindow | null = null
let kernBereit: Extract<KernNachricht, { art: 'kern-bereit' }> | null = null
let beendenGewollt = smokeModus
// § 6.8 Regel 2: Der Haupt weiß, ob irgendwo gerippt wird — Updates
// warten dann.
const aktiveVorgaenge = new Set<string>()
let updateGestartet = false
const smoke = {
fenster: false,
@@ -67,6 +73,17 @@ function start(): void {
smokePruefen()
} else if (nachricht.art === 'rip-status') {
ripStatusVerarbeiten(nachricht.status)
} else if (nachricht.art === 'einstellungen') {
// Einmalig das Selbst-Update einrichten — die Adresse kommt aus
// der EINEN Einstellungs-Quelle im Kern (§ 6.7/§ 6.8).
if (!updateGestartet && !smokeModus) {
updateGestartet = true
updateEinrichten(
nachricht.werte['updateUrl'] ?? '',
() => aktiveVorgaenge.size > 0,
(text) => toast('Rippy-Update', text),
)
}
} else if (nachricht.art === 'disc-info' && nachricht.info.titel.length > 0 && !smokeModus) {
// Windows-Toast beim Erkennen (§ 7) — Klick holt das Fenster hoch.
toast(
@@ -85,6 +102,11 @@ function start(): void {
// § 7: Toasts, Taskleisten-Fortschritt und Tray-Zustand aus dem
// Rip-Status — die Information, die man will, ohne das Fenster zu öffnen.
function ripStatusVerarbeiten(status: Extract<KernNachricht, { art: 'rip-status' }>['status']): void {
if (status.phase === 'rippt' || status.phase === 'komprimiert' || status.phase === 'legt-ab' || status.phase === 'liest-info') {
aktiveVorgaenge.add(status.id)
} else {
aktiveVorgaenge.delete(status.id)
}
if (fenster !== null && !fenster.isDestroyed()) {
if ((status.phase === 'rippt' || status.phase === 'komprimiert') && status.prozent >= 0) {
fenster.setProgressBar(status.prozent / 100)
@@ -126,6 +148,8 @@ function start(): void {
version: app.getVersion(),
leine,
kern: kernVerwaltung.zustand(),
autostart: autostartAktiv(),
update: updateStand(),
}
fenster.webContents.send('haupt-status', status)
}
@@ -173,6 +197,13 @@ function start(): void {
}
})
// Autostart (§ 8): HKCU\...\Run über Electrons eigene API.
ipcMain.handle('autostart-setzen', (_ereignis, an: unknown) => {
autostartSetzen(an === true)
statusSenden()
return autostartAktiv()
})
// Echter Windows-Ordnerdialog (§ 7) — der Nutzer sieht seine
// Netzlaufwerke und Schnellzugriffe statt eines nachgebauten Browsers.
ipcMain.handle('ordner-waehlen', async (_ereignis, titel: unknown) => {