Interactive Markdown reviewer with TUI. Add review comments at section level or line level using Conventional Comments and output structured feedback.
Formerly ccplan — see Migration from ccplan for upgrade instructions.
mise use -g github:koh-sh/commdgo install github.com/koh-sh/commd@latestDownload the latest release from the Releases page.
Display a Markdown file in a 2-pane TUI and add review comments to each section.
review is the default command, so the subcommand name can be omitted.
commd review path/to/document.md
# Same as above (review is the default command)
commd path/to/document.md
# Output review to a file
commd review --output file --output-path ./review.md document.md
# Output to stdout
commd review --output stdout document.md
# Review local git changes in diff view (working tree vs HEAD)
commd review --diff document.md
# Pick from all changed/untracked .md files, comparing against a branch
commd review --diff --base main| Flag | Description |
|---|---|
--output |
Output method: clipboard (default), stdout, file |
--output-path |
File path for --output file |
--theme |
Color theme: dark (default), light |
--track-viewed |
Persist viewed state to sidecar file (.reviewed.json) for change detection across sessions |
--diff |
Review local git changes in diff view. Without a file, pick from changed .md files |
--base |
Git ref to diff against (default: HEAD; requires --diff) |
When --track-viewed is enabled, commd saves which sections you've marked as viewed in a .reviewed.json sidecar file. On subsequent runs, viewed marks are restored automatically. If a section's content has changed, its viewed mark is cleared (detected via content hash).
--diff reviews what changed in the working tree instead of the whole file — for example, docs that Claude Code edited, before you commit them. It uses the same diff view as commd pr:
- The right pane opens in raw view showing the unified diff (
+/-lines); pressrfor the rendered working-tree content - Press
Tabto focus the diff pane, then comment on added, removed, or context lines withc/V; section comments work in the rendered view - Without a file argument, all changed and untracked
.mdfiles under the current directory are offered in a file picker and reviewed one by one; comments are combined into a single output - Untracked files are shown as entirely added; unchanged files are skipped
--track-viewedis not available in diff mode
Review Markdown files changed in a GitHub pull request. Comments are submitted as a GitHub PR Review with inline file comments.
# Interactive file picker for changed .md files
commd pr https://github.com/owner/repo/pull/123
# Review a specific file directly
commd pr https://github.com/owner/repo/pull/123 --file docs/README.md| Flag | Description |
|---|---|
--file |
Review a specific file instead of showing the file picker |
--theme |
Color theme: dark (default), light |
Authentication: Requires a GitHub token via GITHUB_TOKEN environment variable or gh auth login.
File size: The GitHub Contents API only decodes files up to 1 MB. Larger files (up to GitHub's 100 MB limit) are fetched automatically via their raw download URL.
File picker: When --file is not specified, an interactive file picker shows all changed .md files. All files are selected by default. Use space to toggle, a to select/deselect all, enter to confirm, q to cancel.
Review flow: After selecting files, you review them one by one. For each file you can add comments, then press s to finish or q to skip. After all files, a summary dialog lets you choose to approve, comment, or cancel the review.
Submit behavior: Comments are posted as a GitHub PR Review with inline comments on each file. If no comments are added, you can optionally approve the PR. Note: Overview (file-level) comments are not posted to GitHub due to API limitations — only section-level and line-level comments are submitted.
Show the current version.
commd version| Key | Action |
|---|---|
j / k / ↑ / ↓ |
Navigate sections (left pane) or lines (right pane, raw view) |
gg / G |
Jump to first / last |
Ctrl+D / Ctrl+U |
Half page down / up |
Ctrl+F / Ctrl+B |
Full page down / up |
l / h / → / ← |
Expand / collapse (left pane) / Scroll right / left (right pane) |
H / L |
Scroll to start / end (right pane) |
> / < |
Resize left pane wider / narrower |
Enter |
Toggle expand/collapse |
Tab |
Switch focus between panes |
f |
Toggle full view / section view |
r |
Toggle raw source view (with line numbers) / rendered view |
c |
Add comment (section-level in rendered view, line-level in raw view) |
C |
Manage comments (edit/delete) |
V |
Start visual line selection (raw view, right pane) |
v |
Toggle viewed mark |
/ |
Search sections |
s |
Submit review and exit |
q / Ctrl+C |
Quit |
? |
Show help |
| Key | Action |
|---|---|
Tab |
Cycle comment label (forward) |
Shift+Tab |
Cycle comment label (reverse) |
Ctrl+D |
Cycle decoration (none, non-blocking, blocking, if-minor) |
Ctrl+S |
Save comment |
Esc |
Cancel |
| Key | Action |
|---|---|
j / k |
Navigate comments |
e |
Edit selected comment |
d |
Delete selected comment |
Esc |
Back to normal mode |
The status bar shows key hints and a progress indicator: [X/Y viewed] for sections marked as viewed, and [N comments] when comments have been added.
| Key | Action |
|---|---|
| Type text | Incremental filter (searches ID, title, and body) |
j / k |
Navigate results |
Enter |
Confirm search |
Esc |
Cancel search |
Fenced ```mermaid code blocks are automatically converted to ASCII art in the detail pane. If rendering fails (e.g. unsupported diagram type), the original source is shown as-is.
Press r to switch the right pane to raw source view with line numbers. In this mode:
- Line-level commenting: Press
cto comment on the cursor line - Visual selection: Press
V, move withj/kto select a range, thencto comment. In diff mode (commd prand--diff), a selection spanning both sides is automatically restricted to the cursor's side (old or new file lines) to satisfy GitHub's single-side comment requirement - Section navigation:
j/kat the edge of a section automatically moves to the adjacent section - Press
fto toggle between section view (only selected section's lines) and full file view - Press
ragain to return to rendered view
Both section-level comments (from rendered view) and line-level comments (from raw view) can coexist in the same session.
The review output generated on submit uses Conventional Comments labels:
# Review
Please review and address the following comments on: /path/to/document.md
## Overview
[note] Add a performance metrics section.
## S1.1: JWT verification
[suggestion (non-blocking)] Switch to HS256. Load the key from an environment variable.
## S2: Update routing
[issue (blocking)] Not needed; the existing implementation covers this.
---
`L15` [question] Is this variable used?
> const token = parseToken(header)
`L20-L25` [suggestion] Extract this block into a helper function.
> if err := validate(input); err != nil {
> return err
> }Section-level comments (including Overview for the preamble) are grouped under section headings. Line-level comments appear below a --- divider with inline code line references, followed by a quote of the commented source (up to 5 lines) so the target can still be found after the file changes. In diff mode, comments on removed lines are numbered by the old file and marked (removed). When several files are reviewed with --diff, each file gets its own ## path heading with section headings nested below it.
Labels: suggestion, issue, question (default), nitpick, todo, thought, note, praise, chore
Decorations: non-blocking, blocking, if-minor — cycle with Ctrl+D in comment mode
commd can be used as a Claude Code hook to review plan files interactively during plan mode.
Run as a Claude Code hook. Launches the review TUI for the plan file to enable a feedback loop. Two trigger points are supported:
PreToolUseonExitPlanMode(recommended): fires once, when Claude has finished the plan and asks to leave plan mode. Claude Code injects the plan file path (tool_input.planFilePath), so noplansDirectorylookup is involved. Intermediate edits to the plan do not open a review.PostToolUseonWrite|Edit: fires on every write to a file underplansDirectory, including edits made before the plan is complete.
# Called automatically by Claude Code hook (no manual invocation needed)
commd cchook| Flag | Description |
|---|---|
--spawner |
Terminal multiplexer: auto (default), wezterm, tmux |
--theme |
Color theme: dark (default), light |
Note: Currently only WezTerm is supported as a terminal multiplexer spawner. tmux support is not yet implemented.
autowill try WezTerm first, then fall back to running in the same terminal.
Locate plan file paths from a Claude Code transcript JSONL. Useful for debugging the PostToolUse trigger's plansDirectory resolution; the PreToolUse/ExitPlanMode trigger receives the plan path directly and does not need it.
commd cclocate --transcript ~/.claude/projects/.../session.jsonl
# List all plan files found in a transcript
commd cclocate --transcript session.jsonl --all
# Read hook JSON input from stdin to resolve the plan file
commd cclocate --stdinAdd the following to .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "ExitPlanMode",
"hooks": [
{
"type": "command",
"command": "commd cchook",
"timeout": 600
}
]
}
]
}
}The hook only activates in plan mode and automatically enables --track-viewed. The review opens before Claude Code's own plan approval dialog:
- Claude writes the plan and calls
ExitPlanMode - commd opens the plan for review
- submitted (exit 2): the review is sent to Claude as the denial reason; Claude revises the plan in plan mode and calls
ExitPlanModeagain (back to step 2) - approved / cancelled (exit 0): Claude Code shows its usual plan approval dialog
To review on every plan file write instead (including intermediate edits), use the PostToolUse trigger. It requires the file to be under plansDirectory:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "commd cchook",
"timeout": 600
}
]
}
]
}
}Set CC_PLAN_REVIEW_SKIP=1 to temporarily disable the hook.
Dev tools are managed by mise. Run mise install to set up the toolchain (includes Go linters, formatters, and bun).
mise run ci # Run full CI pipeline (fmt, fix, lint, build, cov, e2e-basic)
mise run e2e # Run all E2E tests (full suite)
mise run e2e-basic # Run basic E2E tests (critical path only, included in ci)E2E tests use tuistory to drive the TUI in a virtual terminal.
commd was formerly known as ccplan. If you are upgrading:
| Item | Before | After |
|---|---|---|
| Binary | ccplan |
commd |
| Subcommand | ccplan review |
commd review |
| Subcommand | ccplan hook |
commd cchook |
| Subcommand | ccplan locate |
commd cclocate |
| Hook config | "command": "ccplan hook" |
"command": "commd cchook" |
| Environment variable | PLAN_REVIEW_SKIP=1 |
CC_PLAN_REVIEW_SKIP=1 |
| go install | github.com/koh-sh/ccplan |
github.com/koh-sh/commd |
| mise | github:koh-sh/ccplan |
github:koh-sh/commd |
For mise users upgrading:
mise uninstall github:koh-sh/ccplan
mise use -g github:koh-sh/commd