Skip to content

vscode: viewSpecDiff / viewPlanDiff — side-by-side diff of current vs prior revision for spec/plan files #858

Description

@amrmelsayed

Problem

When a builder iterates on a spec or plan in response to review feedback, the architect has no efficient way to see what changed since the last review. They re-read the entire document hunting for the deltas, or open the file in two windows manually. For long specs / plans (which is common — spec docs routinely cross 200 lines), this is a real friction tax on the review-iterate-review loop.

GitHub's PR review UX has this for code. Codev's review-iterate loop for design docs doesn't.

Current state

  • codev.viewPlanFile exists (commands/view-artifact.ts:29), restricted to PIR builders (per vscode: generalize viewPlanFile to siblings (viewSpecFile, viewReviewFile) with protocol-aware menu visibility #793 which generalizes to spec / review too).
  • The view-artifact commands open the file in the normal editor — no diff surface.
  • codev.viewDiff exists for the code diff of a builder's branch (commands/view-diff.ts), but it's all-or-nothing on the worktree's git diff and doesn't target spec/plan files specifically.
  • Builders edit specs/plans on their branch; each iteration is a git commit on the builder branch. The history of revisions is available via git.

Proposed behavior

Two new commands, parallel to the existing viewSpecFile / viewPlanFile (per #793):

  • codev.viewSpecDiff — opens a side-by-side diff for the builder's spec file
  • codev.viewPlanDiff — same for the plan file

Backed by VS Code's built-in vscode.diff command, which takes two URIs and renders the standard side-by-side diff editor with syntax highlighting and inline change markers.

Surfaces

Which two revisions to compare?

This is the load-bearing design call. Three options, each with a different mental model:

Option Compare Pro Con
A. vs last-approved Current file on builder branch vs the file at the commit when the spec/plan was last approved Matches review semantics: 'what's new since I approved' Requires tracking the approval commit (porch state or git tag); falls back to option B if no prior approval
B. vs HEAD-before-current-revision Current file vs the file at the previous commit that touched it on the builder branch Trivial to implement: just git log -2 --format=%H -- <path>; always works Shows every micro-commit, not the meaningful 'since I last reviewed' delta
C. vs initial-spawn Current file vs the file at builder branch creation Shows the cumulative state of all iteration Conflates 'what the builder wrote initially' with 'what they iterated' — usually too coarse

Recommendation: A with B as fallback. Track the last spec-approval / plan-approval gate commit in porch state; default to that. If no prior approval (first review pass), fall back to B. C is rarely what you want.

Alternative: ship B first as the v1 (zero porch-state changes), iterate to A in a follow-up once the UX is validated. This is the lower-risk path.

Implementation sketch

// codev/commands/view-artifact-diff.ts (new file alongside view-artifact.ts)
async function viewArtifactDiff(connectionManager, builderIdArg, kind) {
  const builder = resolveBuilder(connectionManager, builderIdArg);
  const filePath = artifactPathFor(builder, kind);
  if (!fileExists(filePath)) { return; }

  const baseCommit = await resolveBaseCommit(builder, kind);  // option A → approval commit; option B → prior commit
  if (!baseCommit) { return; }

  const headUri = vscode.Uri.file(filePath);
  const baseUri = vscode.Uri.parse(`git:${filePath}?${baseCommit}`);  // VS Code's built-in git URI scheme

  await vscode.commands.executeCommand(
    'vscode.diff',
    baseUri, headUri,
    `${path.basename(filePath)}${kind} since last revision`,
  );
}

Touch points:

Acceptance criteria

  • codev.viewSpecDiff registered; visible in palette + Builders row context menu (where the builder has a spec file)
  • codev.viewPlanDiff registered; visible in palette + Builders row context menu (where the builder has a plan file)
  • Invoking either opens VS Code's native side-by-side diff editor (left = base revision, right = current)
  • Base-revision selection works per the chosen option (A / B / fallback chain)
  • No regression to existing codev.viewSpecFile / codev.viewPlanFile / codev.viewReviewFile commands
  • (If CodeLens path included) CodeLens appears only on files inside codev/specs/ or codev/plans/; doesn't appear on unrelated .md files

Out of scope

  • Diff for codev/reviews/*.md files (different workflow — review files iterate less and the value is lower; can be added in a follow-up if needed)
  • Inline comment threading on the diff view itself (VS Code's diff editor doesn't support arbitrary inline comments; the Comments API works on the file editor, not the diff editor)
  • 3-way diff (intentionally — 2-way matches the review mental model)
  • A revision picker UI ('compare against revision N') — single base per the chosen option

Dependencies

Design call to make at spec time

Pick the option (A / B / C / A-with-B-fallback) for base-revision selection. Recommendation in the table above.

Metadata

Metadata

Assignees

Labels

area/vscodeArea: VS Code extension

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions