feat(roadmap): surface stale checkboxes + collection output-path setting

Command preview + incognito toggle were already wired end-to-end in the
DownloadBar (Show command button, Incognito checkbox) — flipped the two
stale ROADMAP.md checkboxes with notes; verified live in the preview.

Output-path setting (PINCHFLAT): new Settings.collectionOutputTemplate — a
raw yt-dlp -o template overriding the default Channel/Playlist/NNN-Title
layout for Library downloads (empty = default). collectionOutputTemplate()
takes an optional custom template (joined under outDir, left for yt-dlp to
expand); download.ts passes the setting; zod schema validates it as a safe
relative template; Settings -> Filenames field. Tests in buildArgs +
settingsSchema; live-verified the field renders.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-02 15:44:44 -04:00
parent 72feaa62f8
commit 42b7b2e01f
8 changed files with 98 additions and 16 deletions
+15 -12
View File
@@ -127,12 +127,13 @@ extraArgs ordering). **Smoke-tested ✅ (2026-06-23):** `parseExtraArgs('--write
the Custom commands card). The **"run custom command" mode** is
`Settings.customCommandEnabled`, applied to every new download unless overridden
per-download in the download bar's Custom command panel.
- [ ] **Command preview (plumbed, not surfaced).** `IpcChannels.commandPreview`
`previewCommand()` (`src/main/download.ts`) builds the exact argv via the same
`buildCommand()` path a real download would take, then renders it with
`formatCommandLine`. The **Preview command** button is NOT yet in the download bar —
only the main/preload/buildArgs chain exists. Wire it into the per-download Options
panel or remove the chain (audit M5/UX1).
- [x] **Command preview (surfaced).** `IpcChannels.commandPreview` `previewCommand()`
(`src/main/download.ts`) builds the exact argv via the same `buildCommand()` path a real
download would take, then renders it with `formatCommandLine`. **Now surfaced:** the
DownloadBar's **"Show command"** toggle (`useDownloadBar.toggleCommandPreview`
`window.api.previewCommand(...)`) renders the exact argv in an inline panel that reflects the
current URL/format/options/trim/schedule. (Checkbox was stale — the button has shipped;
re-verified in the browser preview: setting a URL + "Show command" renders the argv panel.)
- [x] **In-app yt-dlp updater.** `updateYtdlp(channel)` (`src/main/ytdlp.ts`) runs
yt-dlp's own `--update-to stable|nightly`. Surfaced in **Settings → About**, right
next to the existing version check, with a channel picker + result output.
@@ -157,12 +158,14 @@ parallel storage. All items verified in the UI preview (typecheck + `npm run tes
- [x] **Native OS notifications** on completion / failure (Electron `Notification`,
`src/main/download.ts`). Gated by a new **Notify when downloads finish** switch
(`Settings.notifyOnComplete`, default on); clicking a notification refocuses the window.
- [ ] **Private / incognito mode (plumbed, not surfaced).** `DownloadItem.incognito` flows
through `buildItem` → history-skip → the QueueItem "Private" badge, and
`store/downloads.ts` checks it before ever calling `useHistory().add(...)`. But no UI
control sets `incognito: true` yet — the download-bar toggle is not wired (audit M6/UX1).
Note `download.ts` would still log a failure / show a completion title for a private item,
so the "private" promise currently covers history only (audit L136).
- [x] **Private / incognito mode (surfaced).** `DownloadItem.incognito` flows through `buildItem`
→ history-skip → the QueueItem "Private" badge, and `store/downloads.ts` checks it before
ever calling `useHistory().add(...)`. **Now surfaced:** the DownloadBar's Advanced options
panel carries an **"Incognito mode (no logging, no history, no cookies)"** checkbox
(`useDownloadBar.setIncognito`), one-shot per download. The main-process promise is also
complete — L136 (Batch 8) threaded `incognito` through `StartDownloadOptions` so main skips
the errorlog write, drops the notification detail, and withholds cookies for a private
download, not just the renderer's history skip.
- [x] **Backup / restore** settings + templates (export / import JSON). New
`src/main/backup.ts` writes/reads `{ settings, templates }` via a save/open dialog;
`replaceTemplates()` (`src/main/templates.ts`) does a full restore rather than a