Add crit command and skill for inline code review
Sourced from https://github.com/tomasz-tomczyk/crit/tree/main/integrations/claude-code Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b4c0ee954d
commit
4fac18c165
2 changed files with 282 additions and 0 deletions
122
.claude/commands/crit.md
Normal file
122
.claude/commands/crit.md
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
---
|
||||
description: "Review code changes or a plan with crit inline comments"
|
||||
allowed-tools: Bash(crit:*), Bash(command ls:*), Read, Edit, Glob
|
||||
---
|
||||
|
||||
# Review with Crit
|
||||
|
||||
Review and revise code changes or a plan using `crit` for inline comment review.
|
||||
|
||||
## Step 1: Determine review mode
|
||||
|
||||
Choose what to review based on context:
|
||||
|
||||
1. **User argument** - if the user provided `$ARGUMENTS` (e.g., `/crit my-plan.md`), review that file
|
||||
2. **Recent plan** - if no argument, check if a plan was written earlier in this conversation. If so, review that file with `crit <plan-file>`
|
||||
3. **Branch review** - otherwise, run `crit` with no arguments. It auto-detects what to review: uncommitted changes, or all changes on the current branch vs the default branch. Works on clean branches too.
|
||||
|
||||
Don't ask for confirmation — just proceed with whichever mode applies.
|
||||
|
||||
## Step 2: Launch crit and block until review completes
|
||||
|
||||
**CRITICAL — you MUST run this step. Do NOT skip it. Do NOT proceed without it.**
|
||||
|
||||
If a crit server is already running from earlier in this conversation, `crit` will automatically connect to it — no need to track ports or skip steps.
|
||||
|
||||
Run `crit` **in the background** using `run_in_background: true`:
|
||||
|
||||
```bash
|
||||
# For a specific file:
|
||||
crit <plan-file>
|
||||
|
||||
# For git mode (no args):
|
||||
crit
|
||||
```
|
||||
|
||||
This starts the daemon if needed (or connects to an existing one), opens the browser, and blocks until the user clicks "Finish Review". Feedback is printed to stdout when it exits.
|
||||
|
||||
Tell the user: **"Crit is open in your browser. Leave inline comments, then click Finish Review."**
|
||||
|
||||
**Do NOT proceed until `crit` completes.** Do NOT ask the user to type anything. Do NOT read `.crit.json` early. Wait for the background task to finish — that is how you know the human is done reviewing.
|
||||
|
||||
## Step 3: Read the review output
|
||||
|
||||
When `crit` completes, read the `.crit.json` file in the repo root (or working directory) using the Read tool.
|
||||
|
||||
The file contains structured JSON with comments per file:
|
||||
|
||||
```json
|
||||
{
|
||||
"files": {
|
||||
"plan.md": {
|
||||
"comments": [
|
||||
{ "id": "c1", "start_line": 5, "end_line": 10, "body": "Clarify this step", "quote": "specific words", "resolved": false }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Identify all comments where `"resolved": false` or where the `resolved` field is missing (missing means unresolved). If a comment has a `"quote"` field, it contains the specific text the reviewer selected — focus your changes on the quoted text rather than the entire line range.
|
||||
|
||||
## Step 4: Address each review comment
|
||||
|
||||
For each unresolved comment:
|
||||
|
||||
1. Understand what the comment asks for (clarification, change, addition, removal)
|
||||
2. If a comment contains a suggestion block, apply that specific change
|
||||
3. Revise the **referenced file** to address the feedback - this could be the plan file or any code file from the git diff
|
||||
4. Use the Edit tool to make targeted changes
|
||||
5. Reply to the comment with what you did: `crit comment --reply-to <id> --resolve --author 'Claude Code' '<what you did>'`
|
||||
|
||||
When addressing multiple comments, use `--json` to resolve them all in one call:
|
||||
|
||||
```bash
|
||||
echo '[
|
||||
{"reply_to": "c1", "body": "Fixed", "resolve": true},
|
||||
{"reply_to": "c2", "body": "Refactored as suggested", "resolve": true}
|
||||
]' | crit comment --json --author 'Claude Code'
|
||||
```
|
||||
|
||||
Editing the plan file triggers Crit's live reload - the user sees changes in the browser immediately.
|
||||
|
||||
**If there are zero review comments**: inform the user no changes were requested and stop the background `crit` process.
|
||||
|
||||
## Step 5: Signal completion and start next round
|
||||
|
||||
**CRITICAL — you MUST run this step. Do NOT skip it. Do NOT proceed without it.**
|
||||
|
||||
Run the **exact same `crit` command from Step 2** in the background using `run_in_background: true`. This is critical — if you launched `crit plan.md` in Step 2, you must run `crit plan.md` again here (not bare `crit`). The daemon is keyed by the arguments, so mismatched args will start a new daemon instead of reconnecting.
|
||||
|
||||
```bash
|
||||
# Must match Step 2 exactly:
|
||||
crit <same-args-as-step-2>
|
||||
```
|
||||
|
||||
On subsequent calls, `crit` automatically signals round-complete first, then blocks again until the next "Finish Review" click.
|
||||
|
||||
Tell the user: **"Changes applied. Review the diff in your browser and click Finish Review when ready."**
|
||||
|
||||
**Do NOT proceed until `crit` completes.** When it does, go back to Step 3. If the user finishes with zero comments, the review is approved — stop the loop and proceed.
|
||||
|
||||
## Sharing
|
||||
|
||||
If the user asks for a URL, a link, to share the review, or to show a QR code, run:
|
||||
|
||||
```bash
|
||||
crit share <file>
|
||||
```
|
||||
|
||||
**Always relay the full output to the user** — copy the URL (and QR code if `--qr` was used) from the command output and include it directly in your response. Do not make them dig through tool output to find it.
|
||||
|
||||
To also show a QR code — **only in real terminal environments** with monospace font rendering (not mobile apps like Claude Code mobile, or web chat UIs where Unicode block characters won't render):
|
||||
|
||||
```bash
|
||||
crit share --qr <file>
|
||||
```
|
||||
|
||||
To remove a shared review:
|
||||
|
||||
```bash
|
||||
crit unpublish
|
||||
```
|
||||
160
.claude/skills/crit-cli/SKILL.md
Normal file
160
.claude/skills/crit-cli/SKILL.md
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
---
|
||||
name: crit-cli
|
||||
description: Use when working with crit CLI commands, .crit.json files, addressing review comments, leaving inline code review comments, sharing reviews via crit share/unpublish, pushing reviews to GitHub PRs, or pulling PR comments locally. Covers crit comment, crit share, crit unpublish, crit pull, crit push, .crit.json format, and resolution workflow.
|
||||
---
|
||||
|
||||
# Crit CLI Reference
|
||||
|
||||
> If a plan was just written and the user said `/crit` or `crit`, invoke the `/crit` command — do not use this reference skill. This skill covers CLI operations like `crit comment`, `crit pull/push`, and `crit share`.
|
||||
|
||||
## .crit.json Format
|
||||
|
||||
After a crit review session, comments are in `.crit.json`. Comments are grouped per file with `start_line`/`end_line` referencing the source:
|
||||
|
||||
```json
|
||||
{
|
||||
"files": {
|
||||
"path/to/file.md": {
|
||||
"comments": [
|
||||
{
|
||||
"id": "c1",
|
||||
"start_line": 5,
|
||||
"end_line": 10,
|
||||
"body": "Comment text",
|
||||
"quote": "the specific words selected",
|
||||
"author": "User Name",
|
||||
"resolved": false,
|
||||
"replies": [
|
||||
{ "id": "c1-r1", "body": "Fixed by extracting to helper", "author": "Claude" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Reading comments
|
||||
|
||||
- Comments are grouped per file with `start_line`/`end_line` referencing source lines in that file
|
||||
- `quote` (optional): the specific text the reviewer selected — narrows the comment's scope within the line range. When present, focus your changes on the quoted text rather than the entire line range
|
||||
- `resolved`: `false` or **missing** — both mean unresolved. Only `true` means resolved.
|
||||
- Address each unresolved comment by editing the relevant file at the referenced location
|
||||
|
||||
### Resolving comments
|
||||
|
||||
After addressing a comment, reply to it using the CLI:
|
||||
|
||||
```bash
|
||||
crit comment --reply-to c1 --resolve --author 'Claude Code' 'Fixed by extracting to helper'
|
||||
```
|
||||
|
||||
This adds a reply to the comment thread and marks it resolved. You can also reply without resolving (omit `--resolve`) if discussion is ongoing.
|
||||
|
||||
## Leaving Comments with crit comment CLI
|
||||
|
||||
Use `crit comment` to add inline review comments to `.crit.json` programmatically — no browser needed:
|
||||
|
||||
```bash
|
||||
# Single line comment
|
||||
crit comment --author 'Claude Code' <path>:<line> '<body>'
|
||||
|
||||
# Multi-line comment (range)
|
||||
crit comment --author 'Claude Code' <path>:<start>-<end> '<body>'
|
||||
|
||||
# Reply to an existing comment (with optional --resolve)
|
||||
crit comment --reply-to <id> --author 'Claude Code' '<body>'
|
||||
crit comment --reply-to <id> --resolve --author 'Claude Code' '<body>'
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
crit comment --author 'Claude Code' src/auth.go:42 'Missing null check on user.session — will panic if session expired'
|
||||
crit comment --author 'Claude Code' src/handler.go:15-28 'This error is swallowed silently'
|
||||
crit comment --reply-to c1 --resolve --author 'Claude Code' 'Added null check on line 42'
|
||||
```
|
||||
|
||||
Rules:
|
||||
- **Always use `--author 'Claude'`** (or your agent name) so comments are attributed correctly
|
||||
- **Always use single quotes** for the body — double quotes will break on backticks and special characters
|
||||
- **Paths** are relative to the current working directory
|
||||
- **Line numbers** reference the file as it exists on disk (1-indexed), not diff line numbers
|
||||
- **Comments are appended** — calling `crit comment` multiple times adds to the list, never replaces
|
||||
- **No setup needed** — `crit comment` creates `.crit.json` automatically if it doesn't exist
|
||||
- **Do NOT run `crit` after leaving comments** — that triggers a new review round
|
||||
|
||||
### Bulk commenting (recommended for multiple comments)
|
||||
|
||||
When leaving 3+ comments, use `--json` to add them all in one atomic operation:
|
||||
|
||||
```bash
|
||||
echo '[
|
||||
{"file": "src/auth.go", "line": 42, "body": "Missing null check"},
|
||||
{"file": "src/auth.go", "line": 50, "end_line": 55, "body": "Extract to helper"},
|
||||
{"file": "src/handler.go", "line": 10, "body": "Swallowed error"}
|
||||
]' | crit comment --json --author 'Claude Code'
|
||||
```
|
||||
|
||||
Replies and resolves work too:
|
||||
|
||||
```bash
|
||||
echo '[
|
||||
{"reply_to": "c1", "body": "Fixed — added null check", "resolve": true},
|
||||
{"reply_to": "c2", "body": "Extracted to validateSession()"}
|
||||
]' | crit comment --json --author 'Claude Code'
|
||||
```
|
||||
|
||||
JSON schema per entry:
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `file` | string | yes (new comment) | Relative file path |
|
||||
| `line` | int | yes (new comment) | Start line (1-indexed) |
|
||||
| `end_line` | int | no | End line (defaults to `line`) |
|
||||
| `body` | string | yes | Comment text |
|
||||
| `author` | string | no | Per-entry override (falls back to `--author`) |
|
||||
| `reply_to` | string | yes (reply) | Comment ID to reply to (e.g. `"c1"`) |
|
||||
| `resolve` | bool | no | Mark the parent comment resolved |
|
||||
|
||||
Benefits over individual `crit comment` calls:
|
||||
- **Atomic** — one write to `.crit.json`, no partial state
|
||||
- **Faster** — single process invocation instead of N
|
||||
- **Safer** — no race conditions with concurrent crit processes
|
||||
|
||||
## GitHub PR Integration
|
||||
|
||||
```bash
|
||||
crit pull [pr-number] # Fetch PR review comments into .crit.json
|
||||
crit push [--dry-run] [--event <type>] [-m <msg>] [pr] # Post .crit.json comments as a GitHub PR review
|
||||
```
|
||||
|
||||
Requires `gh` CLI installed and authenticated. PR number is auto-detected from the current branch, or pass it explicitly.
|
||||
|
||||
Event types for `--event`: `comment` (default), `approve`, `request-changes`. Use `-m` to add a review-level body message.
|
||||
|
||||
## Sharing Reviews
|
||||
|
||||
If the user asks for a URL, a link, to share their review, or to show a QR code, use `crit share`:
|
||||
|
||||
```bash
|
||||
crit share <file> [file...] # Upload and print URL
|
||||
crit share --qr <file> # Also print QR code (terminal only)
|
||||
crit unpublish # Remove shared review
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
crit share <file> # Share a single file
|
||||
crit share <file1> <file2> # Share multiple files
|
||||
crit share --share-url https://crit.md <file> # Explicit share URL
|
||||
```
|
||||
|
||||
Rules:
|
||||
- **No server needed** — `crit share` reads files directly from disk
|
||||
- **`--qr` is terminal-only** — only use when the user has a real terminal with monospace font rendering. Do not use in mobile apps (e.g. Claude Code mobile), web chat UIs, or any environment where Unicode block characters won't render correctly
|
||||
- **Comments included** — if `.crit.json` exists, comments for the shared files are included automatically
|
||||
- **Relay the output** — always copy the URL (and QR code if `--qr` was used) from the command output and include it directly in your response to the user. Do not make them dig through tool output
|
||||
- **State persisted** — share URL and delete token are saved to `.crit.json`
|
||||
- **Unpublish reads `.crit.json`** — uses the stored delete token to remove the review
|
||||
Loading…
Add table
Add a link
Reference in a new issue