Files

197 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# viexp Roadmap — Rust + English in 20-hour sprints
Method: Josh Kaufman, **"The First 20 Hours"** — rapid skill acquisition. The project is split
into isolated 20-hour sprints (~45 min/day for a month each). Every sprint: one Rust sub-skill,
one working app increment, one English artifact. The goal of each sprint is to cross the
frustration barrier and ship something that runs — not perfect code.
**Kaufman's rules, adapted**
| Kaufman principle | How this roadmap applies it |
|---|---|
| Deconstruct the skill | The table below: each sprint = one sub-skill + one app increment |
| Learn just enough to self-correct | Per-sprint "Rust focus — the vital 20%": the minimum theory to *read your own compiler errors*. Every error goes to the ErrorJournal with a self-correction cue |
| Remove barriers to practice | Sprint 0 sets up the whole environment: toolchain, linters, fast feedback (`bacon`), Gitea board, CI. Never debug your setup during practice time |
| Fast feedback loops | `cargo check`/bacon on save, unit tests per session, immediate AI code review of each session's diff (commit → review → fix) |
| Quantity over quality | Many small commits, many small drills. Working ugly code beats beautiful unfinished code. No over-engineering before v0.1 |
## Skill deconstruction
**Rust sub-skills** (learned in order): cargo & project layout → types & control flow →
ownership/borrowing → structs, enums, pattern matching → `Option`/`Result` & `?` →
modules & crates → traits & generics → iterators → `Path`/`fs` & error handling (`thiserror`/`anyhow`) →
serde/TOML → lifetimes → trait objects & dynamic dispatch → threads & channels →
async/await & tokio → process spawning → caching & performance.
**App increments** (each demoable): `vls` CLI → 3-pane TUI → navigation & file ops →
config & openers → text previews → image previews → document previews → media & async →
script plugins → power features → performance → release.
**English track**: every commit message, every issue, all docs — English only. One written
artifact per sprint. Daily DevLog (3–5 sentences). See [[workflows/english-workflow|English workflow]].
## Session rhythm (45 min, every day)
1. **5 min** — read yesterday's DevLog + ErrorJournal; `git pull`, `bacon` starts.
2. **30 min** — today's drill or feature slice (one drill = one commit).
3. **10 min** — get the diff reviewed, fix what the reviewer flags, write the DevLog entry.
**Frustration rules**: stuck >20 min on one error → ask for a review instead of grinding;
never end a session with broken code (revert to green); a slow day is a reading day
(Rust Book chapter in English) — log it, no guilt.
## Sprints
Legend: 🎯 milestone. Each sprint gets a `docs/sprints/sprint-NN-*.md` note (Sprint template)
and a Gitea milestone with issues created from its Definition of Done.
---
### Sprint 0 — Setup & deconstruction (≈6 h, short)
- **App deliverable**: empty `viexp` cargo project that compiles, `cargo test` runs one trivial
test, CI (Gitea Actions) is green, `bacon` + `clippy` + `rustfmt` wired, Gitea board ready.
- **Rust focus**: toolchain mental model — what cargo, rustc, crates.io, `Cargo.toml` are;
read your first compiler error on purpose (break a program, fix it).
- **English**: README "Status" section + the vault (this roadmap counts).
- **DoD**: `cargo bacon` shows check+test on save; first commit pushed; Sprint-1 issues exist.
### Sprint 1 — Rust core via `vls` (20 h)
- **App deliverable**: `viexp ls` subcommand — a better `ls`: colored names by type,
human-readable sizes, `--sort name|size|mtime`, `--hidden`, `--long`; ≥10 unit tests.
- **Rust focus (vital 20%)**: variables & types, functions, `if`/`match`, loops, `Vec`/`String`
vs `&str`, structs & enums, `Option`/`Result` + `?`, modules, `#[cfg(test)]`.
Rust Book ch. 1–9 (skim 7/8), rustlings `intro→enums`.
- **English**: README usage section; article "Why build a file manager in Rust" (draft).
- **DoD**: `vls ~/` output beats `ls` for your eyes; clippy clean; tests green.
### Sprint 2 — First TUI (20 h) — the borrow-checker sprint
- **App deliverable**: three-pane Miller layout (parent / current / placeholder preview),
`j/k/gg/G` cursor movement, `:q` quits, resize-safe redraw, no flicker.
- **Rust focus**: **ownership & borrowing in anger** (the state struct owns everything),
references vs clones, lifetimes as they appear in ratatui calls, the event-loop pattern
(poll event → mutate state → redraw). Rust Book ch. 4, 10.3 (skim), ratatui official docs.
- **English**: keymap reference table in docs (precise imperative phrasing).
- **DoD**: navigate a 10k-file directory smoothly; panic-free for 15 min of use.
### Sprint 3 — Navigation & file ops (20 h) 🎯 **M1: personal daily driver**
- **App deliverable**: enter/leave directories, hidden toggle, sort cycling, `Space`/`V`
selection, `yy`/`dd`/`pp` copy/cut/paste, delete → **first-class trash** (freedescompliant)
with undo, `:mkdir :touch :rename`, status bar (path, size, free space — **not** per-frame
`statvfs`; 1 Hz poll).
- **Rust focus**: `Path`/`PathBuf`, `fs::read_dir`/`metadata`, real error handling
(`thiserror` for lib-style internals, `anyhow` at main), iterators (`map/filter/sort_by`
chains), `Display` impls.
- **English**: article "Week one of dogfooding my own file manager".
- **DoD**: use viexp instead of ranger for real work for 3 days; log every pain point as an issue.
### Sprint 4 — Config & openers (20 h)
- **App deliverable**: `viexp.toml` (defaults, theme colors, sort) + `modules.toml` registry
v0 (ADR-003): mime/glob → opener, per-module `enabled`, user rules prepend/append;
opener engine (infer + xdg-mime → rule table → `xdg-open` fallback), `r` "open with" menu,
`:open_with`.
- **Rust focus**: serde derive on enums/structs, `Default` + merge semantics, `HashMap`/
`BTreeMap`, first **trait design** (`Opener`), builder-ish config loading with helpful errors.
- **English**: configuration guide draft (reference-style writing).
- **DoD**: any file opens with your preferred app from config alone; broken TOML produces a
friendly error, not a panic.
### Sprint 5 — Text previews & bulk rename (20 h)
- **App deliverable**: preview pane v1 — syntax-highlighted text (syntect) with line numbers
and scrolling, directory preview, file metadata panel, zip/tar listing, `:bulkrename` via
`$EDITOR` (ranger's killer feature), `n/N` plain search, `:` command history.
- **Rust focus**: lifetimes in real signatures, **trait objects** (`Box<dyn Previewer>` registry),
advanced iterators, caching keyed by `(path, mtime)`.
- **English**: article "How a TUI paints text" (explaining rendering → strongest writing practice).
- **DoD**: preview parity with ranger for text/code/archive files.
### Sprint 6 — Image previews (20 h) 🎯 **M2a**
- **App deliverable**: image module through the registry; **kitty graphics adapter first**
(owner's terminal), chafa/halfblocks floor; thumbnail disk cache + LRU; runtime
disable/replace via `modules.toml` proven on images.
- **Rust focus**: the `image` crate, decode/resize pipeline, `#[cfg(feature)]` modules,
pixel data, spawning helper processes safely.
- **English**: article "How terminals display images" (kitty protocol, sixel, ueberzug++ —
your best future blog post; research notes already hold the material).
- **DoD**: PNG/JPEG/WebP/GIF preview instantly in kitty; `enabled=false` kills it in one line.
### Sprint 7 — Document previews (20 h) 🎯 **M2b: full ranger replacement**
- **App deliverable**: PDF (pdfium-render, Apache-2.0), EPUB (hand-rolled zip+XML — **GPL
trap avoided**), Markdown (comrak/termimad), DJVU (djvu-rs + `ddjvu` fallback config).
All as registry modules, all runtime-disableable.
- **Rust focus**: binary data & byte streams, feature-gated crates, error taxonomy design,
more trait objects; reading crate docs as a skill.
- **English**: module documentation pages (PDF/EPUB/DJVU) in user-guide style.
- **DoD**: your entire document library previews; ranger uninstalled.
### Sprint 8 — Media & async (20 h) 🎯 **M2c**
- **App deliverable**: video thumbnail (spawn `ffmpeg -ss … -vframes 1`), audio metadata +
cover art (`ffprobe` JSON), **background preview pipeline**: std threads + mpsc now,
generation-counter cancellation, large-directory pagination; adopt **tokio** for the
pipeline by sprint end (ADR-005).
- **Rust focus**: `std::thread`, `mpsc`, `Arc`/`Mutex`, then async/await, `tokio::spawn`,
`select!`, cancellation patterns. Rust Book ch. 16 + async book chapters (English only!).
- **English**: article "Async Rust for a skeptic" — explain threads-vs-tokio in your own words.
- **DoD**: 4K-video directory scrolls at full speed; huge directory never blocks input.
### Sprint 9 — Script plugin protocol (20 h) 🎯 **M3a: extensible**
- **App deliverable**: freeze the **external plugin contract** (ADR-002 phase 2): previewer
argv `(path, w, h, x, y)` + env context + FIFO write-back + `cleaner` hook; documented
exit codes & SIGPIPE; opener scripts; `plugins/` dir discovery; two reference plugins
(bash: torrent info; python: git repo summary).
- **Rust focus**: process spawning & pipes, timeouts, safe command construction (no shell
injection), protocol design & semver, integration tests with fixture scripts.
- **English**: **plugin author guide** — the sprint's main artifact; write it as if for strangers.
- **DoD**: a script written only from the guide (no source peeking) works.
### Sprint 10 — Power features (20 h) 🎯 **M3b: feature parity with your ranger config**
- **App deliverable**: tabs, bookmarks + marks, fuzzy finder (nucleo) with **interruptible**
search (broot lesson), `:commands` set (`:find :delete :copy…`), `push` key-simulation,
shell integration `--choosefile/--choosedir/--selectfile`, cd-on-exit wrapper script,
session restore.
- **Rust focus**: state machines (modes), Rc-free architecture review, `macro_rules!` for
keymap tables, API refactoring under tests.
- **English**: article "Vim-style UX patterns in file managers".
- **DoD**: your shell rc sources the viexp wrapper; fuzzy find feels instant.
### Sprint 11 — Performance & robustness (20 h)
- **App deliverable**: `notify`-based live directory updates, virtual scrolling, startup
<50 ms, one-week dogfood with zero panics, `tracing` logs to file, panic hook restores
the terminal, criterion benchmarks committed, crash-fix buffer.
- **Rust focus**: profiling (`cargo flamegraph`, `perf`), benchmarking (criterion), reading
someone else's code (yazi's) for patterns, hardening.
- **English**: article "Profiling a TUI app: making viexp start in 40 ms".
- **DoD**: benchmark numbers in README; a week of daily use logged.
### Sprint 12 — Release & docs (20 h) 🎯 **M4: v0.1.0 public**
- **App deliverable**: `v0.1.0` — cargo-dist release builds, AUR PKGBUILD, Gitea release +
changelog, **user guide** (mdBook in-repo), plugin examples gallery, install docs.
- **Rust focus**: release engineering, MSRV policy, feature matrix testing, rustdoc comments
on the public plugin API.
- **English**: the user guide is the largest English artifact of the project; polish it hard.
- **DoD**: a stranger installs from AUR and writes a plugin using only the docs.
### Backlog (post-1.0, priority order)
Embedded Lua plugins (mlua, ADR-002 phase 3) · sixel/iTerm2/ueberzug++ adapters · DDS-style
inter-instance pub/sub · `NNN_FIFO`-style hover event stream · themes gallery · zoxide jump ·
archive mount/browsing depth.
## Milestones
| Milestone | After sprint | Meaning |
|---|---|---|
| M1 | 3 | daily driver for basic navigation/file ops |
| M2a–c | 6–8 | full ranger replacement (images, docs, media) |
| M3a–b | 9–10 | extensible by scripts, feature parity |
| M4 | 12 | v0.1.0 released publicly |
At 45 min/day this is roughly a 12–13 month journey to v0.1.0 — the point is a working
product **and** durable skills, in that order, every single sprint.
## Cadence & safety nets
- Sprint notes live in `docs/sprints/`; each sprint's DoD becomes Gitea issues (milestone per
sprint) — see [[workflows/gitea-workflow|Gitea workflow]].
- If a sprint overruns by >30%, cut scope from the bottom of its DoD — never silently skip tests.
- One "buffer week" is allowed between sprints; more than one means the sprint was too big —
re-decompose in the retro.