Commit Graph

117 Commits

Author SHA1 Message Date
xRangerDE
8d0cb4cefd harden: atomic fsync writes + per-item filename claims
Two server-side correctness fixes for parallel downloads and crash recovery.

1. Atomic file writes survive power loss / crash mid-write.
   saveConfig and writeQueueToDisk used writeFileSync + renameSync. Node's
   writeFileSync does NOT fsync — a power loss between write and rename can
   leave the renamed file empty or truncated, and the next launch silently
   falls back to defaults / empty queue.
   New writeFileAtomicSync helper: openSync + writeSync + fsyncSync +
   closeSync + renameSync (with the existing Windows copy fallback). fsync
   failure is non-fatal (some FS reject it) but file ordering is preserved.

2. Per-item claimed filenames fix the parallel-download race.
   With max 2 parallel downloads, processOneQueueItem.finally was calling
   claimedFilenames.clear() — wiping every parallel item's claims when any
   one finished. In the window between an active item claiming a filename
   and streamlink actually writing the first bytes, a third item could
   compute the same filename and both downloads would race the same path.
   New Map<itemId, Set<filename>> tracks claims per active download.
   ensureUniqueFilename(path, itemId) registers per-item;
   releaseClaimedFilenamesForItem(itemId) removes only that item's claims.
   splitMergedFile gained an itemId parameter for the same reason. The
   dead releaseClaimedFilename(path) function was removed.

Build: tsc clean. Tests: smoke + smoke-template-guide + smoke-full + merge-split
+ update-version-logic all pass. No new ESLint warnings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 15:10:15 +02:00
xRangerDE
54197af863 release: 4.5.7 fix notification app name
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 04:20:21 +02:00
xRangerDE
37d75fac24 fix: Windows notification shows 'Twitch VOD Manager' instead of 'electron.app.Electron'
Set app.setAppUserModelId('com.twitch.vodmanager') on startup so Windows
notifications display the correct app name.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 04:18:34 +02:00
xRangerDE
f9a0fdcf3d release: 4.5.6 guard formatDuration against NaN/Infinity
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 15:27:52 +01:00
xRangerDE
da1d14d458 fix: guard formatDuration against NaN/Infinity input
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 15:23:21 +01:00
xRangerDE
18940d0640 chore: add ESLint with security plugin, fix code quality warnings
- Install eslint, typescript-eslint, eslint-plugin-security
- Add eslint.config.mjs with project-tuned rules
- Fix redundant catch assignment in cutVideo
- Fix let→const for promise dedup patterns
- No security bugs found — all regex warnings are false positives (anchored patterns)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 14:55:35 +01:00
xRangerDE
d9bdf744fd release: 4.5.5 fix ETA showing video duration instead of actual remaining time
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:54:44 +01:00
xRangerDE
d8f0836165 fix: ETA calculation was using video duration instead of download progress
The old formula (avgSpeed * expectedDurationSeconds) simplified to just
(videoDuration - elapsedTime), showing 59min ETA for a 60min part after
1min of downloading. Now uses streamlink's actual progress percentage:
ETA = (elapsed / percent) * (100 - percent), which reflects real download
speed rather than video length.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:47:19 +01:00
xRangerDE
a07ec1f958 release: 4.5.4 hardening — clip validation, cutter check, pagination guard, atomic writes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:39:55 +01:00
xRangerDE
5f2e85e455 fix: clip time validation, cutter 0-byte check, pagination guard, atomic config write
H1: Add NaN/negative/zero-duration validation to clip dialog before IPC call
H2: Reject cut video output <= 256 bytes as effectively empty
H3: Add paginated VOD fetching with MAX_VOD_PAGES=50 safety guard
H4: Atomic write (tmp+rename) for config and queue persistence

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:33:31 +01:00
xRangerDE
39fa5065d2 release: 4.5.3 bugfixes — selector overflow, drag safety, filename claims, details persist, progress stability
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:20:11 +01:00
xRangerDE
2b379e5e6a fix: correct dragstart cancel method and release claimed filenames after download
- Use dataTransfer.effectAllowed='none' instead of preventDefault() for dragstart
  (preventDefault does not cancel dragstart events per HTML spec)
- Clear claimedFilenames Set in processOneQueueItem finally block to prevent
  stale claims from blocking re-downloads of same VODs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:19:30 +01:00
xRangerDE
cf9d7b8334 fix: selector overflow for 10+ items, drag-drop status guard, filename claim set for parallel safety
- Queue selector uses min-width instead of fixed width for double-digit numbers
- Drag-start handler validates item is still pending before allowing drag
- ensureUniqueFilename uses in-memory claim set to prevent TOCTOU race

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:15:25 +01:00
xRangerDE
6c47c63fa8 fix: clamp ETA bounds, store stats interval, add activeDownloads finally-cleanup, prevent progress backward jump
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:04:59 +01:00
xRangerDE
4607ba9cc6 fix: persist expanded details across re-renders, guard drag-drop init against duplicates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:03:20 +01:00
xRangerDE
1e81b889f9 release: 4.5.2 compact queue buttons
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:30:50 +01:00
xRangerDE
00d35f1b1c fix(ui): reduce queue action button height for compact layout
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:10:02 +01:00
xRangerDE
8132e062fa release: 4.5.1 fix numbered selector visual update
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:07:51 +01:00
xRangerDE
0133569104 fix: include selection state in queue render fingerprint so numbered selectors update visually
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:06:42 +01:00
xRangerDE
6b97039471 release: 4.5.0 ETA, shortcuts, stats, drag&drop, expandable items, light theme, parallel downloads, code split
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:02:32 +01:00
xRangerDE
66afaba0ea refactor: extract tool discovery functions to src/tools.ts
Move streamlink/ffmpeg path discovery, bundled tool management,
auto-install logic, and related caches (~430 lines) into a
dedicated tools module. main.ts uses dependency injection for
debug logging and directory paths to keep the module decoupled.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 10:00:51 +01:00
xRangerDE
54d04d4f73 feat: support parallel downloads (up to 2 simultaneous)
Add parallel_downloads config option (1 or 2) with Settings UI dropdown.
Refactor processQueue to run concurrent download slots using Promise.race,
extracting per-item logic into processOneQueueItem. Add per-item process
tracking via activeDownloads Map and cancelledItemIds Set so cancel/pause
correctly terminates all active downloads.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:54:20 +01:00
xRangerDE
63aafae85d feat: add light theme with toggle in settings
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:46:26 +01:00
xRangerDE
424b312551 refactor: extract shared interfaces to src/types.ts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:44:37 +01:00
xRangerDE
fbcf3935d0 feat: add drag & drop queue reordering and expandable queue item details
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:42:35 +01:00
xRangerDE
2481230983 feat: add keyboard shortcuts (Del/S) and download statistics bar
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:40:39 +01:00
xRangerDE
c96fd13aff feat: add ETA calculation for download progress display
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:39:27 +01:00
xRangerDE
6a32387add release: 4.4.0 performance optimizations, collision detection, notifications
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:28:42 +01:00
xRangerDE
3537d28eb2 test: add filename collision detection unit tests
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:28:06 +01:00
xRangerDE
a4ca410641 feat: filename collision detection, queue JSON validation, download-complete notification
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:27:19 +01:00
xRangerDE
76ecbc652d perf: parallel init with Promise.all, targeted DOM updates for download progress
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:26:19 +01:00
xRangerDE
b7499c87a3 release: 4.3.4 fix queue buttons overflow
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:06:52 +01:00
xRangerDE
00cf7781d3 fix(ui): prevent queue buttons from being pushed off-screen by long queue
Queue section now uses flex layout with flex-shrink:0 on action buttons,
so they stay visible regardless of queue list length.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 09:06:10 +01:00
xRangerDE
46dc29a226 release: 4.3.3 numbered merge selection, user-defined order
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 08:57:26 +01:00
xRangerDE
0e6b219455 feat(merge-split): numbered selection instead of checkboxes, user-defined merge order
Replace checkboxes with numbered selectors (1, 2, 3...) that show the
merge order. Click order determines VOD sequence in the merged result.
Chronological auto-sort removed — user controls the order.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 08:55:35 +01:00
xRangerDE
674041a603 release: 4.3.2 bugfix — config flush on quit, processQueue concurrency guard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 08:47:15 +01:00
xRangerDE
86c80acf28 fix: flush config on quit, verify temp cleanup, add missing spawn error handlers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 19:42:35 +01:00
xRangerDE
33730fd372 fix: guard processQueue against concurrent invocations, fix stale process kill reference
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 19:41:11 +01:00
xRangerDE
3af159f8e7 release: 4.3.0 add VOD merge+split feature
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 18:23:40 +01:00
xRangerDE
6c082a87ab fix(merge-split): fix premature 100% progress, add ffmpeg preflight, clean partial splits, use locale metaLabel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 18:12:50 +01:00
xRangerDE
30c94b550e test(merge-split): add unit tests for merge-split logic
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:57:21 +01:00
xRangerDE
ad4e540952 feat(merge-split): add queue checkboxes and merge-group selection UI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:55:33 +01:00
xRangerDE
c1a72ebd66 feat(merge-split): add Merge & Split button and queue checkbox/merge-group styles
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:55:14 +01:00
xRangerDE
409c976df0 feat(merge-split): integrate merge-group pipeline into processQueue and cleanup handlers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:53:55 +01:00
xRangerDE
8501bd17f7 feat(merge-split): add processDownloadMergeGroup() 4-phase pipeline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:52:41 +01:00
xRangerDE
03f47a7240 feat(merge-split): add splitMergedFile() function using FFmpeg stream-copy
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:49:15 +01:00
xRangerDE
5a20c1c6a4 fix(merge): fix progress formula for long videos, add optional totalDurationSec param, normalize Windows paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:48:02 +01:00
xRangerDE
645d2f147b feat(merge-split): add createMergeGroup IPC handler
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:47:36 +01:00
xRangerDE
4750af2f97 feat(merge-split): add MergeGroup type definitions to all interface locations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:46:20 +01:00
xRangerDE
03c6e68da0 feat(merge-split): add EN and DE localization strings for merge group
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 17:46:20 +01:00