# shuire (朱入レ)

*(Pronounced: SHOO-ee-reh)*

![demo](demo/demo.gif)

A Vim-like TUI git diff viewer and reviewing tool, built in Rust on top of
[ratatui](https://github.com/ratatui-org/ratatui). Leave inline comments as
you review, then pipe the output directly into your AI tool of choice.

## Features

- Vim-style key bindings (`j/k`, `gg/G`, `Ctrl-d/u`, `Ctrl-f/b`, `/`, `n/p`, …)
- Toggle between unified and split views (`s`)
- Syntax highlighting via [syntect](https://github.com/trishume/syntect)
- Word-level diff highlighting
- Inline commenting — **comments are printed to stdout on exit**, making it easy to pipe into AI tools or other workflows
- GitHub PR review (`--pr <url>`, via the `gh` CLI)

## Installation

### Homebrew (macOS / Linux)

```sh
brew install sachaos/tap/shuire
```

Or tap once and install separately:

```sh
brew tap sachaos/tap
brew install shuire
```

### npm / npx (prebuilt binary)

```sh
# One-off run
npx shuire

# Install globally
npm install -g shuire
```

Supported platforms: Linux x64, Linux arm64, macOS x64, macOS arm64,
Windows x64. The right prebuilt binary is selected automatically via
`optionalDependencies`.

### cargo (from source)

```sh
cargo install shuire
```

### Nix flake

```sh
nix run github:sachaos/shuire
```

### Pre-built binary (Linux / macOS)

```sh
curl -fsSL https://raw.githubusercontent.com/sachaos/shuire/main/install.sh | sh
```

Installs the latest release to `~/.local/bin`. Override the destination with
`INSTALL_DIR=/usr/local/bin` or pin a version with `VERSION=v0.1.0`:

```sh
INSTALL_DIR=/usr/local/bin VERSION=v0.1.0 \
  curl -fsSL https://raw.githubusercontent.com/sachaos/shuire/main/install.sh | sh
```

Supported platforms: Linux x64, Linux arm64, macOS x64, macOS arm64.


## Usage

```sh
# Uncommitted changes — working tree vs HEAD (default)
shuire
shuire .

# Unstaged / staged only
shuire working
shuire staged

# Working tree vs an arbitrary commit
shuire main

# Changes introduced by the last commit
shuire HEAD^ HEAD

# Diff between two branches / commits
shuire main feature-branch

# Changes on feature-branch since it diverged from main (three-dot syntax)
shuire main...feature-branch
# Equivalent to:
shuire main feature-branch --merge-base

# GitHub PR review
shuire --pr https://github.com/owner/repo/pull/123
```

### Main arguments

| Argument / flag | Description |
|---|---|
| `<target>` | Commit-ish (default `@` = `HEAD`). Special values: `.`, `working`, `staged`. Accepts `A...B` three-dot syntax. |
| `[compare-with]` | Base commit-ish |
| `--merge-base` | Resolve the base via `git merge-base` (equivalent to `A...B`) |
| `--include-untracked` | Include untracked files (only for `.` / `working`) |
| `-U`, `--context <N>` | Number of context lines |
| `--theme <dark\|light\|deuteranopia>` | Color theme |
| `--pr <url>` | PR URL to review |
| `--comment <json>` | Inject initial comments as JSON |
| `--auto-viewed <glob>` | Automatically mark matching files as viewed |

## Configuration

Place a file at `~/.config/shuire/config.{toml,json5,yaml,json,ini}` (the
location can be overridden via the `SHUIRE_CONFIG` environment variable) to
override the default theme and individual colors.

```toml
# Default theme (only used when --theme is not passed on the CLI)
theme = "dark"  # "dark" | "light" | "deuteranopia"

# Per-color overrides (layered on top of the base theme)
[colors]
added_fg       = "#3fb950"
removed_fg     = "rgb(248, 81, 73)"
comment_bar    = "magenta"
syntax.keyword = "#e6c050"
```

Supported color formats: `#RRGGBB` / `#RGB` / `rgb(r,g,b)` / named colors
(`red`, `green`, `blue`, `cyan`, `magenta`, `yellow`, `black`, `white`,
`gray`, `darkgray`, `light*`). Keys correspond to the `Theme` /
`SyntaxPalette` field names in `src/theme.rs` (`added_fg`, `removed_bg`,
`comment_bar_dim`, `syntax.keyword`, …). Unknown keys and values that cannot
be parsed are ignored.

## Key bindings

### Navigation

| Key | Action |
|---|---|
| `j` / `k`, `↓` / `↑` | Move by one line |
| `Ctrl-d` / `Ctrl-u` | Half-page scroll |
| `Ctrl-f` / `Ctrl-b` | Full-page scroll |
| `gg` / `G` | Jump to top / bottom |
| `Tab` / `Shift-Tab`, `]` / `[` | Next / previous file |
| `{` / `}` | First / last file |
| `n` / `p` | Next / previous hunk (search results while searching) |
| `h` / `l` | Focus file list / diff |
| `.` | Center current line |

### Display

| Key | Action |
|---|---|
| `s` | Toggle unified / split view |
| `F` | Toggle file list |
| `T` | Switch theme |
| `<` / `>` | Adjust file list width |
| `o` / `O` / `Enter` | Expand folded region (20 lines / all) |

### Search & comments

| Key | Action |
|---|---|
| `/` | Search (diff) / filter (file list) |
| `Esc` | Clear search |
| `i` | Add comment at cursor (Insert mode) |
| `V` | Visual mode (range selection), then `i` to comment |
| `dd` | Delete focused comment |
| `N` / `P` | Jump to next / previous comment |
| `C` | Show comment list |
| `y` / `Y` | Copy comment at cursor / all comments |
| `v` | Toggle viewed marker for current file |
| `e` | Open in editor |
| `R` | Reload diff |
| `?` | Help |
| `q`, `Ctrl-c` | Quit |

## AI Workflow Integration

When you quit shuire, all comments you wrote are printed to stdout in a structured format. This makes it straightforward to feed your review notes directly into AI tools:

```sh
# Review a PR and pipe comments into Claude
shuire --pr https://github.com/owner/repo/pull/123 | claude

# Review local changes and pass comments to any AI CLI
shuire | llm "Based on these review comments, summarize the key issues"

# Save comments for later use
shuire main...feature-branch > review-notes.txt
```

This design lets shuire act as a **human-in-the-loop annotation layer**: you skim the diff, leave targeted notes, then hand off the structured output to an AI for further analysis, summarization, or action.

## Development

See [CONTRIBUTING.md](CONTRIBUTING.md).

## License

[MIT](LICENSE)

## Acknowledgements

shuire was inspired by [difit](https://github.com/yoshiko-pg/difit) — a beautiful browser-based diff viewer with inline commenting. difit's idea of writing comments alongside diffs and outputting them for use in other tools sparked the core design of shuire.

## About the Name: What is "Shuire"?

**Shuire (朱入れ)** is a traditional Japanese term used in publishing and writing. It literally translates to "putting in red." 

When an editor or teacher reviews a physical manuscript, they use a red pen to mark corrections, suggest improvements, and leave feedback. This red-ink markup is called *Shuire*. 

Since code review is the modern software engineer's version of proofreading, we named this TUI tool **shuire** to act as your digital red pen for reviewing git diffs.
