From e872aeef8efeab271603e0def649638319af92dd Mon Sep 17 00:00:00 2001 From: "Fredrik Liljegren (Claude Code Claude Opus 5)" Date: Fri, 21 Aug 2026 13:50:38 +0200 Subject: [PATCH] feat(cli): --repo, and teach the review skill to find the repository and the PR Two things stopped "review my current draft PR" from working from where people actually stand. A project directory often holds several worktrees as subdirectories rather than being a repository itself, so the command was run outside any repository and failed with "Not a git repository". --repo selects one; everything downstream already resolves against the working directory, so the option only has to move it. The skills now look one level down for repositories and ask which one when there is more than one, rather than guessing. A bare review also defaulted to working-tree changes, which on a branch whose work is committed is an empty diff - exactly the case when reviewing your own draft before marking it Ready. With no ref the skill now asks GitHub whether the branch has a pull request and reviews that, which pins the diff to the pull request's base commit. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_018PkYQzbsnMihHesafWvXKs --- packages/cli/src/index.ts | 24 ++++++++++++++++++ packages/skills/diffity-resolve/SKILL.md | 10 +++++++- packages/skills/diffity-review/SKILL.md | 31 +++++++++++++++++++++++- skills/diffity-resolve/SKILL.md | 10 +++++++- skills/diffity-review/SKILL.md | 31 +++++++++++++++++++++++- 5 files changed, 102 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 62f81f7..fedb3ff 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,5 +1,7 @@ import { Command } from 'commander'; import { createHash } from 'node:crypto'; +import { existsSync, statSync } from 'node:fs'; +import { resolve } from 'node:path'; import { createRequire } from 'node:module'; import open from 'open'; import pc from 'picocolors'; @@ -31,6 +33,27 @@ const pkg = require('../package.json'); const program = new Command(); +// Project directories often hold several worktrees as subdirectories, so the repository to +// review is not always the directory the command was run from. Everything downstream resolves +// against the working directory, so switching it here is enough. +function applyRepoOption(repo: unknown): void { + if (typeof repo !== 'string' || !repo) { + return; + } + + const target = resolve(repo); + if (!existsSync(target) || !statSync(target).isDirectory()) { + console.error(pc.red(`Error: --repo is not a directory: ${repo}`)); + process.exit(1); + } + + process.chdir(target); +} + +program.hook('preAction', (thisCommand) => { + applyRepoOption(thisCommand.opts().repo); +}); + program .name('diffity') .description('GitHub-style git diff viewer in the browser') @@ -38,6 +61,7 @@ program .enablePositionalOptions() .passThroughOptions() .option('--skills-hash', 'Print skills hash and exit', false) + .option('--repo ', 'Repository to work on, when the current directory is not one') .argument('[refs...]', 'Git refs to diff') .option('--base ', 'Base ref to compare from (e.g. main, HEAD~3, v1.0.0)') .option('--compare ', 'Ref to compare against base (default: working tree)') diff --git a/packages/skills/diffity-resolve/SKILL.md b/packages/skills/diffity-resolve/SKILL.md index 1dc6e08..e8a7521 100644 --- a/packages/skills/diffity-resolve/SKILL.md +++ b/packages/skills/diffity-resolve/SKILL.md @@ -33,7 +33,15 @@ You are reading open review comments and resolving them by making the requested ## Prerequisites 1. Check that `{{binary}}` is available: run `which {{binary}}`. If not found, {{install_hint}}. -2. Check that a review session exists: run `{{binary}} agent list`. If this fails with "No active review session", tell the user to start diffity first (e.g. `{{binary}}` or **{{slash}}diff**). +2. **Work out which repository to use.** A project directory often holds several worktrees as + subdirectories rather than being a repository itself, so the current directory may not be one. + - If the current directory is a git repository (`git rev-parse --show-toplevel` succeeds), use it. + - Otherwise look one level down for directories containing a `.git` entry. Exactly one → use it. + Several → **ask the user which one**, listing them with their current branch, and stop until + they answer. Guessing here reviews the wrong branch, which wastes the whole review. + - Pass the chosen directory to every `{{binary}}` call as `--repo `, before any positional + argument. Do not `cd`. +3. Check that a review session exists: run `{{binary}} agent list`. If this fails with "No active review session", tell the user to start diffity first (e.g. `{{binary}}` or **{{slash}}diff**). ## Instructions diff --git a/packages/skills/diffity-review/SKILL.md b/packages/skills/diffity-review/SKILL.md index 786a7ca..cbb19ae 100644 --- a/packages/skills/diffity-review/SKILL.md +++ b/packages/skills/diffity-review/SKILL.md @@ -10,7 +10,10 @@ You are reviewing a diff and leaving inline comments using the `{{binary}} agent ## Arguments -- `ref` (optional): Git ref to review (e.g. `main..feature`, `HEAD~3`). Defaults to working tree changes. When both `ref` and `focus` are provided, use both (e.g. `/diffity-review main..feature security`). +- `ref` (optional): Git ref to review (e.g. `main..feature`, `HEAD~3`). When both `ref` and `focus` are provided, use both (e.g. `/diffity-review main..feature security`). + With no `ref`, review **the pull request for the current branch** if there is one, and the working + tree otherwise — see Step 0. "Review my draft PR" with everything committed means the pull + request, not the empty set of uncommitted changes. - `focus` (optional): Focus the review on a specific area. One of: `security`, `performance`, `naming`, `errors`, `types`, `logic`. If omitted, review everything. ## CLI Reference @@ -38,9 +41,35 @@ You are reviewing a diff and leaving inline comments using the `{{binary}} agent ## Prerequisites 1. Check that `{{binary}}` is available: run `which {{binary}}`. If not found, {{install_hint}}. +2. **Work out which repository to use.** A project directory often holds several worktrees as + subdirectories rather than being a repository itself, so the current directory may not be one. + - If the current directory is a git repository (`git rev-parse --show-toplevel` succeeds), use it. + - Otherwise look one level down for directories containing a `.git` entry. Exactly one → use it. + Several → **ask the user which one**, listing them with their current branch, and stop until + they answer. Guessing here reviews the wrong branch, which wastes the whole review. + - Pass the chosen directory to every `{{binary}}` call as `--repo `, before any positional + argument. Do not `cd`. + ## Instructions +### Step 0: Decide what to review + +Only when no `ref` argument was given: + +1. Ask GitHub whether the current branch has a pull request: + ``` + gh pr view --json number,url,isDraft,baseRefName + ``` +2. If it returns one, **review the pull request**: use its URL as the ref + (`{{binary}} --repo --no-open `). diffity pins the diff to the pull request's base + commit, so it matches what GitHub shows — a plain working-tree diff on a branch whose work is + committed would be empty. A draft counts; that is the usual case for a review before marking it + Ready. +3. If there is no pull request, or `gh` is unavailable, review the working tree as before. + +State which one you chose in your first message, so the user can correct you cheaply. + ### Step 1: Ensure diffity is running for the correct ref (without opening browser) The review needs a running session whose ref matches the requested ref. A ref mismatch causes "file not in current diff" errors when adding comments. diff --git a/skills/diffity-resolve/SKILL.md b/skills/diffity-resolve/SKILL.md index 0512d4a..fedc72a 100644 --- a/skills/diffity-resolve/SKILL.md +++ b/skills/diffity-resolve/SKILL.md @@ -33,7 +33,15 @@ diffity agent reply --body "" ## Prerequisites 1. Check that `diffity` is available: run `which diffity`. If not found, install it with `npm install -g diffity`. -2. Check that a review session exists: run `diffity agent list`. If this fails with "No active review session", tell the user to start diffity first (e.g. `diffity` or **/diffity-diff**). +2. **Work out which repository to use.** A project directory often holds several worktrees as + subdirectories rather than being a repository itself, so the current directory may not be one. + - If the current directory is a git repository (`git rev-parse --show-toplevel` succeeds), use it. + - Otherwise look one level down for directories containing a `.git` entry. Exactly one → use it. + Several → **ask the user which one**, listing them with their current branch, and stop until + they answer. Guessing here reviews the wrong branch, which wastes the whole review. + - Pass the chosen directory to every `diffity` call as `--repo `, before any positional + argument. Do not `cd`. +3. Check that a review session exists: run `diffity agent list`. If this fails with "No active review session", tell the user to start diffity first (e.g. `diffity` or **/diffity-diff**). ## Instructions diff --git a/skills/diffity-review/SKILL.md b/skills/diffity-review/SKILL.md index d1eb2e7..8605ca0 100644 --- a/skills/diffity-review/SKILL.md +++ b/skills/diffity-review/SKILL.md @@ -10,7 +10,10 @@ You are reviewing a diff and leaving inline comments using the `diffity agent` C ## Arguments -- `ref` (optional): Git ref to review (e.g. `main..feature`, `HEAD~3`). Defaults to working tree changes. When both `ref` and `focus` are provided, use both (e.g. `/diffity-review main..feature security`). +- `ref` (optional): Git ref to review (e.g. `main..feature`, `HEAD~3`). When both `ref` and `focus` are provided, use both (e.g. `/diffity-review main..feature security`). + With no `ref`, review **the pull request for the current branch** if there is one, and the working + tree otherwise — see Step 0. "Review my draft PR" with everything committed means the pull + request, not the empty set of uncommitted changes. - `focus` (optional): Focus the review on a specific area. One of: `security`, `performance`, `naming`, `errors`, `types`, `logic`. If omitted, review everything. ## CLI Reference @@ -38,9 +41,35 @@ diffity agent tour-done --tour ## Prerequisites 1. Check that `diffity` is available: run `which diffity`. If not found, install it with `npm install -g diffity`. +2. **Work out which repository to use.** A project directory often holds several worktrees as + subdirectories rather than being a repository itself, so the current directory may not be one. + - If the current directory is a git repository (`git rev-parse --show-toplevel` succeeds), use it. + - Otherwise look one level down for directories containing a `.git` entry. Exactly one → use it. + Several → **ask the user which one**, listing them with their current branch, and stop until + they answer. Guessing here reviews the wrong branch, which wastes the whole review. + - Pass the chosen directory to every `diffity` call as `--repo `, before any positional + argument. Do not `cd`. + ## Instructions +### Step 0: Decide what to review + +Only when no `ref` argument was given: + +1. Ask GitHub whether the current branch has a pull request: + ``` + gh pr view --json number,url,isDraft,baseRefName + ``` +2. If it returns one, **review the pull request**: use its URL as the ref + (`diffity --repo --no-open `). diffity pins the diff to the pull request's base + commit, so it matches what GitHub shows — a plain working-tree diff on a branch whose work is + committed would be empty. A draft counts; that is the usual case for a review before marking it + Ready. +3. If there is no pull request, or `gh` is unavailable, review the working tree as before. + +State which one you chose in your first message, so the user can correct you cheaply. + ### Step 1: Ensure diffity is running for the correct ref (without opening browser) The review needs a running session whose ref matches the requested ref. A ref mismatch causes "file not in current diff" errors when adding comments.