39 lines
4.7 KiB
Markdown
39 lines
4.7 KiB
Markdown
# Tasks: note visual diff and time-machine slider (roadmap 27)
|
|
|
|
One task = one agent (`specs/agents/opencode-runbook.md`). Spec: `spec.md`. Rules: `AGENTS.md`, `docs/CODE-MAP.md`.
|
|
**First tool call rule**: after at most three reads, write the first OWNS file in your SECOND tool call (compiling stub + ONE failing test), then make it pass.
|
|
**Standing VERIFY**: `export PATH="$HOME/.cargo/bin:$PATH"`; `cargo test -p <pkg>`; `cargo clippy -p <pkg> --all-targets -- -D warnings`; `rustfmt --edition 2024 <owned files>`; UI tasks add `cargo xtask i18n`; last task of a phase adds `cargo xtask layers` and `cargo xtask tree`.
|
|
**Standing DO NOT**: edit files outside OWNS, git state, `cargo fmt --all`; add `allow`; `unwrap/expect/panic/[i]/[a..b]` on input-derived data; add a dependency.
|
|
|
|
## Owner/lead step 0
|
|
Answer Q1 and Q2. If Q2 = `similar`, the owner adds it and task 1 shrinks to a wrapper.
|
|
|
|
## Phase 1 - pure crate
|
|
- [ ] 1. Crate `notescraft-textdiff` (brief `briefs/14-textdiff-crate.md`). Crate registration is part of this task:
|
|
OWNS: `crates/textdiff/Cargo.toml`, `crates/textdiff/src/lib.rs`, `crates/textdiff/src/tokens.rs`, `crates/textdiff/src/myers.rs`, `crates/textdiff/tests/word_diff.rs`; registration edits: root `Cargo.toml` (one line in `[workspace.dependencies]`: `notescraft-textdiff = { path = "crates/textdiff" }`, and the member glob already covers `crates/*`), `xtask/src/layers.rs` (`("textdiff", Class::Layer(0))` in L0 of `TABLE`), and any layers test in `xtask/` that counts crates (grep `TABLE`).
|
|
FILES TO OPEN: `spec.md` D1, `crates/tasks/Cargo.toml` (manifest to copy: `[lints] workspace = true`, `publish = false`), `crates/tasks/src/lib.rs` (`#![deny(...)]` header and `Error` style), `xtask/src/layers.rs:36-60`.
|
|
GOAL: D1 API; `Error::TooLarge`.
|
|
TESTS: reproduction property (1 000 pseudo-random pairs from a fixed LCG seed, no rand dep), one changed word, insertion at start/end, empty old/new, both empty, CRLF, emoji, 2 MiB pair returns Ok or TooLarge in < 500 ms (`#[ignore]` perf), limits boundaries.
|
|
VERIFY: standing `-p notescraft-textdiff` + `cargo xtask layers`. DO NOT: depend on any crate except `thiserror`; touch other crates.
|
|
## Phase 2 - engine
|
|
- [ ] 2. `history.diff`.
|
|
OWNS: `crates/engine/Cargo.toml` (one dependency line `notescraft-textdiff = { workspace = true }`), `crates/engine/src/commands.rs` (new spec + fn next to `history_list`), `crates/engine/src/ai/assistant_gate.rs`, `crates/engine/tests/core_commands.rs`, `crates/engine/tests/history_diff.rs`.
|
|
FILES TO OPEN: `spec.md` D2, `crates/engine/src/commands.rs:110-125,310-330`, `crates/engine/src/vault/snapshots/mod.rs`, `crates/engine/tests/common/mod.rs`.
|
|
GOAL: D2 table; `against` snapshot or `current` (buffer text if open, else file).
|
|
TESTS: two snapshots (use `snapshot_note_at` through the test helper pattern in `snapshots/mod.rs` tests), diff counts, unknown id -> error, current vs open buffer, spans cap sets `truncated`.
|
|
VERIFY: standing + `--test history_diff --test core_commands`. DO NOT: change `history.list` output; touch UI.
|
|
## Phase 3 - UI
|
|
- [ ] 3. Word diff pane (pure paint + cache).
|
|
OWNS: `crates/ui-egui/src/views/versions_view/word_diff.rs`, `crates/ui-egui/tests/word_diff_view.rs`.
|
|
FILES TO OPEN: `crates/ui-egui/src/views/diff_view/render.rs` (colour tokens used), `crates/ui-egui/src/views/versions_view/mod.rs`, `crates/ui-egui/src/views/share_dialog/mod.rs` (worker pattern).
|
|
GOAL: `paint(ui, tokens, &[Span])` wrapped rich text; `DiffJob` worker with 120 ms debounce and (id, against) cache.
|
|
TESTS: kittest paints add/del spans without panic; cache returns without new job; 5 000 spans bounded.
|
|
VERIFY: standing. DO NOT: hex colours; engine calls on the UI thread.
|
|
- [ ] 4. Slider and wiring.
|
|
OWNS: `crates/ui-egui/src/views/versions_view/slider.rs`, `crates/ui-egui/src/views/versions_view/mod.rs` (hook lines), `crates/ui-egui/src/text/versions_view.rs` (+ matching keys at END of the `[ui.versions]` block in `crates/i18n/locales/en.toml`), `crates/ui-egui/tests/versions_slider.rs`.
|
|
FILES TO OPEN: `spec.md` D3, `crates/ui-egui/src/views/versions_view/mod.rs`, `crates/ui-egui/src/shell/app/window/views.rs:130-160` (how `VersionsAction` is handled), `.claude/skills/notescraft-egui-screen/`.
|
|
GOAL: proportional ticks, keyboard, "vs previous / vs now" toggle (Switch widget), Restore button emits existing `VersionsAction::Restore`.
|
|
TESTS: kittest: ticks count == snapshots+1, click tick selects it, arrow keys move, Restore emits the right id, too-large message shown.
|
|
VERIFY: standing + `cargo xtask i18n` + snapshot PNG read. DO NOT: remove the row list; raw egui widgets.
|
|
- [ ] 5. Docs and status. OWNS: `ROADMAP.md`, `docs/ARCHITECTURE.md` (new crate), `docs/CODE-MAP.md`, `specs/plugins-parity/roadmap.md` (mark 27). VERIFY: `cargo xtask ci`.
|