docs: add post-parity roadmap (YTDLnis features, native polish, reliability)
Fold Phases L-P into ROADMAP.md: media editing (trim/cut, split-chapters, metadata editing), queue/daily-use UX, power-user surface, Windows-native integration, and reliability/trust. Cross-link from ROADMAP-PINCHFLAT.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,9 @@ Sources: [Pinchflat GitHub](https://github.com/kieraneglin/pinchflat) ·
|
||||
[Pinchflat architecture (DeepWiki)](https://deepwiki.com/kieraneglin/pinchflat) ·
|
||||
[Pinchflat FAQ — indexing](https://github.com/kieraneglin/pinchflat/wiki/Frequently-Asked-Questions).
|
||||
|
||||
> **See also:** [ROADMAP.md](ROADMAP.md) → **Post-parity** — YTDLnis-derived editing features,
|
||||
> Windows-native polish, and reliability work, Phases L onward.
|
||||
|
||||
---
|
||||
|
||||
## Implementation status — Phases F–K shipped (2026-06-23)
|
||||
|
||||
+171
@@ -13,6 +13,9 @@ Sources: [Seal GitHub](https://github.com/JunkFood02/Seal) ·
|
||||
> AeroFetch from a one-shot downloader into a [Pinchflat](https://github.com/kieraneglin/pinchflat)-style
|
||||
> media manager (index entire channels → organize into `Channel / Playlist / Title` folders →
|
||||
> keep in sync), reusing the existing queue/history/options rather than replacing them.
|
||||
>
|
||||
> **Post-parity work** (YTDLnis-derived editing features + Windows-native/UX polish + reliability)
|
||||
> is tracked at the end of this document under **Post-parity** (Phases L onward).
|
||||
|
||||
---
|
||||
|
||||
@@ -234,3 +237,171 @@ Some items are Android-specific in Seal and adapted to Windows here.
|
||||
+ Explorer "Send to" integration (a true Share Target needs an MSIX package, out of scope
|
||||
for this app's NSIS/portable distribution).
|
||||
- F-Droid distribution → N/A (AeroFetch ships NSIS + portable).
|
||||
|
||||
---
|
||||
|
||||
# Post-parity — editing, native polish & reliability
|
||||
|
||||
With both parity tracks complete — Seal (Phases A–E above) and the
|
||||
[Pinchflat media-manager roadmap](ROADMAP-PINCHFLAT.md) (Phases F–K ✅) — this final track
|
||||
collects what's left, from two sources:
|
||||
|
||||
1. A **feature study of [YTDLnis](https://github.com/deniscerri/ytdlnis)** (the other major
|
||||
Android yt-dlp frontend), keeping only the features AeroFetch doesn't already have.
|
||||
2. A **Windows-native + daily-use UX gap analysis** of AeroFetch itself (things neither Seal
|
||||
nor Pinchflat cover, but that a desktop app should do).
|
||||
|
||||
Nothing here is built yet — every box is unchecked. Phases continue the existing lettering
|
||||
(A–E Seal, F–K Pinchflat) from **L onward**, and each item carries the yt-dlp flag and the
|
||||
AeroFetch file it touches so it can be driven straight from the existing `buildArgs` /
|
||||
`DownloadOptions` / queue plumbing rather than new infrastructure.
|
||||
|
||||
Sources: [YTDLnis GitHub](https://github.com/deniscerri/ytdlnis) ·
|
||||
[YTDLnis docs](https://ytdlnis.org/) · [YTDLnis changelogs](https://ytdlnis.org/changelogs/) ·
|
||||
[F-Droid listing](https://f-droid.org/packages/com.deniscerri.ytdl/).
|
||||
|
||||
### Already at parity with YTDLnis (do **not** rebuild)
|
||||
|
||||
Format/quality/container picking · SponsorBlock (remove/mark + embed-as-chapters) · embed
|
||||
subtitles/metadata/chapters · cookies + login · custom command templates · backup/restore ·
|
||||
**Observe Sources** (= our Phase J watched sources + RSS) · incognito mode · history with
|
||||
filter + bulk re-download · filename templating · self-managing yt-dlp + ffmpeg binaries.
|
||||
AeroFetch is even with, or ahead of, YTDLnis on all of these.
|
||||
|
||||
## Phase L — Media editing (YTDLnis headline features)
|
||||
|
||||
YTDLnis's signature differentiator. The keyframe plumbing already exists in AeroFetch
|
||||
(`--force-keyframes-at-cuts` is emitted today for SponsorBlock-remove in
|
||||
`src/main/buildArgs.ts`), so this is cheaper than it looks.
|
||||
|
||||
- [ ] **Trim / cut downloads.** Download only part of a video, or remove segments — by
|
||||
**timestamp** or by **chapter**, with multiple cuts allowed. → yt-dlp
|
||||
`--download-sections "*START-END"` (repeatable) + `--force-keyframes-at-cuts`.
|
||||
Chapters come free from the probe's `yt-dlp -J` `chapters[]` array (`src/main/probe.ts`).
|
||||
New fields on `DownloadOptions` (or a per-download override), surfaced as a **Trim**
|
||||
panel in `src/renderer/src/components/DownloadBar.tsx`. *v1 can skip a scrubber/preview
|
||||
player — timestamp inputs + checkboxes of the probed chapter list is enough. Smoke-test
|
||||
the exact multi-section output behaviour (one file vs. per-section) the same way
|
||||
Phases A–C smoke-tested live yt-dlp.*
|
||||
- [ ] **Split by chapters into separate files.** → `--split-chapters` (already flagged as a
|
||||
TODO in Phase A above). One toggle on `DownloadOptions` +
|
||||
`src/renderer/src/components/DownloadOptionsForm.tsx`; pairs naturally with trim. Uses an
|
||||
`--output chapter:` template for the per-chapter filenames.
|
||||
- [ ] **Metadata editing before download.** Change title / author / artist pre-download
|
||||
(YTDLnis: "modify metadata such as title and author"). → `--parse-metadata` /
|
||||
`--ppa "Metadata:-metadata title=…"`; fits the audio path of `DownloadOptions`. Good for
|
||||
building a clean music library where the source title is messy.
|
||||
|
||||
## Phase M — Queue & daily-use UX
|
||||
|
||||
Neither Seal nor Pinchflat covers these; they're what makes the queue pleasant to live in.
|
||||
Today `src/renderer/src/store/downloads.ts` has cancel + retry only.
|
||||
|
||||
- [ ] **Pause / resume individual downloads.** → yt-dlp resumes `.part` files via `--continue`
|
||||
(already the default). Pause = kill the child (existing `taskkill /pid /T /F` path) but
|
||||
keep the partial + mark the item `paused`; resume = relaunch the same item, which
|
||||
continues. New `paused` state in the queue store.
|
||||
- [ ] **Reorder / prioritize the queue.** Drag a queued item up. The renderer scheduler
|
||||
(`pump()` promotes oldest-queued-first) already treats the queued array as the order, so
|
||||
this is reordering that array.
|
||||
- [ ] **Aggregate progress + total ETA + combined speed.** A header strip on the Downloads
|
||||
view summing bytes/speed across active items. Feeds straight into Phase O's taskbar
|
||||
progress bar.
|
||||
- [ ] **Drag-and-drop a link or `.url` file onto the window.** A window `drop` handler that
|
||||
accepts `text/uri-list` and Internet-Shortcut files, reusing `extractIncomingUrl()`
|
||||
from `src/main/deeplink.ts` (already validates http(s)-only).
|
||||
- [ ] **Retry all failed.** One action that re-enqueues every entry in `src/main/errorlog.ts`.
|
||||
- [ ] **Duplicate detection.** Warn ("you already have this") when a URL/video-id is already in
|
||||
history or the active queue before enqueuing.
|
||||
- [ ] **Per-download scheduling + "save for later."** YTDLnis lets you "schedule by date and
|
||||
time" and park items. Add `scheduledFor?: number` + a `saved` state to `DownloadItem`;
|
||||
`pump()` gains a time gate before promotion. Distinct from the existing background
|
||||
`--sync` schedule (Phase J), which is for *sources*, not one-off items.
|
||||
|
||||
## Phase N — Power-user surface
|
||||
|
||||
YTDLnis leans hard into this; AeroFetch has the building blocks (command preview, templates,
|
||||
per-item `options`) but not the surfaces.
|
||||
|
||||
- [ ] **Built-in terminal mode.** An interactive raw-yt-dlp console with live stdout/stderr —
|
||||
YTDLnis's "terminal." AeroFetch already has command *preview* (`previewCommand` +
|
||||
`formatCommandLine` in `src/main/download.ts`) and a streaming spawn path; a terminal is
|
||||
"spawn arbitrary argv → stream to a log pane → input box." New view + one IPC channel.
|
||||
- [ ] **Per-playlist-item editing.** Edit each playlist entry separately — different
|
||||
format/type per item, multiple audio formats, batch-update type in one click (YTDLnis).
|
||||
Extend the playlist selection panel in `src/renderer/src/components/DownloadBar.tsx`; the
|
||||
queue already carries per-item `DownloadItem.options`, so the model supports it.
|
||||
- [ ] **Weighted format sorting ("format aspect importance").** Rank codec / container /
|
||||
quality and auto-pick by weighted priority. Extends today's single codec preference
|
||||
(`-S res,fps,vcodec:…`) into a fuller `-S` builder.
|
||||
- [ ] **URL-regex template auto-matching.** A `CommandTemplate` gains an optional URL pattern;
|
||||
`buildCommand` auto-applies the matching template (e.g. always use template X for
|
||||
`soundcloud.com`). Small extension to the existing `defaultTemplateId` logic in
|
||||
`src/main/templates.ts`.
|
||||
- [ ] **Command palette + keyboard shortcuts.** A Ctrl+K palette and a few global shortcuts
|
||||
(paste-and-download, focus URL, switch tabs). Today keyboard handling is just Enter in a
|
||||
couple of inputs.
|
||||
|
||||
## Phase O — Windows-native integration & discoverability
|
||||
|
||||
Grepping `src/main` confirms none of these exist yet (no `setProgressBar`, `Tray`,
|
||||
`setThumbarButtons`, `setJumpList`, `globalShortcut`). All live in the main process, mostly in
|
||||
`src/main/index.ts`.
|
||||
|
||||
- [ ] **Taskbar progress bar.** `win.setProgressBar(fraction)` driven by Phase M's aggregate
|
||||
progress. ~20 lines, very high perceived-quality return.
|
||||
- [ ] **System tray + minimize-to-tray.** A `Tray` with show/quit/pause-all. This is also the
|
||||
coherent home for the **watched-source background sync** (Phase J), which today just
|
||||
"launches the normal window unobtrusively."
|
||||
- [ ] **Thumbnail toolbar buttons** (`win.setThumbarButtons`) — pause/cancel from the taskbar
|
||||
preview — and a **jump list** (`app.setJumpList`) with "Paste & download."
|
||||
- [ ] **Taskbar overlay badge** (`win.setOverlayIcon`) showing active-download count / error state.
|
||||
- [ ] **Settings discoverability.** `src/renderer/src/components/SettingsView.tsx` is ~1,000
|
||||
lines across ~10 cards. Add a **settings search box** or a **Basic / Advanced split** so
|
||||
first-time users aren't faced with the full power-user wall.
|
||||
|
||||
## Phase P — Reliability, longevity & trust
|
||||
|
||||
The least glamorous, highest-leverage track: make sure what's *already shipped* actually works,
|
||||
keep YouTube downloads working as the platform tightens, and remove first-run friction.
|
||||
|
||||
- [ ] **PO Token generation.** YTDLnis mints YouTube tokens in a WebView to dodge throttling
|
||||
and "Sign in to confirm you're not a bot." This is becoming **required** for YouTube to
|
||||
keep working at all. → reuse the existing persisted Electron `BrowserWindow`
|
||||
(`persist:aerofetch-login` in `src/main/cookies.ts`) to host a token-minting script, or
|
||||
support a PO-token provider, passed via `--extractor-args youtube:po_token=…`. A
|
||||
longevity hedge more than a feature.
|
||||
- [ ] **Verify the shipped-but-untested OS wiring** (flagged across both parity tracks as
|
||||
"reasoning + typecheck only"). A single real NSIS-install smoke-test pass over: the
|
||||
cookies sign-in window export · the `aerofetch://` protocol + Explorer "Send to" · the
|
||||
scheduled `--sync` + RSS fast-check (Phase J) · aria2c · proxy. Converts a lot of
|
||||
"probably works" into "verified."
|
||||
- [ ] **Code signing.** The unsigned `.exe` triggers SmartScreen "Run anyway" — the single
|
||||
biggest first-run friction for anyone you share it with. electron-builder `win` signing
|
||||
(OV/EV cert); EV builds SmartScreen reputation fastest.
|
||||
- [ ] **i18n / language setting.** Carried over from Phase E (deferred). YTDLnis and Seal both
|
||||
ship many languages. Large but optional — needs an i18n library + string extraction, with
|
||||
translations arriving incrementally.
|
||||
|
||||
---
|
||||
|
||||
## Post-parity — what we reuse vs. build
|
||||
|
||||
**Reuse unchanged:** `buildArgs`/`buildCommand` flag emission, `DownloadOptions` +
|
||||
`DownloadOptionsForm`, the renderer queue scheduler + concurrency cap + per-item `options`,
|
||||
the persisted cookies `BrowserWindow`, the probe's `chapters[]`/format data, `errorlog.ts`,
|
||||
`CommandTemplate`s, `extractIncomingUrl()`, and the self-managing binary updater.
|
||||
|
||||
**Build new:** the trim/split UI + `--download-sections`/`--split-chapters` wiring (L), the
|
||||
pause/reorder/schedule queue states (M), the terminal view + per-item playlist editor (N), the
|
||||
main-process taskbar/tray/jumplist integration (O), and the PO-token provider (P).
|
||||
|
||||
## Post-parity — suggested order
|
||||
|
||||
**L is the high-value headline** — trim + split-chapters share one UI surface and the keyframe
|
||||
plumbing already exists, so they land cheaply and give AeroFetch YTDLnis's marquee capability.
|
||||
Then **P's PO-token + verify-wiring** as a reliability block (keeps YouTube working and de-risks
|
||||
shipped features). **M** and **O** are the daily-use polish and pair well (aggregate progress →
|
||||
taskbar bar). **N** is the power-user surface, each item independently shippable. Each phase is
|
||||
self-contained and rebuild-gated (`npm run typecheck` + `npm run test` + `npm run build`) the
|
||||
same way Phases A–K were.
|
||||
|
||||
Reference in New Issue
Block a user