Add research documentation on unified diff UX and external tool references - #2807
Open
sinelaw wants to merge 19 commits into
Open
Add research documentation on unified diff UX and external tool references#2807sinelaw wants to merge 19 commits into
sinelaw wants to merge 19 commits into
Conversation
Raw upstream doc dumps (GitLens README, Zed agent-panel and git docs) left in the tree by an earlier research session; committed as-is so the research inputs travel with the branch. A fourth file was a saved '404: Not Found' page and was deleted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…iner, four doors Diagnoses the seven overlapping diff surfaces (Review Diff, Review Range/ Stash, Review PR Branch, Git Log, Side-by-Side, Live Diff, Blame + three hunk-nav and two gutter systems), distills field research across ~40 tools (magit, lazygit, tig, jj, delta, difftastic, diffview.nvim, hunk, Zed, VS Code, JetBrains, Gerrit, Reviewable, Graphite, GitHub 2025-26, Conductor, Superset, Linear Diffs, difit/diffx/tuicr/revdiff, ...), and proposes a single architecture: - one Diff Renderer (stack/split, syntax + intraline everywhere) - one Review Session container parameterized by (source, lens, verbs, state), with comments, viewed marks, and a per-commit lens replacing the separate PR-Branch mode - one in-buffer Lens merging live-diff, git-gutter, and diff-nav - four task-shaped doors: Review Changes, Review Branch/PR, History, Review Agent Work (new orchestrator entry point), behind a single Review… picker - an agent loop: severity-tagged comments dispatched to sessions, review IPC, and iteration interdiff as the long-term differentiator Includes a phased migration plan (0-3), rename/deletion table, and risks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…hatch, feedback-transport resilience, keep/reject guardrails
Reevaluates the unified diff-experience design against a deep-research pass
on what agent-era users praise and complain about:
- TUI fatigue: adopt the field's local-web escape hatch, but via Fresh's
existing parity-tested web bridge ("Open this review in the browser",
same session/state, no second implementation) — new section 3.8
- feedback loop: dual transports for agent exchange (rich IPC path plus a
file-based .review/ outbox/inbox fallback, since sandboxed agents
demonstrably can't reach local daemon ports)
- keep/reject context blindness: file-level default granularity, a
related-changes nudge, and a leftover-noise scan for agent diffs
- marathon reviews: persist read position, fold layout, and unsent comment
drafts with the session, not just comments and viewed marks
- review inbox across agent sessions in the picker; megamerge review
explicitly deferred
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…agent/external comms) Part I — the priority — is the review experience itself: navigation, baselines, lenses, doors, layouts, comments-as-notes, and marathon-review persistence. It ships identically in TUI and web via the existing scene parity discipline, so the dedicated web-escape-hatch section is replaced by a parity constraint (no review feature may land as TUI-only logic). Part II — explicitly lower priority and orthogonal by construction — now holds everything that talks to the outside world: comments-as-prompts / send-to-session, review IPC with the file-based transport fallback, agent-seeded reviews, pause-on-review, guided-review outlines, and forge/PR sync. Door 4 is reduced to pure UI (baseline + keep/reject verbs); the iteration-interdiff lens stays in Part I as baseline-selection UX. Phasing reflects the split: phases 0-3 are Part I only; new Phase 4 is Part II. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
Nine frames grounded in the real chrome captured during the tmux exploration: the Review Session container in stack and split layouts (worktree door), the Review Branch door in flattened and per-commit lenses, the History door with its shared-renderer detail pane, the agent door with baseline picker and related-changes nudge dialogs, the Review… picker palette, and the buffer lens with a hunk expanded in place. Each frame annotates what it encodes (enclosing-context hunk headers, copy-safe bodies, session-wide counters, viewed/kept progress, comment severity badges, lens-stable comments) so the wireframes double as the spec for the chrome contract. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
Replaces the chrome-conservative Part I presentation with a clean-slate UI built purely from the research lessons (the prior draft stays in git history as the low-risk fallback, per the new §3.12 migration note): - two lines of chrome total: a scope bar (base ⟶ target · lens · burn-down gauge) and a context line that doubles as the action receipt - no separate picker, History tab, or fixed comments column: doors become scope presets inside the workspace's scope-choosing state; History is the commits lens over a wide scope; comments live inline plus a notes projection of the one navigator rail (files/commits/notes, cycled) - the stream is a magit-style section document with sticky context header, depth presets, persistent folds, chip-row verbs on the focused section (the only mutation surface, doubling as the keymap hint), format-only dimming, generated-file quarantine, and interactive unchanged-context separators - three-key review loop: Space = mark-and-advance burn-down, Enter = zoom (scope → file → hunk → real buffer portal), Esc = back out; completion and resume states designed explicitly - one view transient with sticky options; runnable ? help; Z undo with command echo for every mutation - verb sets bound by scope target (stage / keep-reject / read-only) with the agent guardrails re-expressed in the new chrome Ten new wireframes cover: reading state, scope-choosing, lens menu, rail projections, line selection, comment compose, completion, resume, view transient, buffer portal, and the agent reject receipt. Stale door/section references in Parts II, phases, and rename table updated to the scope-preset vocabulary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…ce, and adoptions Two designers were given only the task list and research evidence (the existing Fresh UI and this doc's workspace design withheld) and asked to design the review TUI from scratch. Both independently converged with the workspace on the same skeleton — comparison-as-identity, section tree, selection-drives-preview, relabeling verbs, hash-keyed viewed marks, resume-leads-with-delta, undo over confirmation, runnable help — which de-risks the §3 core. The section presents each alternative's distinctive ideas with one representative frame and a verdict table, keeps the genuine differences explicit (chips vs hint bar, cycling rail, in-workspace presets), and ends with the adoption list: uppercase-escalation keymap rule, C conclude verb, runnable-help-as-palette, persisted undo journal via git objects, waiting-on-you session ordering, narrative default order for agent scopes, live-update queueing, symbol-graph reject guard, last-review default target, interdiff pseudo-commit, noise out of the progress denominator, command log, and the sub-100-col zoom model. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…Appendix A Section 3 is now the design of record with the blind-redesign adoptions folded in: C conclude verb, uppercase-escalation keymap rule, runnable help-as-palette, git-object undo journal surviving restarts, waiting- on-you session ordering with sparklines, narrative default file order in agent scopes, live-update queueing (content never moves under the cursor), symbol-graph reject guard, since-my-last-review as the default reopened target, interdiff pseudo-commit after force-pushes, noise excluded from the progress denominator, the command log, the sub-100-col zoom model, and the wide-screen anchored comments rail. Mouse operation is now first-class throughout: verb rows are clickable buttons that print their keys, every scope-bar segment is a button, hover reveals checkboxes and per-row actions, context-expanders and scrollbar-map markers are click targets, right-click menus mirror every verb, and a dedicated mouse-story section (3.10) states the parity rule - no keyboard-only and no mouse-only paths - while keeping the two-line chrome budget. The two independent redesigns move from §3.13 to Appendix A with cross-references updated; §3.14 records provenance and the two questions left to prototyping (section buttons vs hint bar, h/l granularity ladder). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…eraction captions A click-by-click progression through a full agent-session review with no key pressed at any point: menu bar → Review menu → scope-choosing rows → workspace → lens dropdown → commits strip → hunk verb button → symbol- graph guard buttons → undo receipt → live-queue badge → rail-projection dropdown → notes rail → note jump with comment-box buttons → hover- checkbox completion → conclude summary. Each frame is separated by a caption stating exactly what the user clicked. Cross-linked from the mouse-story section (3.10). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…r + hover ⊕ gutter button Comments were already line-anchored by design; state it explicitly: the comment verb follows the same ladder as every verb (line / range / hunk / file), single-line is the base case, anchors are stored at line granularity and never widened to the hunk. Adds the direct mouse path — hovering any diff line reveals a ⊕ gutter button that opens the composer anchored to exactly that line — and lists it in the mouse story. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…le, mark-and-collapse States explicitly that the flat stream reviewed top-to-bottom is the main flow the design optimizes (commits lens, history, zoom are secondary). Marking a file reviewed now collapses it in place to its one-line header, GitHub-style, so the stream shrinks into a to-do list as you scroll; the sticky file header carries the file's own Reviewed button and fold triangle so scroll-and-mark never leaves the stream; Space on a file header or last hunk marks and collapses the whole file and advances to the next unreviewed file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…of reviewed - Reviewing a specific GitHub PR joins Part I as a primary scope: a PR picker (review-requested first, filterable) reachable from the preset row or by typing a PR number/URL; selection fetches refs/pull/N/head with no checkout, scopes to merge-base(PR base) -> PR head, imports existing threads as author-badged anchored comments, and C conclude becomes submit-to-GitHub with verdict choice, summary, and the draft list (severities rendered into comment bodies). Force-pushes surface as the interdiff pseudo-commit instead of a reset review. Part II 4.4 narrows to the deeper sync (thread replies/resolution, live updates, viewed-state sync). - Collapsed and reviewed are now explicitly independent states: the fold triangle collapses without marking (no checkmark, still unreviewed in the gauge and Space order); marking auto-collapses; unfolding never unmarks; both persist independently per scope across sittings. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…tor integration Answers the two open questions on the PR flow: Checkout: a PR review never switches the user's working tree. Tier 0 (default) reviews entirely from fetched git objects — reading, marks, comments, and submit need no checkout; Enter opens read-only file-at-PR-head buffers. Tier 1 materializes a linked review worktree on demand (scope-bar button, or offered at depth boundaries like LSP, edit, run-tests) using the orchestrator's worktree machinery; the workspace-trust prompt fires at materialization — when code could first run, not when reading. Review state is keyed to PR identity (repo + number + head-sha versions), never worktree paths, so materialization and force-pushes carry marks forward. Orchestrator: one worktree engine, one dock. A materialized PR review is a workspace with a dock card (progress + checks) and normal lifecycle; the PR picker and scope bar reuse the orchestrator's PR metadata plumbing; an agent session with an attached PR is the same review seen from two bases (merge-base vs session-start) via the scope-bar flip; the reverse door (hand must-fix comments to an agent in the same worktree) stays Part II. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…rries the flows - The scope chooser shrinks to four rows and a prompt: the context-aware star row (this session's changes in an agent workspace / branch vs base on a feature branch, resuming since-my-last-review by default), working tree, pull requests, history. Stashes, ranges, and single commits are revspecs, not rows. Agent-session rows are gone from the chooser: reviewing an agent's work means clicking its dock card and opening Review there — the dock is the cross-workspace review inbox (waiting-on-you ordering and progress badges live on the cards). - PR selection rides the orchestrator: if the PR branch is checked out in this workspace the review opens in place; otherwise a direct offer — 'Checkout in a new workspace' (primary: standard worktree + trust flow, review opens inside, dock card appears) or 'Read here without checkout' (objects-only quick look; depth boundaries re-offer checkout). 'Materialize' terminology dropped for plain 'checkout'. - Removed cross-session cycling keys; walkthrough, phases, and rename table updated to the workspace-local model. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
Adds unified-diff-experience-implementation-plan.md: milestones M0-M6 mapping the design onto this codebase — what each builds on (audit_mode, git_log, live_diff, composite buffer, orchestrator, scene projections), the short list of new host primitives (overlay layering, inline actionable spans, sticky rows, rebindable composite Actions, per-hunk streaming with cancellation, ref recording), per-milestone exit criteria, cross-cutting workstreams (keybindings, testing, i18n, perf), and the risk/sequencing picture. Removes the raw third-party research dumps a previous session left in docs/ (zed-git.md, zed-agent-panel.md, gitlens-readme.md) — their relevant conclusions are already distilled into the design doc's research section; only project-specific material stays in the repo. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…t toolkit Investigated the widget framework (17 WidgetSpec kinds, host-owned instance state, hit areas, keyboard+mouse dispatch, Settings already migrated onto it) and the buffer decoration APIs before committing to new host work. Findings change the build: - Chrome (scope bar, chooser, rail, verb rows, transients, banners) maps onto existing widgets — click targets, hover/focus, retained state and web parity come free. Building it the audit_mode way (Raw panel content + byte-offset mouse_click math) would repeat what the git_log migration called the most error-prone part of that plugin. - The diff stream should be a real editor buffer (WindowEmbed or buffer-group center panel), not panel content: syntax highlighting, folds, scrollbar markers, selection and search then come free, exactly as git_log already does with .diff-suffixed file-backed buffers. Primitives re-scored: overlay-priority downgraded from API to rendering strategy (fgOnCollisionOnly and extendToLineEnd already exist); sticky rows dropped (audit_mode already ships a sticky panel slot); ref recording dropped (plugins spawn git directly); inline actionable spans kept but confined to in-diff-body affordances, and reduced to consuming InlineOverlay.properties, which the data model already declares as click target metadata but nothing reads; composite-key Actions and streaming cancellation unchanged. Net: one new host capability instead of six. Milestones, web-parity scope and the risk section updated accordingly, with an M1 spike added to choose stream hosting. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…away The default view is now the diff at full width: the navigator rail starts collapsed behind a visible scope-bar toggle, so opening a review lands straight on the thing the user came for. Clicking it expands, and the choice persists per scope. Adds the collapsed default frame alongside the expanded one, states progressive disclosure as the workspace-wide rule (nothing hidden behind a key you must know), and updates the mouse-only walkthrough to open collapsed and demonstrate the toggle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
…ghlighting claim Read audit_mode's implementation before planning its replacement, and corrected a wrong assumption in the process: - Correction: rendering the stream from a .diff file-backed buffer gives diff-level scoping only, NOT per-token language highlighting. The embedded-region mechanism (EMBEDDING_SPECS) is a build-time table keyed on host-grammar scopes and can't be driven by a plugin, and its language token is a language name, not a path. Per-token highlighting in a composed unified stream therefore needs one narrow, scheduled host addition (per-byte-range language regions reusing the engine's composite parse snapshots), now listed as primitive #7 and deferred to M2; M0 ships only the cheap add/remove backgrounds. - New section 4 records what must survive the migration: the single-pass build that emits rows, byte offsets, row-property maps and collapsible body ranges together; collapse as O(1) host fold registration with no rebuild; the plugin-side entryPropsByRow map (which exists to dodge a real getTextPropertiesAtCursor row-boundary bug); width-parameterised prebuild; the guarded sticky-header repaint; manual-refresh policy (auto-refresh on activation was removed for spawning git per panel switch); streamed SHA-cached git show. Plus the port-don't-rewrite list (staging engine with apply --cached and --check dry run, comment model and persistence, range/stash pipelines, repo resolution, i18n, e2e suites) and an explicit list of APIs considered and rejected because existing mechanisms cover them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
… plan's inventory The section 1 row for git_log still described its .diff buffer as having real syntax highlighting, which the section 2 correction contradicts — it is diff-level scoping only. Aligns the wording and repoints the row's role at what git_log actually contributes: the streaming/SHA-cache pattern the commits lens reuses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds comprehensive research and reference documentation to inform the design of Fresh's diff and review experience. Three new documents are added:
unified-diff-experience-design.md— A detailed design specification and research synthesis for consolidating Fresh's seven fragmented diff surfaces into one coherent review experiencegitlens-readme.md— Reference documentation from GitLens (VS Code extension) showing patterns for Git integration and PR review workflowszed-git.mdandzed-agent-panel.md— Reference documentation from Zed editor demonstrating modern approaches to diff viewing, staging, agent integration, and multi-threaded AI workflowsKey Changes
Design specification (
unified-diff-experience-design.md):External tool references:
Notable Details
This is a design and research document only — no code changes to Fresh itself. It serves as the specification for future implementation phases.
https://claude.ai/code/session_01756Rh35n65zC4xHQcQAqBL