Desktop: expose channel canvas revision history
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
**Motivation**
The Desktop canvas view shows only the current content. It doesn't show who signed the current revision, and there's no way to look at an earlier one. In a channel where agents and people both edit the canvas, there's currently no in-app way to answer "who changed this, and what did it say before?"
The revisions themselves are already on the relay. `KIND_CANVAS` is 40100 (`crates/buzz-core/src/kind.rs:434-435`), which is neither replaceable (`kind.rs:701-705` covers 0, 3, 41 and 10000–19999) nor parameterized-replaceable (30000–39999, `kind.rs:708-713`). Canvas updates take the ordinary event-insert path, so a later save doesn't supersede the earlier rows.
The attribution already crosses the IPC boundary too. `get_canvas` asks for `limit: 1` and returns the newest event's content, author and timestamp (`desktop/src-tauri/src/commands/canvas.rs:15-41`), and the TS bridge normalizes those to `author` and `updatedAt` (`desktop/src/shared/api/tauri.ts:410-421`). But `ChannelCanvas.tsx:38` reads only `.content`, so neither value is rendered.
**Proposed solution**
A read-only first slice:
- A line on the canvas showing who last updated it and when, resolving the pubkey through the existing profile batch query so people and agents render the same way
- A history view listing earlier revisions with author and timestamp
- Selecting a revision shows that content read-only, with a way back to current
Deliberately out of the first slice: diffing between revisions, and restore.
**Alternatives considered**
Restore-as-new-event would be the natural follow-up, since publishing an old revision's content as a new 40100 keeps the history append-only and makes the restore itself attributable. Kept separate so the read-only view isn't blocked on it.
Diffing needs a dependency decision. `desktop/src/features/messages/lib/parseDiff.ts:18-34` parses an existing unified diff via `react-diff-view`; it doesn't generate one, and there's no text-diff generator in `desktop/package.json`. That's a separate conversation.
**Additional context**
Closest prior art: #2809 proposes surfacing the current revision's author, timestamp and event ID in the canvas panel, and explicitly lists revision browsing as a non-goal. This issue is that follow-up, so the attribution line overlaps and should probably follow whatever placement #2809 settles on. Merged PR #1755 exposes the current canvas revision id and timestamp to ACP agents, but not to users. I didn't find an open issue or PR asking for revision history itself.
Two things worth deciding if this is wanted:
- How many revisions to load by default, and whether to cap or paginate. A heavily-edited canvas could have a lot of rows.
- Whether legacy canvases are in scope. The older singleton `channels.canvas` column still exists (`migrations/0001_initial_schema.sql:72-80`, `crates/buzz-db/src/channel.rs:297-324`), so canvases written through the pre-event path won't have history to show. Current kind:40100 revisions need no migration.
Happy to implement the read-only slice if the scope looks right.
Contributor guide
Assessment
This issue has not been assessed yet.