Skip to content

Commit 251622b

Browse files
Alan Shumclaude
andcommitted
feat: hunk-level grouping, multi-backend AI, config, caching, help overlay
- Hunk-level semantic grouping: groups related hunks across files by intent, a single file's hunks can appear in different groups - Multi-backend AI: support Claude CLI and Copilot CLI (copilot --yolo) with configurable preference and automatic fallback - Config file: ~/.config/semantic-diff.json with JSONC comment support, model selection, and cross-backend model mapping - Grouping cache: .git/semantic-diff-cache.json keyed by diff hash for instant startup when diff hasn't changed - Group-aware diff filtering: sidebar file/group selection filters diff view - Help overlay: press ? for keybinding reference - Text wrapping: long diff lines flow with terminal width - Improved key responsiveness: accept Repeat events on macOS - Scroll-to-top on file select from sidebar Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent f48a47e commit 251622b

File tree

14 files changed

+1266
-134
lines changed

14 files changed

+1266
-134
lines changed

Cargo.lock

Lines changed: 60 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[package]
22
name = "semantic-diff"
3-
version = "0.1.0"
3+
version = "0.2.0"
44
edition = "2021"
5-
description = "A terminal diff viewer with AI-powered semantic grouping via Claude CLI"
5+
description = "A terminal diff viewer with AI-powered semantic grouping (Claude CLI / Copilot)"
66
license = "MIT"
77
repository = "https://github.com/alankyshum/semantic-diff"
88
keywords = ["git", "diff", "tui", "semantic", "claude"]
@@ -23,6 +23,7 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
2323
serde = { version = "1.0.228", features = ["derive"] }
2424
serde_json = "1.0.149"
2525
which = "8.0.2"
26+
dirs = "6"
2627
tui-tree-widget = "0.24"
2728

2829
[profile.release]

