Harden audit findings: correctness, type-safety, Windows conventions & polish

Audit-pass over CODE-AUDIT.md (~48 items closed this pass; all verified —
typecheck + 234 tests + eslint + prettier green).

Correctness / bugs:
- B3: match the release checksum to the asset's filename line (no wrong-hash verify)
- B4: newline-safe metadata probe (one --print with a unit-separator delimiter)
- B5 / L88: guard the meta event against canceled items; progress no longer promotes
  a queued item outside pump()
- B7: cookie-login promise always resolves (handles destroy-without-close)
- L146: trim parser rejects >2 colon-group times; M36: Library selection counts only
  actionable rows
- L11 / L50 / L156 / L57 / L159 / L15 / L3: live queue count, empty-cookie message,
  schedule picker min, dead-code/comment cleanup

Type safety:
- Enable noUncheckedIndexedAccess + noFallthroughCasesInSwitch (15 real edge cases fixed)

Resilience / Windows / metadata:
- R5: settings write failure handled (no unhandled IPC rejection; reconciles to truth)
- W1 / W5 / W6: min window size, seeded folder picker, parented sign-in window;
  L147 dead macOS branches removed
- CL1: shared stdout markers; package/builder metadata (license, homepage, repository,
  copyright, tsbuildinfo glob)

Copy / docs / tests:
- M37 / SR9 dev-jargon cleanup in hints; M8 / M25 / M26 / L66 / L80 / L81 reconciled
- New unit tests for L35 (isValidMediaItem) and L36 (compareVersions)

This commit also checkpoints the previously-uncommitted feat/tray-background-clipboard
work it builds on: background running + auto-download, library clipboard detection,
tray, binary management & library scale, credential encryption at rest, the shared
jsonStore and ui/ primitives, and the eslint/prettier tooling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 13:02:54 -04:00
parent a6a8c5f578
commit 1376c2dee8
82 changed files with 4571 additions and 1276 deletions
+30 -2
View File
@@ -20,7 +20,6 @@ export const IpcChannels = {
downloadStart: 'download:start',
downloadCancel: 'download:cancel',
downloadPause: 'download:pause',
defaultFolder: 'download:default-folder',
chooseFolder: 'download:choose-folder',
openPath: 'shell:open-path',
showInFolder: 'shell:show-in-folder',
@@ -52,6 +51,9 @@ export const IpcChannels = {
/** main → renderer push channel for OS theme/contrast changes (nativeTheme 'updated') */
systemThemeUpdate: 'system-theme:update',
openHighContrastSettings: 'shell:open-high-contrast-settings',
/** preload → main: the contextBridge failed to expose the API; main shows a
* hard error instead of letting the renderer silently fall back to mock mode (M30) */
preloadBridgeFailure: 'preload:bridge-failure',
/** main → renderer push channel: a URL handed to AeroFetch from outside the app
* (the aerofetch:// protocol, or a .url file via Explorer's "Send to" menu) */
externalUrl: 'external-url',
@@ -78,7 +80,9 @@ export const IpcChannels = {
/** main → renderer push channel for live terminal output lines */
terminalOutput: 'terminal:output',
/** renderer → main: reflect overall queue progress on the Windows taskbar (Phase O) */
taskbarProgress: 'taskbar:progress'
taskbarProgress: 'taskbar:progress',
/** renderer → main: open a YouTube WebView and extract a PO token (Phase P) */
youtubePoTokenMint: 'youtube:po-token-mint'
} as const
/** Sentinel format id meaning "let yt-dlp pick the best video+audio". */
@@ -118,6 +122,14 @@ export type CookieBrowser = (typeof COOKIE_BROWSERS)[number]
export const ACCENT_COLORS = ['rose', 'coral', 'amber', 'teal'] as const
export type AccentColor = (typeof ACCENT_COLORS)[number]
/** Quality/format labels for the video download selector. */
export const VIDEO_QUALITY_OPTIONS = ['Best available', '1080p', '720p', '480p', '360p'] as const
export type VideoQuality = (typeof VIDEO_QUALITY_OPTIONS)[number]
/** Quality/format labels for the audio download selector. */
export const AUDIO_QUALITY_OPTIONS = ['Best (MP3)', '320 kbps', '192 kbps', '128 kbps'] as const
export type AudioQuality = (typeof AUDIO_QUALITY_OPTIONS)[number]
/** UI color theme: an explicit mode, or 'system' to follow the OS preference. */
export type ThemeMode = 'light' | 'dark' | 'system'
@@ -177,6 +189,12 @@ export interface DownloadOptions {
splitChapters: boolean
/** embed metadata (title/artist/etc.) */
embedMetadata: boolean
/** override the title tag before embedding; blank = keep the extracted value */
metadataTitle?: string
/** override the artist tag before embedding (audio downloads) */
metadataArtist?: string
/** override the album tag before embedding (audio downloads) */
metadataAlbum?: string
/** embed the thumbnail (cover art for audio, poster for mp4/mkv video) */
embedThumbnail: boolean
/** crop embedded audio artwork to a centred square (Seal's "crop artwork") */
@@ -452,6 +470,14 @@ export interface DownloadProgress {
eta?: string
/** human-readable total size, e.g. '512 MB' */
sizeLabel?: string
/** true when yt-dlp reports no total/estimated size (livestreams, some sites),
* so `progress` stays 0 the whole time — the bar should go indeterminate
* instead of reading a frozen 0% (L137) */
sizeUnknown?: boolean
/** latched true once the first download stream has finished, so the remaining
* stream/merge/post-processing shows as an indeterminate "Finishing…" state
* rather than a second 0→100% fill of the bar (SR7) */
finishing?: boolean
}
/** Discriminated union pushed on IpcChannels.downloadEvent. */
@@ -740,4 +766,6 @@ export interface TaskbarProgress {
fraction: number
/** taskbar bar mode: hidden, normal, or red (some failed) */
mode: 'none' | 'normal' | 'error'
/** active download count for the overlay badge; absent or 0 = clear badge */
badgeCount?: number
}