- Always force re-download once when both JVM and legacy extractors fail
(suggestRedownload=true), regardless of valid archive signature
- Add autoRecoveredForRedownload Set for loop protection (one attempt per archive)
- Clear loop protection on package reset (clearHybridArchiveState)
- Previous sibling-items check failed when other episodes were already
cleaned up after hybrid extraction
- Lower mini-download retry threshold from 100KB to 5KB
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Retry extraction with 2.5s delay on CRC/password errors (Windows file handle race)
- Improve auto-recovery: force re-download when known password fails (content corruption)
- Expand auto-recovery to wrong_password category for encrypted RAR5
- Add fsync after download for pre-allocated files
- Fix permanent extraction failure loop for archives with valid headers but corrupt content
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Switch JVM GC from SerialGC to G1GC with MaxGCPauseMillis=50
for shorter pause times in long-lived daemon
- Increase JVM heap from 512m/8g to 1g/32g to reduce GC pressure
on systems with plenty of RAM
- Raise hybrid thread cap from floor(cpuCount/2) capped 8
to ceil(cpuCount*0.75) capped 12 — downloads are I/O-bound
and don't need much CPU headroom
- Refresh daemon process priority before each request so hybrid
extraction gets correct CPU priority even if daemon was started
with a different priority level
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Early-exit now also uses raw Content-Length as fallback when
totalBytes is unknown (provider returned fileSize=0)
- Stall handler checks if file is already complete on disk before
deleting and retrying — prevents re-download loop for files that
finished but server delayed closing the connection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add scheduler generation counter to prevent stale scheduler from
continuing after stop/start cycle
- Guard processItem stop-abort handler: skip status overwrite when a
new start() has already re-activated the session
- Yield in start() after recoverRetryableItems to let pending abort
handlers complete before evaluating item states
- Add test: rapid stop → disable provider → start must resolve
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Files with valid RAR/7z/ZIP signature are not corrupt (wrong password),
only files with invalid signature get force-redownloaded.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Trust extractor CRC verdict over file size checks
- Re-queue incomplete downloads instead of just warning
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
If the primary extractor (7-Zip) fails with wrong_password/checksum
error on a .rar file, automatically try the alternative extractor
(UnRAR/WinRAR) which handles RAR format natively and more reliably.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Items incorrectly marked as "completed" by the old 50% recovery threshold
persist in the session file across updates. On startup, check all completed
items: if the file on disk is smaller than expected totalBytes, reset to
"queued" so it gets re-downloaded. Also reset items whose files are missing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two bugs in findReadyArchiveSets disk-fallback:
1. Failed items were explicitly excluded from the blocking check
(status !== "failed"), so partial downloads with "failed" status
would not block extraction. Now ANY non-completed item blocks.
2. The disk size check was only > 10 KB, allowing 627 MB partial
files of 1001 MB archives to pass. Now requires the file to be
within one allocation unit of the item's expected totalBytes.
Added findItemByDiskPath helper to look up the owning item for a
file on disk and get its expected size.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Item-Recovery incorrectly marked partially downloaded files as "completed"
when the file size was >= 50% of expected size. A 627 MB partial download
of a 1001 MB file (62.7%) would pass the check and trigger hybrid
extraction on incomplete RAR archives.
Fix: require file to be within one allocation unit (4 KB) of the expected
size instead of 50%. Also add a pre-allocation guard: if the file appears
to be at the expected size but downloadedBytes is significantly behind
(< 95%), skip recovery (likely a pre-allocated sparse file from a crash).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Detect items whose targetPath has a " (N)" suffix from the previous
duplicate filename bug and rename them back to the original filename.
This fixes extraction failures for RAR split archives that were
downloaded with (1) suffix before v1.7.19.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace shared currentKeyIndex round-robin with sequential scan from
first key. All parallel items now consistently use the same key (e.g.
Key 3) until it hits a quota/error, then all move to Key 4, etc.
Previously, currentKeyIndex was shared across parallel unrestrict calls,
causing items to scatter across keys (3, 5, 7) even when Key 3 still
had capacity.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After restart, reservedTargetPaths (in-memory) was empty so claimTargetPath
could not distinguish between "file belongs to this item" and "file belongs
to another item". The naive fix (allow overwrite if unclaimed) would have
risked overwriting completed files from other items.
Proper fix: restore reservedTargetPaths from persisted session data on init.
This way each item's targetPath is correctly claimed, and claimTargetPath
can safely reuse the item's own file while protecting other items' files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the app restarts (or updates) while downloads are in progress,
partial files remain on disk but reservedTargetPaths (in-memory) is empty.
claimTargetPath treated the unclaimed-but-existing file as a conflict and
appended (1) to the filename, breaking RAR split archive extraction.
Fix: if a file exists on disk but no other item has reserved the path,
allow overwriting instead of creating a duplicate.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add "notDebrid", "disabledServerHost", "notFree" as immediate-skip errors
(no 3x retry per key, break to next key instantly like quota errors)
- Add per-key cooldown cache (2 min) so parallel items skip recently-failed keys
instead of all starting at the same broken key
- Set cooldown on quota errors too, preventing repeated checks on exhausted keys
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shelve (15+ failures) now mimics manual stop/start behavior:
- Clears item.provider for fresh provider selection on retry
- Resets provider circuit breaker (providerFailures) for the old provider
- Reduces shelve duration from 5 min to 90s since the issue is stale
provider state, not a timing problem (manual restart works instantly)
Also adds comprehensive session-load logging:
- Logs package/item count on every session file read
- Logs errors when session file parsing fails (was silent before)
- Safety net: if primary session is empty but backup has packages,
automatically restores from backup
- Logs shutdown save with package/item counts
- Logs DownloadManager init state and cleanup policy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The inner unrestrict error handler still called recordProviderFailure()
for hosterNotAvailable errors, causing provider-level cooldown escalation
(up to 180s) even though the issue is hoster-side, not provider-side.
This made auto-retry stall while manual reset worked instantly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
hosterNotAvailable was added to isTemporaryUnrestrictError which
triggered aggressive provider-level cooldowns (up to 180s) that
blocked ALL items for the affected provider. Since items kept
failing, the cooldown never expired (15-min reset threshold never
reached), causing retries to effectively stall.
Fix: remove hosterNotAvailable from isTemporaryUnrestrictError.
It still gets normal unrestrict retry with item-level backoff
(5s -> 120s) via isUnrestrictFailure, but without provider-wide
cooldown blocking other items.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move hosterNotAvailable from isPermanentLinkError to
isTemporaryUnrestrictError — hoster being unavailable is usually
transient (overload, maintenance) and should be retried with backoff
instead of immediately failing as "Link ungültig".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backup redesign (JDownloader 2 style):
- AES-256-GCM encrypted .mdd format with fixed app key
- All credentials exported (no more ***-masking), works on any PC
- Includes settings, session AND history in backup
- Backward-compatible: auto-detects legacy JSON backups
- Normalize history entries on import
- Added debridLinkApiKeys, linkSnappy credentials to sensitive keys
Hide extracted items:
- New setting: hide completed/extracted items from package item list
- Items still count in progress stats (done/total), only hidden in UI
- Default: enabled
- Toggle in settings: "Entpackte Items in Paketliste ausblenden"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace plaintext JSON export with encrypted binary format (JDownloader 2 style)
- Fixed app-internal key, works on any machine without password
- Export now includes ALL credentials (no more ***-masking), session AND history
- Add debridLinkApiKeys, linkSnappy credentials to sensitive keys list
- Backward-compatible import: auto-detects legacy JSON backups
- File extension changed from .json to .mdd
- MDD1 magic bytes + random IV + GCM auth tag for integrity
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Archives with absolute internal paths (e.g. scene groups storing full
Windows paths) fail all password attempts in normal mode at ~98%, then
succeed only after the flat-mode fallback kicks in. Previously every
archive in such a package wasted all password cycles before discovering
flat mode was needed again.
Now the first successful flat-mode extraction sets a package-level flag
so subsequent archives skip the normal loop entirely and go straight to
flat-mode extraction, saving ~4x password attempts per archive.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- SCENE_EPISODE_RE/JOINED_RE: use (?!\d) lookahead instead of requiring
separator after episode number, so filenames like s09e06rrp now match
- MKV-Sammelordner: skip 0-byte files from failed/partial extractions
- MKV-Sammelordner: detect same-name same-size duplicates in target dir
and skip instead of creating (2) copies; remove duplicate source file
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Retry failed wrong_password archives serially after parallel extraction
to recover from CRC mismatches caused by concurrent UnRAR I/O contention
- Stop resetting sessionDownloadedBytes on start/resume so the session
total accurately reflects all bytes downloaded since app launch
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multiple accounts from the same provider are now merged:
"Debrid-Link (#3), Debrid-Link (#4)" becomes "Debrid-Link (#3 + #4)"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Daily traffic limits:
- Per-provider daily download limit (configurable in GB per provider)
- Per Debrid-Link API key daily limit (individual limits per key)
- Usage tracking with automatic daily reset at midnight
- Provider is skipped when daily limit reached, falls back to next provider
- Reset button per provider and per Debrid-Link key in account settings
- Hoster routing skips daily-limited providers gracefully
Debrid-Link multi-key improvements:
- Keys now display with labels (#1, #2...) and masked tokens in account list
- Option to show detailed per-key view with individual usage stats
- Keys that hit their daily limit are automatically skipped
- providerAccountId/providerAccountLabel stored per download item
Auto-sort packages by progress:
- Active packages automatically sorted to top during downloads
- Sorted by completion ratio, then downloaded bytes
- Toggle in settings (autoSortPackagesByProgress)
UI polish:
- Package column headers: flatter, more transparent design
- LinkSnappy mode label: "Login" renamed to "Web"
- Account list: new toggle for detailed Debrid-Link key display
- Account usage stats section with warning styling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All ? placeholders in App.tsx replaced with correct UTF-8 umlauts
(ä, ö, ü, ß). File is now properly encoded as UTF-8.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- extractor: detect UnRAR "Cannot create...\..." error (archive with
leading-backslash internal paths) and retry in flat mode (-e) which
strips all paths and avoids the invalid double-separator on Windows
- types/download-manager: add providerLabel field to DownloadItem,
store full label (e.g. "Debrid-Link #1") set at unrestrict time
- App: display providerLabel in Service column (falls back to generic
provider name if label not yet set)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sanitizeFilename() is now applied before constructing outputDir and
extractDir, so names like "TMSF/4SF" no longer produce broken Windows paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a pending item has neither targetPath nor fileName (e.g. after a
reset before re-unrestrict), it is invisible to pendingItemStatus and
the disk-fallback could incorrectly start extraction with a partial file.
Add a guard that skips disk-fallback for any archive set if the package
contains such an untracked pending item.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Clear item.provider on stop/restart so provider order/routing changes
are respected on next download attempt
- Reset item.provider for all non-completed items when providerOrder or
hosterRouting changes in settings
- Cancel scheduled-start timer when queue is started manually
- Track disk-fallback hybrid-extract archives per session to prevent
infinite post-processing loop
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace fixed primary/secondary/tertiary slots with unlimited ordered
providerOrder: DebridProvider[] list; supports as many accounts as needed
- Provider list reorderable via up/down buttons in Accounts settings tab
- Migration: derives order from legacy primary/secondary/tertiary if empty
- Mega-Debrid split into megadebrid-api and megadebrid-web as separate providers
- Add per-hoster routing (hosterRouting) to assign specific debrid provider per hoster
- Fix duplicate MKV files in library: filter out sample files from Sample subfolders
- Remove legacy provider-selection dropdowns from hidden settings section
- Add CSS for provider-order-list/row/num/label/actions classes
- Update debrid tests: add providerOrder: [] to use legacy fallback path
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MKV library collection now filters out sample files before moving.
Files in "sample"/"samples" directories and files with "sample" in
their name are excluded. This prevents duplicate "(2)" entries in
the library folder caused by samples having the same base name as
the real episodes (just different casing from the archive).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New settings field hosterRouting maps file hosters to specific debrid providers
- 27 known hosters predefined (Rapidgator, Uploaded, Turbobit, Nitroflare, etc.)
- Custom hoster support via prompt dialog
- Routing takes priority over default provider chain
- Falls back to normal chain on error when autoProviderFallback is enabled
- Logs routing decisions: "Hoster-Zuordnung: rapidgator → Debrid-Link"
- Full UI section in settings with add/remove/change provider per hoster
- Storage validation and normalization for hosterRouting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add LinkSnappy provider with cookie-based session auth and /api/linkgen
- Upgrade LinkSnappy download URLs from http to https (fix 425 errors)
- Add account deactivation toggle (disabledProviders in settings)
- Show account type (API/Web/Login) in provider dropdowns
- Show API key count for Debrid-Link in status label
- Fix all missing German umlauts throughout the UI
- Wider modal for textarea, compact action buttons in one row
- Debrid-Link: log which API key (#1/#2) is used for unrestrict
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New DebridLinkClient with automatic API key rotation on quota errors
(maxLink, maxLinkHost, maxData, maxDataHost, maxAttempts, maxTransfer)
- Multi-account support: comma or newline-separated API keys
- Full UI integration: account settings, provider dropdowns, summary display
- Safe fallback for undefined debridLinkApiKeys on settings upgrade
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace BrowserWindow-based login flow with Netscape cookie file import
for BestDebrid authentication. Cloudflare Turnstile captcha cannot be
solved in Electron's embedded browser, so users export cookies from
their real browser and import them here.
- Rewrite bestdebrid-web.ts: remove BrowserWindow/CDP code, add
parseNetscapeCookieFile() and importCookiesFromFile()
- Add file picker dialog for .txt cookie files in main IPC handler
- Update IPC channel from OPEN_BESTDEBRID_LOGIN to IMPORT_BESTDEBRID_COOKIES
- Update preload bridge and renderer UI with cookie import button
- Fix pLabel scope in downloadToFile (pass as parameter from processItem)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Detaching the debugger before loadURL removed the registered
anti-fingerprint scripts, causing blank pages. Now keep the
debugger attached through page load and detach on window close.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use Chrome DevTools Protocol to inject scripts before page load that:
- Set navigator.webdriver to false
- Add fake navigator.plugins
- Set navigator.languages to realistic values
- Add window.chrome runtime stub
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cloudflare Turnstile blocks Electron's default user agent. Set a
Chrome user agent on both the session and webContents level so the
login captcha passes correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass cdn: 0 to 1Fichier get_token API to force direct server
downloads instead of CDN, avoiding unnecessary CDN credit usage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The running download status (e.g. "Download läuft", "Warte auf
Festplatte") now shows the full provider label including the source
mode, e.g. "Mega-Debrid (API)" instead of just "Mega-Debrid".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Real-Debrid, AllDebrid, and Mega-Debrid now show their active
mode in logs and UI (e.g. "Real-Debrid (API)" or "Real-Debrid (Web)").
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multiple parallel downloads calling connectUser simultaneously caused
token invalidation races. Only one connectUser request now runs at a
time; all parallel callers share the same result.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Mega-Debrid API support (connectUser + getLink endpoints)
- API mode preferred by default, with automatic web fallback on failure
- User toggle "Mega-Debrid bevorzugt über API" in settings UI
- Provider labels now show source: "Mega-Debrid (API)" or "Mega-Debrid (Web)"
- sourceLabel propagated through all provider result paths
- API session token cached for 20 minutes with auto-invalidation
- Remove megaWebUnrestrict requirement for Mega-Debrid provider config
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When hybrid extraction handled all archives, extractedCount stayed 0
causing all cleanup steps (archive deletion, resume state, link/sample
removal, empty dir pruning, auto-rename, nested extraction) to be
bypassed. Extended conditions to also trigger on alreadyMarkedExtracted.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace extractSlow() per-item extraction with IInArchive.extract() bulk API
in 7-Zip-JBinding. Solid RAR archives no longer re-decode from the beginning
for each item, bringing extraction speed close to native WinRAR/7z.exe (~375 MB/s
instead of ~43 MB/s).
- Add BulkExtractCallback implementing both IArchiveExtractCallback and
ICryptoGetTextPassword for proper password handling during bulk extraction.
- Fix resolveArchiveItemsFromList with multi-level fallback matching:
1. Pattern match (multipart RAR, split ZIP/7z, generic splits)
2. Exact filename match (case-insensitive)
3. Stem-based fuzzy match (handles debrid service filename modifications)
4. Single-item archive fallback
- Simplify caching from Set+Array workaround back to simple Map<string, T>
(the original "caching failure" was caused by resolveArchiveItemsFromList
returning empty arrays, not by Map/Set/Object data structure bugs).
- Add comprehensive tests for archive item resolution (14 test cases)
and JVM extraction progress callbacks (2 test cases).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- JVM extractor now supports --daemon mode: starts once, processes
multiple archives via stdin JSON protocol, eliminating ~5s JVM boot
per archive
- TypeScript side: daemon manager starts JVM once, sends requests via
stdin, falls back to spawning new process if daemon is busy
- Fix extraction progress caching: replaced Object.create(null) + in
operator with Set<string> + linear Array scan — both Map.has() and
the in operator mysteriously failed to find keys that were just set
- Daemon auto-shutdown on app quit via shutdownDaemon() in before-quit
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace Map-based archive item cache with plain Object.create(null)
to work around mysterious Map.has() returning false despite set()
being called with the same key — this caused resolveArchiveItems
to run on every 1.1s pulse instead of being cached, preventing
extraction progress (Entpacken X%) from ever showing in the UI
- Apply same fix to both hybrid and full extraction paths
- Increase JVM heap from 512MB to 1GB for better extraction throughput
- Use SerialGC for faster JVM startup on short-lived extract processes
- Add download lifecycle logging (package add + item download start)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Log when packages are added (count + names)
- Log when individual item downloads start (filename, size, provider)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change OS priority from IDLE/BELOW_NORMAL to NORMAL/BELOW_NORMAL so
extraction runs at full speed (matching manual 7-Zip/WinRAR performance)
- Use "high" priority in both hybrid and full extraction paths
- Increase hybrid extraction threads from hardcoded 2 to dynamic
calculation (half CPU count, min 2, max 8)
- Fix emitState forced emit being silently dropped when a non-forced
timer was already pending — forced emits now always replace pending
timers to ensure immediate UI feedback during extraction transitions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Force immediate emitState when first resolving archive items so UI
transitions from 'Ausstehend' to 'Entpacken X%' instantly
- Use BELOW_NORMAL priority (instead of IDLE) for final extraction
when all downloads are complete — matches manual extraction speed
- Add diagnostic logging for resolveArchiveItems matching
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add "Download fertig: filename (size), pkg=name" log line when an item
finishes downloading, enabling precise timing analysis of when archive
parts become available for extraction.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Run collectMkvFilesToLibrary in background after each hybrid extraction
round so MKVs are moved to the library as episodes are extracted, not
only after the entire package finishes
- Add timing logs to identify bottlenecks:
- Post-process slot wait time
- Per-round duration with requeue status
- Recovery loop duration
- Setup time in handlePackagePostProcessing
- findReadyArchiveSets duration when > 200ms
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After a hybrid extraction round completes, set the requeue flag so the
do-while loop immediately checks for more ready archive sets. Previously,
if all items completed before the task started processing, the single
requeue flag was consumed and no new completions triggered re-extraction,
causing 25+ second gaps until the next download completion.
Also change runHybridExtraction return type from void to number
(extracted count) to enable conditional self-requeue only when archives
were actually extracted, preventing infinite requeue loops.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Release post-process slot immediately after main extraction completes.
All slow post-extraction work (nested extraction, auto-rename, archive
cleanup, link/sample removal, empty directory cleanup, MKV collection)
now runs in background via runDeferredPostExtraction so the next package
can start unpacking without delay.
- Export hasAnyFilesRecursive, removeEmptyDirectoryTree, cleanupArchives
from extractor.ts for use in deferred handler
- Import removeDownloadLinkArtifacts, removeSampleArtifacts from cleanup
- Expand runDeferredPostExtraction with full post-cleanup pipeline:
nested extraction, rename, archive cleanup, link/sample removal,
empty dir tree removal, resume state clearing, MKV collection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Long changelogs made the update dialog unscrollable, preventing users
from reaching the install button. Changelog is now in a collapsed
<details> element. Dialog also has max-height with overflow scroll.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CSS defines .btn.danger (two classes) but code used "btn btn-danger"
(one hyphenated class). History danger buttons now get correct red styling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DDownload was missing from provider validation sets, preventing users
from configuring it as primary or fallback provider in settings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use PackagePriority type instead of string/any in preload and app-controller
- Add .catch() to start(), extractNow(), setPackagePriority(), updateSettings(columnOrder), openLog(), openSessionLog()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix ~70 issues across the entire codebase including security fixes,
error handling improvements, test stabilization, and code quality.
- Fix TLS race condition with reference-counted acquire/release
- Bind debug server to 127.0.0.1 instead of 0.0.0.0
- Add overall timeout to MegaWebFallback
- Stream update installer to disk instead of RAM buffering
- Add path traversal protection in JVM extractor
- Cache DdownloadClient with credential-based invalidation
- Add .catch() to all fire-and-forget IPC calls
- Wrap app startup, clipboard, session-log in try/catch
- Add timeouts to container.ts fetch calls
- Fix variable shadowing, tsconfig path, line endings
- Stabilize tests with proper cleanup and timing tolerance
- Fix installer privileges, scripts, and afterPack null checks
- Delete obsolete _upload_release.mjs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>