Skip to content

Review surface: protocol-level worktree diff + hunk comments that feed back to the agent #250

Description

@saucam

Problem

Codeoid runs agents unattended — autonomous mode, worktree-per-session, the conductor spawning workers through the dispatch queue — but there is no way to see what an agent actually changed without leaving codeoid for a terminal or an IDE.

grep -rn diff src/ today hits only compress/rules/shell.ts, compress/registry.ts and context-math.ts: we know how to compress git diff output to save tokens, but we never show it to the human. For a control plane whose premise is "the agent works while you're away," the review half of the loop is missing.

This is the clearest functional gap surfaced by the Superset comparison (docs/COMPARISON.md): their editable diff viewer + PR status is the most-used surface in an agent IDE, and we have nothing in that row.

Why this is a protocol feature, not a UI feature

The tempting move is "add a diff view to the web UI." That would be the wrong layer.

The daemon already owns the worktree (daemon/git-worktree.ts, worktree.ts) and already shells out to git. If the daemon computes the diff and streams it structured over the protocol, then the TUI, the web UI, Telegram, and the mobile client all get review from one implementation — consistent with "daemon owns all state; clients are pure renderers."

That is also a real advantage over Superset, whose diff viewer is Electron-only and therefore unreachable from a phone.

Proposed scope

Daemon

  • session.diff → structured diff for the session's worktree: per-file status, hunks, line stats, plus a summary (files changed / +/-). Computed server-side against the session's base ref.
  • session.diff_file → hunks for one path, for lazy loading on large changes.
  • Invalidate/notify on worktree change so an attached client sees the diff update as the agent works (the fs watching primitives exist for memory indexing already).
  • Large-diff discipline: reuse the byte-budget chunking already proven in scrollback.ts (readChunked / #partition) rather than inventing a second framing scheme. A 10k-line diff must not blow the WS outbound limit (fix: scrollback replay frame can exceed WS backpressure limit and lock clients out of large sessions #84 class).

Protocol (packages/protocol)

  • New request/response + event types, with zod schemas in schemas.ts.
  • Reads ride the existing session:read scope. Write actions (stage / commit / push / PR create) must not: they need their own scope and must be attributed in audit_log.

The differentiating bit: comments feed back to the agent
In Superset, diff comments are for humans. In codeoid a comment on a hunk should be able to become a prompt to the session that produced itfile:line + the comment + the hunk injected as the next user turn. That closes the loop inside the control plane instead of sending the user to a PR to write the same sentence again.

PR surface
Shell out to gh for PR create + status, the way fleet.ts already uses execFile. No GitHub API client, no new auth.

Frontends
Web UI first (web/src). TUI after. Telegram gets the summary + per-file stats, not the hunks.

Non-goals

  • Not an editable diff. Codeoid is not an IDE; the Inline IDE code actions row in COMPARISON.md says "not our niche" and that stays true. Read, comment, approve, commit — the agent does the editing.
  • No syntax-highlighted three-way merge UI, no conflict resolution.
  • No replacement for gh pr view / the GitHub web UI on the PR itself.

Open questions

  1. What is the base ref for the diff — worktree base branch, session start commit, or last-reviewed commit? "What changed since I last looked" is probably the most useful default and needs a stored per-session review watermark.
  2. Where do comments live — transcript entries, a new table in store.ts, or ephemeral until sent to the agent?
  3. Does the conductor get a read-only diff tool (FLEET_TOOL_NAMES) so it can summarize worker output without raw scrollback? Likely yes, and it fits the never-OOC rule since a diff is a digest by nature.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions