Commit Graph

214 Commits

Author SHA1 Message Date
Sucukdeluxe
c8beaf96ed Ferndiagnose (MCP): Verbindungscode + abgesicherter Fernzugriff + stdio-Bridge
Neue Funktion, um Diagnose eines laufenden Servers aus der Ferne zu ermoeglichen:
Hilfe -> Remote-Support -> "Ferndiagnose (MCP)". Erzeugt einen Verbindungscode,
den der Assistent nutzt, um Status, Logs, Fehler und Accounts read-only zu lesen.

App-Seite:
- Live (re)startbarer Debug-Server ohne App-Neustart (restartDebugServer wartet auf
  'close' + closeAllConnections, behandelt EADDRINUSE).
- IP-Allowlist (debug_allowlist.txt, exakte IP + CIDR), erzwungen VOR der Auth.
  Fail-closed: Netzwerk-Bind (0.0.0.0) ohne Allowlist akzeptiert nur Loopback.
- One-Click Aktivieren/Aktualisieren/Deaktivieren + Token-Rotation (alter Code sofort
  ungueltig). Sichtbarkeit waehlbar: "Nur lokal" (Tunnel-Empfehlung) vs "Im Netzwerk".
- Verbindungscode rddiag:v1:base64url({v,h,p,t,n?,fp?,s?}); oeffentlicher Host frei
  waehlbar, Netzwerk-IPs als Schnellauswahl.
- Neue IPC: get/enable/disable/rotate Remote-Diagnostics; Controller-Methoden; Typen.

Bridge (tools/rd-diagnostics-mcp, standalone, KEINE App-Dependency):
- stdio MCP-Server (@modelcontextprotocol/sdk) mit 14 Tools, proxyt die bestehende
  HTTP-Debug-API. Multi-Server ueber code/server/RDDIAG_CODE/RDDIAG_SERVERS.
- TLS-Fingerprint-Pinning auf secureConnect (vor Token-Versand), falls https genutzt.
- test/harness.mjs: faehrt einen Fake-Debug-Server hoch und treibt die Bridge als
  echten stdio-Child per JSON-RPC -> voller Protokollpfad gruen.

Sicherheit (Audit): keine persistenten Secrets in den Logs der Debug-API (Passwoerter
redigiert, keine Debrid-Keys/aufgeloesten Download-URLs geloggt; settings/accounts
redigiert). Empfohlener Transport: Loopback + privater Tunnel; Direkt-Bind nur mit
Allowlist in vertrauenswuerdigen Netzen.

Tests: connection-code-Cross-Check (App-Encoder <-> Bridge-Decoder), Allowlist-Matrix
(Loopback, exakt, CIDR, fail-closed, Live-Restart). Volle Suite 905 gruen, tsc=6.
2026-06-19 17:05:28 +02:00
Sucukdeluxe
1e04b7bdcb Fix: Bearbeiten eines Mega-Debrid-Accounts ändert nicht mehr heimlich die API/Web-Bevorzugung
Sind beide Mega-Debrid-Modi (API + Web) aktiv, entscheidet megaDebridPreferApi,
welcher Modus zuerst versucht wird. Beim Speichern des Account-Dialogs hat
applyAccountDialogToSettings diese Einstellung jedoch fest überschrieben: ein
Bearbeiten der API-Zeile erzwang megaDebridPreferApi=true, ein Bearbeiten der
Web-Zeile erzwang false. Wer also bewusst Web bevorzugt (preferApi=false) hatte
und nur einen zweiten Account hinzufügen oder das Tageslimit ändern wollte und
dafür die API-Zeile bearbeitete, dem wurde die Reihenfolge ungefragt auf
"API zuerst" umgestellt — was die Provider-Auflösung für alle künftigen
Mega-Links ändert.

Fix: Die festen megaDebridPreferApi-Werte aus beiden Dialog-Zweigen entfernt.
Der bestehende Wert wird über den ...settings-Spread durchgereicht. Erst-Anlage
bleibt korrekt, weil der Default ohnehin true ist (constants). Bei nur EINEM
aktiven Modus ist preferApi ohnehin irrelevant (die single-mode-Zweige
kurzschließen davor).

Test: bei beiden Modi aktiv + preferApi=false bleibt nach API-Edit false; bei
preferApi=true bleibt nach Web-Edit true. Mit der alten Festverdrahtung kippt der
Wert (rot bewiesen).
2026-06-17 05:54:42 +02:00
Sucukdeluxe
76b3f99476 Fix: Mega-Debrid-Account sperrt sich nicht mehr dauerhaft selbst (Self-Cooldown bis Neustart)
Ein gesunder Mega-Debrid-Account konnte sich dauerhaft "bis Neustart" sperren,
ohne sich von selbst zu erholen — genau das vom Nutzer beobachtete Verhalten
("das Tool setzt sich selbst Cooldowns"). Zwei Ursachen, beide behoben:

1) Falsche Einstufung eines HOSTER-Problems als ACCOUNT-Limit:
   classifyAccountFailure hat den hoster-spezifischen Fehler "Kein Server fuer
   diesen Hoster" (MEGA_DEBRID_NO_SERVER_RE — Mega-Debrid hat fuer EINEN Hoster,
   z.B. Rapidgator, gerade keinen Server) mit limitSignal=true markiert. Dieses
   Signal speist den "bis Neustart"-Streak (3x -> Dauer-Park). Bei einer
   Warteschlange voller Links desselben (kurzzeitig nicht bedienbaren) Hosters
   kletterte der Streak hoch und parkte einen kerngesunden Account — der sich
   dann ueber die Rotation auf ALLE Accounts ausbreitete. Fix: limitSignal aus
   dem No-Server-Zweig entfernt (der 120s-Cooldown bleibt). Hoster-Verfuegbarkeit
   ist kein Account-Gesundheitssignal. Der echte Tageslimit-Pfad (leere Antwort)
   bleibt unveraendert.

2) "Bis Neustart"-Park hatte keine Ablaufzeit (until = MAX_SAFE_INTEGER) und
   konnte daher NIE von selbst aufgehen — auch nicht, nachdem Mega-Debrid wieder
   Server hatte oder das Tageslimit um Mitternacht zuruecksetzt. Nur ein Neustart
   half. Fix: Der Park laeuft jetzt zum naechsten Tagesreset (lokale Mitternacht,
   mind. 120s) ab und heilt sich damit garantiert innerhalb von <=24h selbst —
   egal welcher Zweig ihn ausgeloest hat. Texte entsprechend von "bis Neustart
   gesperrt" auf "bis zum Tagesreset gesperrt" angepasst (Main + Renderer
   konsistent).

Tests: (a) ein geparkter Account ist nach dem Tagesreset wieder frei statt
dauerhaft gesperrt (rot ohne Fix: MAX_SAFE_INTEGER laeuft nie ab); (b) ein
"no server"-Fehler liefert kein limitSignal mehr (rot ohne Fix), waehrend die
echte leere Antwort weiterhin als Limit zaehlt. 86 Debrid-Tests gruen.
2026-06-17 05:47:52 +02:00
Sucukdeluxe
6d4da02f92 Fix: Mega-Debrid-Umwandlung robust + parallel — schneller Retry, alle Accounts, sichtbarer Grund
R3 (Kern): Transiente Resolve-Fehler ("Datei beim Hoster gerade nicht
abrufbar", frz. "Fichier supprimé") werden jetzt mit kurzem Delay
(3–6–10s) neu versucht statt mit dem 5s..120s-Exponential. Ein solcher
Einzel-Fehler zählt nicht mehr zum Provider-Circuit-Breaker (der bei 20
Fehlern 30–300s Cooldown setzt und die Mega-Session invalidiert) und
löst keine Provider-Cooldown-Inflation aus — dadurch bremst er die
gesunden Links nicht mehr aus. Neuer Branch vor der generischen
Unrestrict-Retry-Logik; Detektor isMegaDebridTransientResolveFailure
matcht sowohl die rohe französische als auch die gerenderte deutsche
Meldung (am Download-Manager kommt die klassifizierte deutsche an).

R2 (parallel): getSerializedValidatingLimit für megadebrid-web ist nicht
mehr hart 1, sondern die Anzahl nutzbarer Accounts. Der harte Wert 1
stammte aus der Einzel-Account-Zeit (Commit a3e3d6f). Sicher, weil die
Web-Ebene ohnehin pro Account serialisiert (runExclusive, key=login) und
die Account-Rotation gleichzeitige Aufrufe atomar auf distinkte Accounts
verteilt (megaDebridInFlight wird synchron vor dem await erhöht). Ein
Account → Limit 1 (keine Änderung).

R4 (Sichtbarkeit): Der echte Grund steht inline im Status und als Tooltip
(item.lastError); kaputten "?"-Separator zu "(Rn)" gesäubert.

UI-Bugfixes: Account-Duplizierung beim Entfernen (React-Key-Kollision
API/Web → rowKey nach kind), Username-Spalte zeigt eingegebenen Login
statt Anbieter-Mail (Mail als Tooltip).

Tests: transientResolveRetryDelayMs, isMegaDebridTransientResolveFailure,
2 behaviorale Download-Manager-Tests (schneller Re-Try mit deutschem
Grund; 1 Web-Umwandlung pro Account parallel). 833/833 grün, tsc
unverändert.
2026-06-17 02:07:25 +02:00
Sucukdeluxe
938b84392d Fix: Tote Mega-Debrid-Links (frz. "Fichier supprimé") vergiften nicht mehr die ganze Queue
Mega-Debrid liefert bei geloeschten Hoster-Dateien franzoesische Fehlertexte
("Fichier supprime chez l'hebergeur"). Diese wurden weder in classifyAccountFailure
(debrid.ts) noch in isPermanentLinkError (download-manager.ts) erkannt und landeten
im generischen "temporaer"-Zweig: 30s Account-Cooldown + (bei retryLimit 0) endlose
Wiederholung. Mit nur einem Account (als API UND Web) blockierte ein einziger toter
Link ueber den Cooldown auch alle gesunden Links (SKIP_COOLDOWN) -- die Queue stand.
Beleg aus dem Support-Bundle: 479 von 983 Zeilen im Rotations-Log waren dieser Fehler.

- shared/dead-link.ts: zentrale Tot-Link-Erkennung (frz./dt./engl.), eine Quelle fuer
  beide Schichten, damit die Muster nicht auseinanderdriften.
- classifyAccountFailure: toter Link -> fatal/skip, KEIN Account-Cooldown (Account ist
  gesund, nur die Datei ist weg).
- isPermanentLinkError: toter Link -> Item sofort als gescheitert markiert, kein
  Endlos-Retry. Greift auch im aggregierten Provider-Ketten-Fehlerstring.
- Provider-Kette + interner Web-Fallback: toter Link -> kein Fallback auf weitere
  Provider/Modi (spart den 60s-Web-Timeout; saubere Meldung erreicht isPermanentLinkError
  unveraendert).
- Anzeige: deutsche Klartext-Meldung "Link tot - Datei beim Hoster geloescht" statt frz.
- Account-Liste: Hinweis, dass Mega-Debrid API + Web derselbe Account in zwei Modi sind.

Tests: tests/dead-link.test.ts (inkl. aggregierter Provider-Ketten-String + akzentfreie
Variante). Volle Suite 823/823 gruen.
2026-06-17 00:23:50 +02:00
Sucukdeluxe
622ed1653b Account-Liste: Status-Spalte sortiert nach Premium-Restlaufzeit (Klick)
User-Wunsch: in der Account-Liste auf "Status" klicken und nach Premium-Restlaufzeit
sortieren (laengste<->kuerzeste). Da die Accounts pro Anbieter gruppiert sind, wird
INNERHALB jeder Gruppe sortiert (dort sitzen die Premium-Tage).

- Neuer Zustand accountStatusSort (none -> desc -> asc -> none) per Klick auf den
  Status-Spaltenkopf (mit ▼/▲-Indikator).
- groupedAccountRows sortiert bei desc/asc jede Gruppe nach premiumUntilMs:
  Premium-Accounts nach Restlaufzeit (desc = laengste zuerst, asc = kuerzeste
  zuerst), Accounts ohne Premium/ohne Status bleiben am Ende.

Reine Renderer-Aenderung. tsc=6, build ok.
2026-06-15 03:49:00 +02:00
Sucukdeluxe
d10033f11e Update-Fenster: Changelog wird vollstaendig angezeigt (Truncation entfernt)
Der In-App-Update-Dialog kuerzte den Changelog selbst: eine "compactLines"-Logik
schnitt jede Zeile NACH dem Doppelpunkt ab, wenn dahinter mehr als 60 Zeichen
standen. Aus "- Account-Liste: <lange Beschreibung>" wurde so nur "- Account-Liste:".
Zusaetzlich wurden eingerueckte Unterpunkte und Leerzeilen verworfen.

Fix: Die Kuerzungs-Logik entfernt. Der Changelog wird jetzt vollstaendig
uebernommen (nur Markdown-Sternchen/Backticks und ATX-Ueberschriften werden
gestrippt, 3+ Leerzeilen auf eine reduziert). Die Anzeige-Box bricht ohnehin um
(white-space: pre-wrap) und scrollt (max-height) — es wird also der ganze Text
lesbar dargestellt.

Hinweis: Der Fix greift fuer Update-Fenster AB der naechsten Version; das Fenster
fuer dieses Update wird noch von der alten (kuerzenden) Version gerendert.

Reine Renderer-Aenderung. tsc=6, build ok.
2026-06-15 03:40:14 +02:00
Sucukdeluxe
ce3d7bb728 Account-Liste: kein irrefuehrendes gruenes "Konfiguriert" mehr bei nicht-pruefbaren Anbietern
Single-Token-Anbieter (Real-Debrid, AllDebrid, 1Fichier, DDownload, LinkSnappy,
BestDebrid) haben keine Status-Pruefung. Bisher stand bei ihnen ein gruenes
"Konfiguriert"-Badge in der Status-Spalte, das wie "geprueft & ok" aussah, obwohl
nichts geprueft wurde. Jetzt zeigen sie dort ein dezentes graues "—" (Tooltip:
"Fuer diesen Anbieter gibt es keine Status-Pruefung"). Gruen/gelb/rot bleibt den
tatsaechlich geprueften Mega-Debrid-/Debrid-Link-Accounts vorbehalten.

Reine Renderer-Aenderung. tsc=6, build ok.
2026-06-15 02:02:07 +02:00
Sucukdeluxe
32e43d1a62 Account-Liste: einklappbare Anbieter-Gruppen (z.B. "Mega-Debrid · 4 Accounts")
User-Idee: Anbieter mit mehreren Accounts zusammenfassbar machen, platzsparend.

- Anbieter mit >= 2 Accounts (Mega-Debrid, Debrid-Link) bekommen einen klickbaren
  Gruppen-Kopf "<Anbieter> · N Accounts" mit Chevron zum Ein-/Ausklappen; Einzel-
  account-Anbieter bleiben normale flache Zeilen.
- Gruppen-Kopf zeigt eine Mini-Status-Zusammenfassung als Badges: "X OK" (gruen),
  "Y Problem" (rot, ungueltige Logins), "Z aus" (deaktiviert).
- Standard ausgeklappt (Status bleibt auf einen Blick sichtbar); Klapp-Zustand wird
  pro Anbieter in localStorage gemerkt (rd-account-collapsed-groups-v1).
- Mitglied-Zeilen leicht eingerueckt mit Akzent-Leiste. Zebra-Streifen entfernt
  (mit Gruppen-Koepfen unruhig).
- Zeilen-Rendering in renderAccountRow ausgelagert (fuer flache + Gruppen-Mitglieder
  wiederverwendet); neues groupedAccountRows-useMemo gruppiert accountRows nach Service.

Reine Renderer-Aenderung. 810 Tests gruen, tsc=6, build ok.
2026-06-15 01:46:23 +02:00
Sucukdeluxe
d594afe93a UI Phase 3: Account-Verwaltung als JDownloader-artige Liste (eine Zeile pro Account, Status inline) + Pruefung beim Hinzufuegen
Account-Rework (User-Wunsch nach JDownloader-Vorlage-Screenshot):

- Tabelle zeigt jetzt EINE ZEILE PRO EINZELNEM ACCOUNT statt eine Zeile pro
  Anbieter. Mega-Debrid mit 4 Accounts = 4 Zeilen, Debrid-Link je Key eine Zeile,
  Single-Token-Anbieter je eine Zeile. Neues geflachtes Modell accountRows
  (useMemo) aus configuredAccounts: Mega ueber parseMegaDebridAccounts, DL ueber
  entry.debridLinkKeys, Rest 1:1.
- Spalten wie JDownloader: aktiviert-Checkbox | Hoster (+Modus) | Download-Traffic
  (Rest von Limit "X von Y uebrig" bzw. "Unbeschraenkt") | Status (farbig) |
  Benutzername | Verfallsdatum | Aktion (Bearbeiten/Entfernen).
- STATUS INLINE + farbig (gruen Premium / gelb Free / rot ungueltig / grau nicht
  geprueft / Deaktiviert) direkt in der Zeile, ohne erst "Bearbeiten" zu oeffnen.
  Quelle: settings.debridAccountStatuses[accountId] (Mega/DL werden geprueft),
  Benutzername aus status.email, Verfallsdatum aus premiumUntilMs. Single-Token-
  Anbieter (Real-Debrid, AllDebrid, 1Fichier, ...) werden nicht geprueft -> "Konfiguriert".
- Problemzeilen (Login ungueltig) rot hinterlegt, deaktivierte Zeilen ausgegraut.
- aktiviert-Checkbox schaltet den EINZELNEN Account: Mega via neuem
  onToggleMegaAccountEnabled (megaDebridDisabledAccountIds), DL via bestehendem
  onToggleDebridLinkApiKeyEnabled, Single via onToggleAccountEnabled. Entfernen je
  Account: Mega/DL ueber neue Handler (Zeile aus megaCredentials/debridLinkApiKeys
  raus), Single ueber onRemoveAccount.
- PRUEFUNG BEIM HINZUFUEGEN: onSaveAccountDialog stoesst nach dem Speichern
  checkAllAccounts() an -> Status erscheint sofort in der Liste + Toast meldet
  "X/Y Login gueltig, Z Premium" (Speichern bleibt erlaubt, wie gewuenscht).
- Hoster-Reihenfolge- und Rotations-Verlauf-Panel unveraendert darunter. Alte
  resizable Spalten + "Zugang einzeln"-Toggle entfernt (durch Zeilen ersetzt).
  Web-Login-/AllDebrid-Status-Aktion bleibt als Knopf in der Single-Zeile.
- account-validity-badge.ok von Neon-Verlauf auf flaches Gruen, .disabled ergaenzt.

Reine Renderer-Aenderung. 810 Tests gruen, tsc=6 Baseline, build ok.
Erste Version nach Screenshot — Feinschliff der Optik nach User-Feedback.
2026-06-15 01:11:56 +02:00
Sucukdeluxe
de154ab783 UI Phase 2: Einstellungen-Tab neu strukturiert (Untergruppen + Erklaertexte) + konfigurierbarer Verlauf (Obergrenze + Zeitlimit)
Settings-Rework (User-Wunsch, mit Multi-Agent-Design-Runde fuer die Taxonomie:
3 Lenses -> Synthese, gegen das echte settingsDraft-Inventar auf Vollstaendigkeit
geprueft, 51 Einstellungen je genau einmal platziert).

UI (App.tsx + styles.css):
- 5 der 6 Bereiche (Allgemein/Entpacken/Geschwindigkeit/Bereinigung/Updates) in
  klare Untergruppen mit Unter-Ueberschriften (.settings-subhead) gegliedert, je
  Bereich ein Intro, und unter JEDER Einstellung ein knapper Erklaertext
  (.setting-hint, <= ~90 Zeichen, echte Umlaute). Reihenfolge nach Aufgaben-Logik
  (z.B. Allgemein: Speicherort / Download-Verhalten / Verlauf / Oberflaeche /
  Discord; Entpacken: Ziel & Ablauf / Deutsche Tonspur / Ablageform / Leistung /
  Passwoerter). Einige Labels praezisiert (z.B. "Codeberg Repo" -> "Update-Quelle",
  "Light Mode" -> "Heller Modus"). Account-Bereich bleibt fuer Phase 3 unangetastet.

Verlauf-Retention konfigurierbar (vorher: hart 500, kein Zeitlimit):
- Neue Settings historyMaxEntries (Standard 500) + historyMaxAgeDays (Standard 0=aus)
  in types/constants/normalizeSettings (geclamped 50..100000 bzw. 0..3650) + App-
  Default-Snapshot. Zwei neue Zahlenfelder im Bereich Allgemein -> Verlauf, direkt
  unter "Verlauf speichern"; ausgegraut wenn nicht "Dauerhaft".
- storage.ts: pruneHistoryEntries(entries, limits) wendet Alters- (completedAt <
  jetzt - Tage) und Anzahl-Grenze an; load/save/addHistoryEntry + die *ForRetention-
  Wrapper nehmen optionale Limits. app-controller reicht die Limits aus den Settings
  durch (historyLimits()) und schneidet den Verlauf bei Aenderung der Grenzen aktiv
  neu (damit "aelter als X Tage" wirklich von der Platte fliegt).

2 neue storage-Tests (Anzahl-Cap, Alters-Pruning). 810 Tests gruen, tsc=6 Baseline,
self-check + build ok.
2026-06-15 00:49:19 +02:00
Sucukdeluxe
4c09c9a2f3 UI Phase 1: Statistik 50/50, Footer rechts, Linksammler bis Footer, Bandbreiten-Graph oben rechts, Stat-Karten + Hilfe-Untermenues
Sichtbarkeits-/Layout-Politur (User-Wunsch, Quick-Wins-Paket vor den groesseren
Reworks von Einstellungen-Tab und Account-Verwaltung):

- Statistik: Bandbreitenverlauf und Hoster-Statistik jetzt 50/50 statt 40/60
  (grid-template-columns 1fr 1fr).
- Footer: die Zaehler (Pakete/Links/Session/Gesamt/Hoster/Speed/ETA) wandern
  nach unten-RECHTS, die Aktions-Buttons (Ein-/Ausklappen, Leeren, Clipboard)
  nach links.
- Linksammler: das Textfeld fuellt jetzt die volle Hoehe bis zum Footer
  (collector-view: grid-row 1fr, textarea flex:1) statt bei 220px zu enden.
- Downloads-Tab: neuer Bandbreiten-Graph oben rechts (DownloadSpeedSparkline)
  neben der Suche. Eigener 250ms-Timer mit geglaettetem Verlauf: bei kurzem
  Einbruch auf 0 faellt die Kurve nicht hart ab, sondern gleitet weich runter
  (asymmetrisches Easing: schnell hoch 0.45, langsam runter 0.12) und
  korrigiert sich wieder; die angezeigte Zahl bleibt der echte aktuelle Wert.
  Erste Version - Optik wird nach JDownloader-Screenshot nachgezogen.
- Stat-Karten professioneller: Wert in Zahl + Einheit getrennt (Einheit
  dezent), ruhige Leerzustaende (idle '0'/'—' gedaempft statt nacktem grossen
  '0'), kompaktere Karten, dezentere Eyebrow-Labels.
- Hoster-Balken: flacher Akzent statt Neon-Verlauf (kein Gradient).
- Hilfe-Menue umstrukturiert mit Hover-Untermenues: 'Logs oeffnen' (Haupt-,
  Audit-, Rename-, Session-, Trace-Log), 'Remote-Support' (Support-Bundle +
  Support-Trace), 'Diagnose' (Debug-Setup + Debug-Token); 'Letzte Fehler
  anzeigen' und 'Suche Aktualisierungen' bleiben direkt.

Reine Renderer-Aenderung (App.tsx + styles.css). 808 Tests gruen, tsc=6
Baseline, Build ok.
2026-06-15 00:18:14 +02:00
Sucukdeluxe
86d935e449 Fix: Testen-Button — Speichern-Hinweis + kein stilles Verschlucken
Audit-Befunde R1, R2:
- Nach erfolgreichem Test mit ungespeicherten Einstellungen sagt der Toast
  jetzt "Einstellungen jetzt noch speichern!" — vorher konnte man testen
  (klappt!), nie speichern, und nach dem naechsten App-Neustart/Auto-Update
  feuerte kein einziger Webhook, weil notifyUrl nie persistiert war.
- Button ist waehrend einer laufenden Quick-Action deaktiviert statt den
  Klick still zu verschlucken (performQuickAction returnt sonst kommentarlos).
2026-06-10 00:36:39 +02:00
Sucukdeluxe
25f226db43 Feature: Testen-Button neben der Webhook-URL
Schickt sofort eine Test-Nachricht (inkl. Discord-Ping falls gesetzt) an die
EINGETRAGENEN Entwurfs-Werte — funktioniert also schon vor dem Speichern der
Einstellungen. Toast meldet Erfolg bzw. verweist bei Fehlschlag auf
Hilfe -> Letzte Fehler (dort steht der HTTP-Status/Fehlertext aus notify.ts).
Neuer IPC TEST_NOTIFY (main.ts ruft sendNotification direkt), Button im
input-row-Muster, deaktiviert solange die URL leer ist.
2026-06-09 23:42:15 +02:00
Sucukdeluxe
8ab87bda51 Feature: Discord-Ping in Benachrichtigungen (optionale Erwaehnung)
Neues Settings-Feld "Discord-Ping" unter der Webhook-URL: User-ID, @everyone
oder @here. Wird jeder Webhook-Nachricht vorangestellt, damit Discord wirklich
pingt statt nur still in den Kanal zu schreiben. Eine nackte Zahl wird als
<@id> verpackt (nur so pingt eine User-Erwaehnung); @everyone/@here und fertige
<@...>-Mentions gehen unveraendert durch. Default leer = Verhalten wie bisher.
5 neue Tests (Normalisierung + Content-Prefix).
2026-06-09 21:52:47 +02:00
Sucukdeluxe
41cf36890b Benachrichtigungen: ntfy ersetzt durch Discord-Webhooks
User-Wunsch: Discord statt ntfy. notify.ts sendet jetzt einen JSON-Webhook-POST
({username, content} mit fettem Titel + Nachricht, auf Discords 2000-Zeichen-
Limit gekappt) statt ntfy-Headern. Emoji-Status im Titel (OK/Fehler/Ziel-
flagge) ersetzt Priority/Tags. Settings-UI: Label/Placeholder/Hinweis auf
Discord-Webhook umgestellt (Servereinstellungen -> Integrationen -> Webhooks).
Hooks, Dedup und Guards unveraendert. Tests auf das JSON-Format angepasst
(inkl. Discord-204-Antwort und 2000-Zeichen-Cap).
2026-06-09 21:40:39 +02:00
Sucukdeluxe
e753ea1296 Feature: Push-Benachrichtigungen (ntfy/Webhook) bei Paket fertig/fehlgeschlagen + Run-Ende
Headless-Server: Paket-Ausgaenge waren bisher nur per RDP+Log sichtbar. Neues
Modul notify.ts schickt einen fire-and-forget POST (ntfy-kompatibel: Title/
Priority/Tags als Header, Nachricht als Body) an eine konfigurierbare URL —
mit der kostenlosen ntfy-App aufs Handy, ohne Account/Port/Firewall (outbound).

- Settings: notifyUrl + 3 Ereignis-Toggles (Default aus) in Allgemein.
- Hook 1: Post-Processing-Ende (Paket completed/failed nach Entpacken).
- Hook 2: refreshPackageStatus fuer den Alle-Items-fehlgeschlagen-Fall (Link
  tot -> Paket erreicht das Post-Processing nie; ohne diesen Hook schwiege
  ausgerechnet der haeufigste Fehlerfall).
- Hook 3: finishRun mit Run-Summary (X/Y erfolgreich, Dauer, Schnitt).
- Dedup-Set pro Paket+Run, Lifecycle gespiegelt an historyRecordedPackages
  (Run-Start-Clear, Retry-Deletes, removePackageFromSession). Guard
  session.running || runPackageIds.has(id): nachlaufendes Entpacken nach
  Run-Ende benachrichtigt noch, Startup-Recovery nach App-Neustart nicht
  (sonst Doppel-Push fuer laengst fertige Pakete).
- 5s-Timeout, Fehler nur als logger.warn — blockiert nie den Download-Pfad.
- 9 Unit-Tests fuer notify.ts.
2026-06-09 20:50:58 +02:00
Sucukdeluxe
be4d54a6b5 Feature: "Letzte Fehler anzeigen" im Hilfe-Menue (Error-Ring ins UI)
Der Error-Ring aus v1.7.185 war bisher nur ueber die Debug-Server-URL mit
Token erreichbar — per RDP ist ein Menueklick drastisch schneller als curl.
Neuer Menuepunkt im Hilfe-Dropdown zeigt die letzten 200 WARN/ERROR-Eintraege
(Kopf: "X Fehler, Y Warnungen") im bestehenden Bestaetigungs-Dialog mit
aufklappbaren Details; der Bestaetigen-Knopf kopiert die komplette Liste in
die Zwischenablage — direkt verwertbar fuer Bug-Reports.

IPC-Kette nach dem GET_DEBUG_SETUP_CHECK-Muster (ipc.ts, main.ts mit direktem
error-ring-Import wie debug-server/support-bundle, preload, preload-api).
Read-only auf den In-Memory-Snapshot, kein neues CSS.
2026-06-09 20:45:21 +02:00
Sucukdeluxe
2a1a55401e Feature: Tonspur-Ergebnis sichtbar am Paket (audioStripSummary)
Die Antwort auf "warum hat Paket X noch .DL.?" steht bisher nur in den
Rename-/Item-Logs — "kein Deutsch-Tag" ist INFO-Level und taucht nirgends im
UI auf. Jetzt speichert keepGermanAudioOnlyImpl pro Paket eine Zusammenfassung
(remuxed/kept-single/ohne-DE-Tag/ffmpeg-fehlt/Fehler + bis zu 100 Datei-Details
mit Aktion, Grund und erkannten Sprachen) direkt am PackageEntry:

- Status-Spalte zeigt "Tonspur: 5 OK / 1 ohne DE-Tag / ffmpeg fehlt" (rot bei
  Auffaelligkeiten, flacher Stil), Datei-Details als Tooltip.
- Auch der ffmpeg-nicht-gefunden-Fruehausstieg schreibt die Summary.
- pkg.updatedAt wird gesetzt + Feld im Paket-Delta-Hash, damit der Snapshot
  die Aenderung pusht; normalizeLoadedSession whitelistet das Feld mit
  Shape-Validierung, sonst waere es nach jedem App-Neustart weg.
- 2 neue Integrationstests (Summary-Zaehler + ffmpeg-fehlt-Pfad).
2026-06-09 20:42:22 +02:00
Sucukdeluxe
aa65f56c28 Fix Mega-Web rotation skipping accounts on a timeout abort
When a Mega-Web account's unrestrict aborts because the shared unrestrict
timeout fired while it was running, give that account a 2-min cooldown
(only if it actually ran >=8s, so a quick user-cancel does not cool it
down). The download-manager retry then skips the cooled-down account and
rotates to the next one, instead of hammering the same account every 60s.

- debrid.ts: handle the abort in the rotation catch before classifyAccountFailure
- rotation log event TIMEOUT_COOLDOWN (+ renderer label) replaces the misleading
  red "fataler Fehler" for this case
- RD_MEGA_ABORT_MIN_RUN_MS env override for the run-length threshold
- 2 regression tests (cooldown set -> next call rotates; quick abort -> no cooldown)
2026-06-08 13:33:49 +02:00
Sucukdeluxe
77661389f3 Add "keep only German audio" post-extract step for .DL. files
- New video-processor.ts: ffmpeg/ffprobe remux that keeps only the German
  audio track (by language tag, with safe fallbacks) and strips the ".DL."
  marker from the filename
- Runs after extraction in both the deferred and hybrid post-process paths,
  inside the per-package file-op chain; abortable, disk-space checked,
  mtime-preserving, atomic temp->replace so the original is never lost
- System ffmpeg via PATH / RD_FFMPEG_BIN; toggle + track-mode select in settings
2026-06-07 21:17:26 +02:00
Sucukdeluxe
d006a60553 Backup: nur Settings als Default + 4 Selektions/Flicker-Bugfixes
Backup:
- Neues Setting backupIncludeDownloads (Default aus) — Backup sichert
  standardmaessig NUR Einstellungen, nicht die Download-Liste/History.
- buildBackupPayload/planBackupImport (testbare backup-payload.ts): Export
  omittet session+history wenn Flag aus (explizites kind-Marker); Import folgt
  dem FILE-Inhalt, nicht dem lokalen Toggle.
- importBackup: settings-only -> frueher Return nach setSettings, KEIN stop/
  Queue-Wipe/Relaunch. Return {restored,relaunch,message}; main.ts gated den
  Auto-Relaunch auf relaunch. Renderer re-seeded settingsDraft bei !relaunch.

Bugfixes:
- Ctrl+A waehlte das ungefilterte Paket-Map -> Loeschen nach Suche traf
  versteckte Pakete. Jetzt visibleOrderIds (sichtbare Zeilen, inkl. Items).
- selectedIds nie geprunt bei Delta-Removal -> aufgeblaehte Counts. Neue pure
  pruneSelection (selection.ts) + Effect.
- link-status-dot conditional -> Dateiname sprang ~14px. Platzhalter-Slot.
- sortPackagesForDisplay sortierte aktive Pakete nach Live-Progress -> Reshuffle
  pro Tick. Jetzt stabile Queue-Reihenfolge je Gruppe (Anti-Flicker).

+17 Tests (backup-payload 9, selection 5, package-order anti-flicker 3).
2026-06-07 04:40:54 +02:00
Sucukdeluxe
3ed3877ac9 chore: remove all source code comments and internal artifacts
Strip every comment from the source (parsed with the TypeScript compiler so
strings, template literals, regex literals and JSX are never touched), and drop
internal/working artifacts that do not belong in the public repository
(design mockups, internal analysis docs, a stray backup file and an old log).
No functional change: build is green, the full test suite passes.
2026-06-06 04:53:54 +02:00
Sucukdeluxe
ffcd0817cf Mega-Debrid: Account am Tageslimit bis Neustart parken (Streak-Heuristik) statt endlos neu testen
User-Entscheidung: ein Mega-Debrid-Account am Tageslimit soll bis zum Programm-Neustart
uebersprungen werden, nicht alle 20s/2min neu getestet.

Ground Truth (Support-Bundle gegrept): der limitierte Account liefert im Web-Pfad NIE eine
unterscheidbare Meldung — "Kein Server" = 0 Treffer, "Antwort leer" = 20.861. Tageslimit und
transienter Blip sind auf Message-Ebene nicht trennbar (generate() findet ohne processDebrid-
Code keinen Code -> return null -> "Antwort leer"). Ein Trigger auf "Kein Server" waere toter Code.

Loesung (Verhaltens-Signal statt Wortlaut):
- megaDebridEmptyResponseStreaks zaehlt aufeinanderfolgende "Antwort leer"/"Kein Server"-
  Treffer je Account; ab 3 wird der Account bis Neustart geparkt (until=MAX_SAFE_INTEGER,
  nur In-Memory -> Neustart loescht). Erfolg/anderer Fehler setzt zurueck.
- classifyAccountFailure markiert beide Signale als limitSignal (Symmetrie: ein einzelner
  evtl. transienter Treffer parkt NICHT, behaelt kurzen Cooldown).
- Skip-Branch: "uebersprungen (bis Neustart gesperrt)", traegt nicht zu earliestCooldownUntil
  bei (kein absurder Retry-Timer); Post-Loop wirft klare Endmeldung wenn alle geparkt.
- generate() surfacet "Kein Server" zusaetzlich als Page-Error (falls es doch im HTML steht).
- UI: Rotations-Verlauf zeigt "bis Neustart gesperrt".

Verifiziert: tsc 9 (Baseline), 655 Tests + 5 neue (inkl. Wiring-E2E der eine echte leere
Antwort durch unrestrictWithAccounts->classify->catch->Park treibt), Build gruen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 21:08:43 +02:00
Sucukdeluxe
efb5696c13 Feature: Mega-Debrid-Account beim Hinzufuegen sofort pruefen (Gueltigkeit + Premium)
Beim "Hinzufuegen" eines Mega-Debrid-Accounts im Bearbeiten-Dialog wird der Account
jetzt sofort einzeln geprueft (connectUser) — Login-Gueltigkeit + Premium-Restlaufzeit
erscheinen direkt als Badge, ohne den Tab schliessen und "Alle pruefen" klicken zu
muessen. Waehrend der Pruefung zeigt das Badge "Pruefe…".

Neue Einzel-Check-IPC (Spiegel von checkDebridAccounts): CHECK_MEGA_DEBRID_ACCOUNT
-> app-controller.checkSingleMegaDebridAccount(login, password) baut den Account-Entry
(id via getMegaDebridAccountId), ruft die bestehende checkMegaDebridAccount() und merged
das Ergebnis via applyDebridAccountStatuses -> Snapshot -> Badge (gleicher Pfad wie
"Alle pruefen"). Funktioniert fuer den noch nicht gespeicherten Draft-Account, weil
applyDebridAccountStatuses merged (kein Pruning) + emitState.

Kern-Check-Logik unveraendert + weiterhin durch account-check.test.ts gedeckt.
643 Tests gruen, tsc 9 (unveraendert), Build sauber. GUI compile-/build-verifiziert,
im laufenden Electron noch nicht click-getestet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 14:20:21 +02:00
Sucukdeluxe
66878174e6 Feature: Mega-Debrid-Accounts einzeln (temporaer) deaktivieren — UI-Toggle
Backend war bereits vorhanden (megaDebridDisabledAccountIds + Rotation-Skip +
Storage-Normalisierung); es fehlte nur das UI. Spiegelt das Debrid-Link-Muster:
im Account-Bearbeiten-Dialog bekommt jeder Mega-Account einen Aktivieren/
Deaktivieren-Toggle (+ "Deaktiviert"-Badge). Der Disabled-Zustand wird im Dialog-
Draft gehalten (megaDisabledIds) und beim Speichern via applyAccountDialogToSettings
in megaDebridDisabledAccountIds uebernommen (gefiltert auf vorhandene Accounts).
Kein Live-Persist mitten im Dialog -> kohaerent mit dem draft-then-Save-Modell.

Wirkt OHNE Neustart: DebridService.unrestrictLink liest this.settings live
(setSettings propagiert die Liste), unrestrictWithAccounts ueberspringt deaktivierte
Accounts (gleicher Mechanismus wie Daily-Limit/Cooldown-Skip).

Test: "skips a manually disabled Mega-Debrid account" — acc1 disabled -> acc2 loest
auf (beweist den ID-Seam getMegaDebridAccountId). 643 Tests gruen, tsc 9, Build sauber.
GUI-Toggle compile-/build-verifiziert, im laufenden Electron noch nicht click-getestet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 13:08:09 +02:00
Sucukdeluxe
3977184fd4 Account-Rotation: Login/Premium-Badges + Live-Rotations-Panel + "Alle pruefen"
- Pro Mega-Debrid-Account UND Debrid-Link-Key im Bearbeiten-Dialog: Badge mit
  Login-Gueltigkeit + Premium-Restlaufzeit (connectUser vip_end / account/infos premiumLeft)
- "Alle pruefen"-Button oben rechts; prueft alle Accounts (Concurrency-Cap 4),
  Ergebnis persistiert (debridAccountStatuses), ueberlebt Neustart
- Rotations-Verlauf-Panel: zeigt live welcher Account/Key versucht wurde + warum
  gewechselt (Ring-Buffer -> Snapshot -> UI), statt nur "Link-Umwandlung erneut"
- Bug A: Mega-Debrid Per-Account-Verbrauch wurde nie erfasst (Heute/Insgesamt immer 0)
- Bug B: isProviderConfigured erkannte reine megaCredentials-Multi-Config nicht
- Neu: account-check.ts (standalone), CHECK_DEBRID_ACCOUNTS IPC, 13 Tests

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 21:19:23 +02:00
Sucukdeluxe
96bcbd13d7 Ember-Theme: warmer Amber-Akzent auf kühlem Navy
Redesign-Entscheid des Users (siehe design-mockups/): Aurora-Flavor "Ember".
Re-Skin der Dark+Light-Theme-Variablen + hartcodierte Cyan-Stellen:

- --accent Cyan #38bdf8 -> Amber #f2942d, neue --accent-2 Koral #ff7a5c
- Surfaces/Text/Muted leicht ins Warme verschoben (Warm-Kalt-Spannung:
  Amber-Signal auf kühlem Navy bleibt erhalten)
- Download-Progress Cyan-Gradient -> Amber->Koral (3 Stellen)
- Accent-Button + Border -> Amber
- Speed-Chart (App.tsx Canvas) Akzent -> Amber
- Grün (Entpacken/Online/Erfolg) bleibt semantisch unverändert

Bewusst KEINE Glas-/Glow-/Gradient-Mesh-Effekte (User lehnt KI-Look ab) —
nur die warme Farbwelt auf der bestehenden flachen Struktur.

design-mockups/: 4 Erst-Richtungen + Aurora-Flavor-Switcher + Forge (Referenz).
tasks/todo.md: Bug-/Feature-Analyse (3 parallele Subagents).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 16:17:47 +02:00
Sucukdeluxe
4d1f3c3fdc Performance: hash-based IPC state diffing (the big one)
Implements per-item / per-package hash-based diffing for the IPC state-update
channel. This is the architecturally biggest performance win — for queues
with thousands of items where most are idle between emits, this can cut
IPC payload size by 80-95%.

How it works:
1. New `getSnapshotForEmit()` method computes a compact hash per item and
   per package covering the visible/mutable fields. On each emit it includes
   only items/packages whose hash changed since the last emit, plus a list
   of removed IDs. Every 30 seconds a full resync is sent for safety.

2. A new `payloadKind: "full" | "delta"` field on UiSnapshot signals the
   format. `removedItemIds` and `removedPackageIds` lists carry deletions.

3. The renderer maintains a `masterSnapshotRef` and merges incoming deltas:
   spreads new items over master items, deletes the removed-IDs, then sets
   the merged snapshot as React state. Full payloads replace the master
   entirely (initial sync + 30s resync).

4. The existing direct `getSnapshot()` API used by app-controller, debug-server,
   and link-export is unchanged — they still get a full snapshot. Only the
   "state" emit channel uses delta encoding.

Trade-offs accepted:
- Hash computation cost: ~13 string concats per item per emit. With 5000
  items at 700ms intervals that's ~7100 hash ops/sec — well under 1ms total.
- The 30s full resync ensures any drift bug self-heals within 30s without
  user-visible glitch.
- Server keeps two extra Maps (item/package hash tracking).

Items / packages that are completely idle between emits add ZERO bytes to
the IPC payload now, instead of ~450 bytes per item. For a normal queue of
5000 items where ~30 are actively downloading, payload drops from ~3.6 MB
to ~30 KB per emit — a 100x reduction.

Tests: 140/140 download-manager + 133/133 storage+auto-rename green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 14:10:48 +02:00
Sucukdeluxe
d71dd3af0b Performance: visiblePackages dep fix + ItemRow date memo + small Object.keys cuts
Five more low-risk hot-path optimizations:

1. visiblePackages no longer re-runs the sort callback on every item update.
   The sort is only meaningful when running && autoSort && >1 packages, so we
   pass null as items dep otherwise. Previously fired the full O(N) sort
   pass on every progress tick even when it would have returned the input
   array unchanged.

2. ItemRow memoizes formattedCreatedAt + displayStatus + statusTitle so a
   row that re-renders because of progress/speed changes no longer pays for
   formatDateTime() and computeDisplayedItemStatus() twice (title+body).

3. resetSessionTotalsIfQueueEmpty: removed redundant Object.keys() check.
   itemCount + packageOrder.length cover the same condition without
   allocating two intermediate arrays.

4. markQueuedAsReconnectWait: replaced Object.keys() array allocation with
   for-in iteration when runItemIds is empty. Saves a 5000-element string
   array allocation every 900ms during reconnect.

5. columnOrderJson useEffect dep: replaced JSON.stringify with cached
   join() + useMemo. Stringifying a 7-element settings array on every
   render was ~2-3ms per render for nothing.

All 140 download-manager tests green. Renderer + main both build clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 13:46:57 +02:00
Sucukdeluxe
3c9894c7b0 Performance: ItemRow extraction + scheduler single-pass + selectedIds memo fix
Major optimizations to reduce UI lag with large queues (5000+ items):

1. ItemRow extracted to its own memoized component (renderer)
   Previously every package re-render mapped all its items inline,
   producing N×M re-renders per state update. Now each item-row only
   re-renders when ITS specific data changes, with custom equality on
   the visible fields (status, progress, speed, fullStatus, etc.).
   Also adds stable useCallback handlers per item.

2. PackageCard stats consolidated into single useMemo (renderer)
   Replaces 5 separate filter()/some() + 2 reduce() calls (O(7N)) with
   one O(N) pass collecting all aggregates (done/failed/cancelled/
   extracted/extracting/activeProgress/extractingProgress).

3. selectedIds memo comparator fixed (renderer)
   Custom equality now checks if selection state changed for items in
   THIS package only. Previously any selection anywhere broke memo on
   all 200+ visible PackageCards.

4. Scheduler single-pass queue presence (main)
   New getQueuePresence() returns hasImmediate + hasDelayed in one
   iteration. Replaces hasQueuedItems() + hasDelayedQueuedItems() that
   each scanned packages independently. Saves one full O(n) iteration
   per scheduler tick.

No functional changes. All 565 tests green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 13:07:42 +02:00
Sucukdeluxe
bece2f3e85 Performance: prune long-lived caches, hoist regexes, idle chart redraws
Three low-risk optimizations that reduce CPU/memory footprint without
changing user-visible behavior:

1. Periodic cleanup of unbounded module-level Maps (24/7 stability):
   - debridLinkKeyCooldowns, debridLinkKeyCooldownDetails,
     debridLinkKeyRuntimeStatuses (debrid.ts)
   - megaDebridAccountCooldowns (debrid.ts)
   - allDebridHostInfoCache (download-manager.ts)
   - All pruned every 10 min via existing resetStaleRetryState() with a
     1h grace window for debugging
   - Without this, modules accumulated entries indefinitely over days
     of continuous server operation

2. Hoist regex literals in resolveArchiveItemsFromList() to module scope.
   Avoids 5 RegExp constructions per call. The function is called per
   archive set during extraction discovery — adds up on packages with
   many archives.

3. BandwidthChart: skip the 250ms redraw interval while the session is
   stopped or paused. The chart renders once on state change to show the
   latest history, then sleeps until downloads resume. Saves 4 canvas
   redraws per second when idle (renderer CPU).

No functional changes. All 565 tests green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-19 12:32:38 +02:00
Sucukdeluxe
38179881f5 Fix Debrid-Link key rotation cascade failure, case-sensitive rename, and sample filter
- notDebrid (host-level) no longer burns all keys: stops rotation immediately
  with 5min cooldown instead of cycling through all 9 keys pointlessly
- Remove double provider-blockade: debrid_link_cooldown no longer stacks
  recordProviderFailure + applyProviderBusyBackoff on top of key cooldowns
- Detect timeout cascades: 2+ consecutive transport failures trigger 3min
  cooldown instead of burning remaining keys
- Case-sensitive rename: files with different casing (e.g. lowercase scene
  names) now get properly renamed instead of being skipped as "already matching"
- Extended sample filter: detect -s.mkv suffix and \Sample\ subdirectories
  in auto-rename (already worked in MKV-move)
- Add key status display with state pills in Debrid-Link key stats popup
- Add parseDebridLinkTerminalFailure for fast-fail on exhausted keys

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 13:04:42 +01:00
Sucukdeluxe
65650737b1 Refactor Mega-Debrid account UI from textarea to proper account list
Replace the raw login:password textarea with a proper form-based UI:
- Individual Login + Password input fields with "Hinzufügen" button
- List of configured accounts with masked logins and "Entfernen" button
- Duplicate login detection
- Storage format unchanged (megaCredentials stays login:password pairs)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:35:17 +01:00
Sucukdeluxe
6df0834b67 Add Mega-Debrid multi-account support with automatic fallback
Multiple Mega-Debrid accounts can now be configured as login:password
pairs (one per line). When an account hits Fair-Use limits or errors,
the next account is tried automatically.

- New parser module mega-debrid-accounts.ts (parse, ID generation,
  masking, serialization)
- Per-account daily limits, usage tracking, enable/disable
- Account rotation with per-mode cooldowns (API failures don't
  block Web attempts)
- Backward compatible: existing single megaLogin/megaPassword
  is auto-migrated to the new format
- UI: textarea for credentials, account list with masked logins

Follows the existing Debrid-Link multi-key pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:12:51 +01:00
Sucukdeluxe
17e947fc6b Harden type safety and recovery guards 2026-03-10 05:54:19 +01:00
Sucukdeluxe
6d7b3686dc Add AVI video-library support and startup recovery fixes 2026-03-10 00:43:51 +01:00
Sucukdeluxe
51d4e2100f Rename backup menu actions 2026-03-09 18:16:30 +01:00
Sucukdeluxe
05df79d518 Refine statistics overview layout 2026-03-09 05:53:05 +01:00
Sucukdeluxe
40f097249c Fix manual extract relabeling 2026-03-09 05:38:56 +01:00
Sucukdeluxe
3de4ba3e90 Fix final post-process requeue stall 2026-03-09 05:33:09 +01:00
Sucukdeluxe
1afce943ae Fix history timing and retention controls 2026-03-09 05:16:41 +01:00
Sucukdeluxe
1f9a26e4b0 Add app runtime statistics 2026-03-09 04:59:00 +01:00
Sucukdeluxe
55e0ebd0f8 Add dedicated rename support logging 2026-03-09 04:48:58 +01:00
Sucukdeluxe
2066d0ad26 Keep manually collapsed packages closed 2026-03-09 04:30:08 +01:00
Sucukdeluxe
85a9a2fa9f Add package and item link export 2026-03-09 04:11:18 +01:00
Sucukdeluxe
7027e11cbd Add support self-check diagnostics 2026-03-09 03:00:36 +01:00
Sucukdeluxe
fc4fafa0d6 Harden support logging and debug setup 2026-03-09 02:47:49 +01:00
Sucukdeluxe
f5f7f14104 Add support bundle and trace tooling 2026-03-09 02:15:32 +01:00
Sucukdeluxe
56ce7c2aea Add remote host and item diagnostics 2026-03-09 01:21:11 +01:00