Skip to content

feat(desktop): populate file panel Diff/History from session snapshots#158

Merged
oratis merged 2 commits into
mainfrom
feat/desktop-file-panel-snapshots
Jun 4, 2026
Merged

feat(desktop): populate file panel Diff/History from session snapshots#158
oratis merged 2 commits into
mainfrom
feat/desktop-file-panel-snapshots

Conversation

@oratis
Copy link
Copy Markdown
Owner

@oratis oratis commented Jun 4, 2026

What

The desktop file panel (FilePanel.tsx) has Source / Diff / History tabs, but Diff + History were always empty — the follow-up noted in use-file-panel.ts ("Diff/History data is left empty here — those are backed by session snapshots, wired in a follow-up").

This wires both tabs to session snapshots.

Why it needed Rust-side capture

Core captures snapshots in agent.ts (pre/post each Edit/Write) — but only when a SessionManager is passed. The desktop runs core's runAgent in the renderer (mac-agent.ts) and deliberately passes no manager (the webview has no node:fs). So desktop sessions captured zero snapshots. The fix captures them on the Rust side instead.

How

Rust (apps/desktop/src-tauri/src/)

  • snapshots.rs (new): capture_file_snapshot writes a blob + appends manifest.jsonl under ~/.deepcode/sessions/<id>/snapshots/ — the same on-disk layout/shape as core (filePath, capturedAt, reason, hash, size, seq, blobPath, kind) so /rewind interops. Adds session_snapshots(sessionId, filePath) command. Uses sha2 for the hash; ISO + blob timestamps are hand-rolled (no chrono).
  • tools.rs: tool_write / tool_edit take an optional session_id and capture a pre + post pair per mutation. Best-effort — a snapshot hiccup never fails the user's edit. The post snapshot is stamped +1ms so two history rows never collide on a millisecond timeline.
  • mac-session.ts (new): publishes the active session id (mac-agentmac-tools + panel) so tools snapshot under it and the panel reads them back, with no mac-agent ↔ mac-tools import cycle.

Renderer

  • diff.ts (new): pure LCS line differ → DiffLine[] (testable, no deps).
  • file-history.ts (new): snapshots → History timeline (collapses consecutive identical states) + Diff baseline (oldest snapshot).
  • useFilePanel.open fetches a file's snapshots → Diff (current vs session baseline) + History; selectHistory(ts) recomputes the diff against the chosen revision and jumps to the Diff view.

Diff semantics

The Diff tab defaults to the net session changeoldest snapshot → current file — i.e. "what did this conversation do to this file". (The task suggested most-recent-pre-edit vs current; for a multiply-edited file the net view is the more useful default, and the History tab drills into individual revisions. One-line change if you'd prefer last-edit-only.)

Tests / verification

  • Rust (24 pass): capture↔list roundtrip + path filtering, capture-pair seq/distinct-ms, monotonic seq across calls, ISO/blob time formatting, camelCase serialization. cargo build --release compiles clean under LTO. (CI does not build Rust — ran locally.)
  • TS (54 desktop pass): line differ (insert/delete/change/empty edges), history mapping/dedup, reducer setDiff. typecheck / lint (0 new warnings) / format:check / desktop vite build all green.
  • Mock-Tauri preview (preview-app.html): opened the file, confirmed the Diff renders the real computed baseline diff, History shows the deduped timeline, and selecting a History row recomputes the diff vs that revision + switches to Diff.
Diff + History tabs (mock-Tauri preview)

Diff = <meta charset> added, <canvas> changed (del+add), <script> block added (oldest snapshot → current); History = 3 deduped rows with tool badge + time.

Remaining manual step

A live packaged-app check (build the .app, run a real agent Edit/Write, open the file → confirm Diff/History populate) needs DeepSeek credentials + GUI interaction, so it's not automated here. The Rust↔JS IPC mapping (camelCase→snake_case) follows the existing tool_read/tool_edit convention already shipping in prod.

🤖 Generated with Claude Code

t and others added 2 commits June 4, 2026 15:57
The desktop file panel's Diff/History tabs were always empty: the renderer
runs core's runAgent without a SessionManager (the webview has no node:fs),
so core's snapshot capture (agent.ts) never fired for desktop sessions.

Capture snapshots on the Rust side instead, mirroring core's on-disk format
(~/.deepcode/sessions/<id>/snapshots/ — manifest.jsonl + blobs) so /rewind
interops:
- snapshots.rs: capture_file_snapshot + session_snapshots(sessionId,
  filePath) command. sha2 for the hash; ISO/blob timestamps hand-rolled
  (no chrono).
- tool_write/tool_edit take an optional session_id and capture a pre+post
  pair per mutation, best-effort (a snapshot hiccup never fails the edit).
  The post is stamped +1ms so history timestamps never collide.
- mac-session.ts publishes the active session id (mac-agent -> mac-tools +
  panel) so tools snapshot under it and the panel reads them back.

Render it:
- diff.ts: pure LCS line differ -> DiffLine[].
- file-history.ts: snapshots -> History timeline (consecutive identical
  states collapsed) + Diff baseline (oldest snapshot).
- useFilePanel.open fetches a file's snapshots -> Diff (current vs session
  baseline) + History; selectHistory(ts) recomputes the diff against that
  revision and jumps to the Diff view.

Diff defaults to the NET session change (oldest snapshot -> current) — the
"what did this conversation do to this file" view.

Tests: +5 Rust (capture<->list roundtrip, capture-pair seq/ms, time fmt),
+15 TS (differ, history mapping), +2 reducer. Verified the full hook flow
(Diff, History, selectHistory) in the mock-Tauri preview.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
… titlebar

The right activity rail was icon-only (tooltips on hover only), so the Inspector / Files / Settings toggles were not self-explanatory. Add a text label under each icon (rail 48->64px) and surface the active right-panel's name centered in the otherwise-empty macOS titlebar strip (pointer-events:none keeps it OS-draggable, matching the shell's no-webkit-drag approach). No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@oratis oratis merged commit 9c8d2c3 into main Jun 4, 2026
3 checks passed
@oratis oratis deleted the feat/desktop-file-panel-snapshots branch June 4, 2026 13:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant