4.7 KiB
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(briefbriefs/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: rootCargo.toml(one line in[workspace.dependencies]:notescraft-textdiff = { path = "crates/textdiff" }, and the member glob already coverscrates/*),xtask/src/layers.rs(("textdiff", Class::Layer(0))in L0 ofTABLE), and any layers test inxtask/that counts crates (grepTABLE). FILES TO OPEN:spec.mdD1,crates/tasks/Cargo.toml(manifest to copy:[lints] workspace = true,publish = false),crates/tasks/src/lib.rs(#![deny(...)]header andErrorstyle),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 exceptthiserror; touch other crates.
Phase 2 - engine
- 2.
history.diff. OWNS:crates/engine/Cargo.toml(one dependency linenotescraft-textdiff = { workspace = true }),crates/engine/src/commands.rs(new spec + fn next tohistory_list),crates/engine/src/ai/assistant_gate.rs,crates/engine/tests/core_commands.rs,crates/engine/tests/history_diff.rs. FILES TO OPEN:spec.mdD2,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;againstsnapshot orcurrent(buffer text if open, else file). TESTS: two snapshots (usesnapshot_note_atthrough the test helper pattern insnapshots/mod.rstests), diff counts, unknown id -> error, current vs open buffer, spans cap setstruncated. VERIFY: standing +--test history_diff --test core_commands. DO NOT: changehistory.listoutput; 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;DiffJobworker 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 incrates/i18n/locales/en.toml),crates/ui-egui/tests/versions_slider.rs. FILES TO OPEN:spec.mdD3,crates/ui-egui/src/views/versions_view/mod.rs,crates/ui-egui/src/shell/app/window/views.rs:130-160(howVersionsActionis handled),.claude/skills/notescraft-egui-screen/. GOAL: proportional ticks, keyboard, "vs previous / vs now" toggle (Switch widget), Restore button emits existingVersionsAction::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.