README.md

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,26 @@ A terminal diff viewer with AI-powered semantic grouping. Built with Rust and [r
44

55
Groups your git changes by *meaning* — not just by file path. Designed to run as a cmux split pane alongside Claude Code, giving real-time visibility into what's being changed and why.
66

7+
## Demo
8+
9+
https://github.com/user-attachments/assets/semantic-diff-demo.mp4
10+
711
## Features
812

9-
- **Semantic grouping** — Claude CLI clusters changes into named groups (e.g. "Refactored auth logic", "Added test coverage")
13+
- **Hunk-level semantic grouping** — AI clusters related hunks across files by intent (e.g. "Auth refactor", "Test coverage"), not just file-level grouping
14+
- **Multi-backend AI** — Supports Claude CLI and GitHub Copilot CLI (`copilot --yolo`), with configurable preference and automatic fallback
15+
- **Configurable**`~/.config/semantic-diff.json` with JSONC comment support, model selection, and intelligent cross-backend model mapping
16+
- **Grouping cache** — Cached in `.git/semantic-diff-cache.json` keyed by diff hash; instant reload when nothing changed
1017
- **Syntax-highlighted diffs** — Powered by syntect with word-level inline highlighting
1118
- **Collapse/expand** — Toggle files, hunks, and semantic groups
12-
- **File tree sidebar** — Changed files organized by semantic group with stats
19+
- **File tree sidebar** — Changed files organized by semantic group with per-hunk stats
20+
- **Group-aware diff filtering** — Select a file or group in the sidebar to filter the diff view to only those changes
1321
- **Hook-triggered refresh** — Auto-updates when Claude Code edits files (via SIGUSR1)
1422
- **cmux integration** — Auto-opens in a right split pane
23+
- **Help overlay** — Press `?` to see all keybindings
24+
- **Text wrapping** — Long diff lines flow with the terminal width
1525
- **Progressive enhancement** — Shows ungrouped diff immediately, regroups when AI responds
16-
- **Graceful degradation** — Works without Claude CLI (falls back to ungrouped view)
26+
- **Graceful degradation** — Works without any AI CLI (falls back to ungrouped view)
1727

1828
## Install
1929

@@ -49,16 +59,40 @@ semantic-diff
4959

5060
| Key | Action |
5161
|-----|--------|
52-
| `j/k` | Navigate up/down |
53-
| `Enter` | Collapse/expand file, hunk, or group |
62+
| `j/k`, `↑/↓` | Navigate up/down |
63+
| `Enter` | Sidebar: select file/group · Diff: toggle collapse |
5464
| `Tab` | Switch focus between tree sidebar and diff view |
5565
| `/` | Search/filter files |
5666
| `n/N` | Next/previous search match |
57-
| `Escape` | Clear search |
5867
| `g/G` | Jump to top/bottom |
5968
| `Ctrl+d/u` | Page down/up |
69+
| `?` | Show shortcut help |
70+
| `Escape` | Clear filter / quit |
6071
| `q` | Quit |
6172

73+
### Configuration
74+
75+
On first run, a default config is created at `~/.config/semantic-diff.json`:
76+
77+
```jsonc
78+
{
79+
// Which AI CLI to prefer: "claude" or "copilot"
80+
// Falls back to the other if preferred is not installed
81+
// "preferred-ai-cli": "claude",
82+
83+
"claude": {
84+
// Model: "sonnet", "opus", "haiku"
85+
// Cross-backend models mapped automatically (gemini-flash → haiku)
86+
"model": "sonnet"
87+
},
88+
89+
"copilot": {
90+
// Model: "sonnet", "opus", "haiku", "gemini-flash", "gemini-pro"
91+
"model": "sonnet"
92+
}
93+
}
94+
```
95+
6296
## Claude Code Integration
6397

6498
semantic-diff is designed to work as a live diff viewer alongside Claude Code.
@@ -101,14 +135,32 @@ chmod +x ~/.claude/hooks/refresh-semantic-diff.sh
101135
2. PostToolUse hook fires `refresh-semantic-diff.sh`
102136
3. If semantic-diff is running: sends SIGUSR1 to refresh the diff
103137
4. If not running: opens a cmux right-split pane and launches semantic-diff
104-
5. Claude CLI groups the changed files by semantic meaning
138+
5. AI groups the changed hunks by semantic meaning
105139
6. You see real-time, grouped changes without leaving the terminal
106140

141+
## Changelog
142+
143+
### v0.2.0
144+
145+
- **Hunk-level semantic grouping** — Groups related hunks across files by intent, matching GitHub Copilot's content-level approach. A single file's hunks can appear in different groups.
146+
- **Multi-backend AI support** — Added GitHub Copilot CLI (`copilot --yolo`) as a fallback when Claude CLI is not available.
147+
- **Configuration file**`~/.config/semantic-diff.json` with JSONC comment support. Configure preferred AI backend, model per backend, with intelligent cross-backend model mapping (e.g. `gemini-flash``haiku`).
148+
- **Grouping cache** — Results cached in `.git/semantic-diff-cache.json` keyed by diff hash. Instant startup when diff hasn't changed.
149+
- **Group-aware diff filtering** — Selecting a file in the sidebar filters the diff to its entire group. Selecting a group header toggles the filter.
150+
- **Help overlay** — Press `?` to see all keybindings in a centered popup.
151+
- **Text wrapping** — Long diff lines wrap with the terminal width instead of being truncated.
152+
- **Improved key responsiveness** — Accept `Repeat` key events on macOS for smooth held-key navigation.
153+
- **Scroll-to-top on file select** — File header pinned to top of viewport when selected from sidebar.
154+
155+
### v0.1.0
156+
157+
- Initial release with file-level semantic grouping, syntax highlighting, collapse/expand, file tree sidebar, and Claude Code hook integration.
158+
107159
## Requirements
108160

109161
- Rust 1.75+
110162
- Git
111-
- [Claude CLI](https://claude.ai/download) (optional, for semantic grouping)
163+
- [Claude CLI](https://claude.ai/download) or [GitHub Copilot CLI](https://github.com/github/copilot-cli) (optional, for semantic grouping)
112164
- [cmux](https://cmux.dev) (optional, for auto-split pane)
113165

114166
## License

0 commit comments

Comments
 (0)