Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ All notable changes to this project are documented here. The format is based on

## [Unreleased]

## [1.16.0] - 2026-08-15

### Added
- Pinned preview: `p` freezes one settled file preview beside the active file for session-only comparison. Active stays beside the tree and pin sits on the right; when space is short the active/tree layout remains intact, the held pin says how to widen it, and `Tab` visits only visible regions. Its title carries the captured branch, naming the worktree only when the pin came from a different one, finder confirmation takes focus to the chosen active file, and branch-change replacement names both branches. The captured origin survives a worktree switch; each preview keeps independent scroll/search state, and `{` / `}` or the mouse resize their divider. → [usage](docs/usage.md#pinned-previews) · [keys](docs/keys.md)
- `changed_file_view`: choose whether existing Git-changed files initially open as diffs (default) or in their normal rendered Markdown/syntax-content view; deleted paths stay diff-first, and `v` still cycles through the diff views. → [configuration](docs/configuration.md) · [usage](docs/usage.md#viewing-a-file)
- Pinned preview: press `p` on a settled file to freeze it on the right while you keep browsing on the left. `p` again unpins it, or press `p` on another file to replace it. `Tab` moves between the tree, the active file, and the pin. Hold a file from one worktree and switch (`W`) to compare it with another. → [usage](docs/usage.md#pinned-previews) · [keys](docs/keys.md)
- `changed_file_view`: choose whether existing Git-changed files initially open as diffs (default) or in their normal rendered Markdown/syntax-content view; deleted paths stay diff-first, and `v` still cycles through the diff views. Thanks @umutciloglu (#146) → [configuration](docs/configuration.md) · [usage](docs/usage.md#viewing-a-file)

### Fixed
- Agent skill: the launch instructions no longer tell agents to pass `--cwd`. herdr resolves the manifest's relative pane command against it, so the launch failed with `plugin_pane_open_failed` — or worse, inside a built plugin checkout, silently ran that checkout's binary. The skill and the `docs/usage.md` snippet now explain that the viewed root follows the *focused herdr pane's* directory, so an agent's own `cd` does not move it. Thanks @AntonyKor (#139) → [agent skill](skills/herdr-file-viewer/SKILL.md) · [usage](docs/usage.md#teach-your-agent)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "herdr-file-viewer"
version = "1.15.0"
version = "1.16.0"
edition = "2024"
rust-version = "1.96"
description = "A git-aware, read-only file viewer that runs as a herdr TUI pane"
Expand Down
50 changes: 30 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
![herdr 0.7+](https://img.shields.io/badge/herdr-0.7%2B-8a2be2)
![platforms: linux • macOS • Windows (preview)](https://img.shields.io/badge/platforms-linux%20%E2%80%A2%20macOS%20%E2%80%A2%20Windows%20(preview)-informational)

**Browse your repo without leaving your terminal session: a git-aware, read-only file viewer
that lives in a herdr pane.** A keyboard-driven TUI with a directory tree
on the left and, on the right, exactly the view each file deserves: a **diff** if it changed,
**rendered markdown** if it's markdown, **syntax-highlighted code** otherwise. Git status is woven
right into the tree. It opens beside whatever you're doing and never touches your files.
**A git-aware, read-only file viewer in a herdr pane.** Tree on the left. On the right, the view
that file deserves: a **diff** if it changed, **rendered markdown**, or **highlighted code**.
Agents can drop you on a file or a line. You pin one file, mark a range, and paste those notes
back into the chat. It never touches your files.

![herdr-file-viewer open in a herdr split beside your work: the directory tree on the left, syntax-highlighted content on the right](assets/File-viewer.png)

Expand All @@ -22,20 +21,28 @@ right into the tree. It opens beside whatever you're doing and never touches you

![herdr-file-viewer running full-screen](assets/File-Viewer-FS.png)

*Pin a file with `p` and keep browsing: tree, the file you are on, and a frozen `Pinned: [main]` beside it:*

![herdr-file-viewer with a pinned preview: tree on the left, the active file in the middle, a frozen pin of another file on the right](assets/Pinned-preview.png)

## Why you'd want it

- **The right view, automatically.** Stop `cat`-ing files and squinting at raw diffs. A changed
file shows its diff; a README renders; code is highlighted: no mode-switching, no commands.
- **Git at a glance.** `M`/`A`/`D`/`?` markers (colored, with the glyph as a non-color cue), a
changed-files-only filter, and a baseline you can flip between your branch's merge-base and
`HEAD` — all in the tree, not a separate mode.
- **It sits beside your work.** Opens in a herdr split (or its own tab) with one keypress, and
toggles away just as fast. Great next to an agent, a build, or an editor.
- **Safe on anything.** Read-only by construction and hardened to open *untrusted* repos (an
agent's worktree, a fresh clone) without running repo-controlled code or letting hostile file
content drive your terminal. See [SECURITY.md](SECURITY.md).
- **Keyboard-first**, mouse-optional, and it never reinvents rendering: it delegates to
`glow` / `delta` / `bat` and degrades gracefully when they're absent.
- **The right view, automatically.** A changed file opens as a diff. A README renders. Code is
highlighted. No `cat`, no mode switch, no commands. Press `v` only when you want something else.
- **Git in the tree.** `M`/`A`/`D`/`?` on every row, a changed-only filter (`c`), jump next/prev
changed file (`]`/`[`), flip the baseline between your branch and `HEAD` (`b`). Not a separate
git client.
- **Pin one file, keep browsing.** `p` freezes it on the right. Switch worktree (`W`) and compare
it with another checkout, or pin the old version and walk the new one.
- **Agents show you the spot. You send notes back.** Teach them the [bundled skill](skills/herdr-file-viewer/SKILL.md)
and "open `src/app.rs:42` in Files" lands you there. Mark a file or a range (`a`), copy the
notes (`A` then `y`), paste them into the chat.
- **Edit in *your* editor.** `e` suspends the viewer and opens the file in neovim, vim, micro, or
whatever you set as `editor` (else `$EDITOR`). You change the file there; the viewer never writes
it, and comes back when you quit the editor.
- **Beside your work, safe on anything.** One keypress in a herdr split (or its own tab). Read-only,
hardened for an agent's worktree or a fresh clone. Delegates rendering to `glow` / `delta` / `bat`.
See [SECURITY.md](SECURITY.md).

## Highlights

Expand All @@ -45,13 +52,16 @@ A taste of what the keys do — the [full key & mouse reference](docs/keys.md) h
| Key | Does |
| --- | --- |
| `f` | Fuzzy-find any file in the tree |
| `p` | Pin the current file and keep browsing (compare across worktrees with `W`) |
| `a` / `A` | Annotate a file or range; copy the notes out for an agent |
| `v` | Cycle the view (diff ⇄ rendered ⇄ syntax) |
| `]` / `[` | Jump to the next / previous changed file |
| `b` | Flip the diff baseline: your branch's merge-base ⇄ `HEAD` |
| `W` | Switch to another git worktree, in place |
| `L` | Copy a `path:line` reference (or the selected lines) to your clipboard |
| `L` | Copy a `path:line` reference (or the selected lines) |
| `Z` | Full-screen the current file |
| `e` / `O` / `R` | Hand off: open in your editor / the OS default app / the file manager |
| `?` | Help overlay: What's New first, then keys, settings, and about |
| `e` / `O` / `R` | Hand off: editor / OS default app / file manager |
| `?` | Help overlay: What's New, keys, settings, about |

## Quick start

Expand Down
Binary file added assets/Pinned-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion herdr-plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

id = "herdr-file-viewer"
name = "herdr-file-viewer"
version = "1.15.0"
version = "1.16.0"
description = "A git-aware, read-only file viewer: a keyboard-driven TUI in a herdr split pane."
min_herdr_version = "0.7.0"
platforms = ["linux", "macos", "windows"]
Expand Down
8 changes: 4 additions & 4 deletions tests/docs_consistency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ fn pinned_preview_docs_cover_the_frozen_reference_contract() {
// AC-40: pinning is deliberately more than a `p` row. Its session lifetime, captured origin,
// focus routing, independent interaction state, narrow-layout floor, and read-only boundary
// must stay discoverable across the feature guide, key/config reference, architecture map, and
// Unreleased changelog entry.
// the released changelog entry.
for phrase in [
"## Pinned previews",
"frozen in-memory snapshot",
Expand Down Expand Up @@ -507,9 +507,9 @@ fn pinned_preview_docs_cover_the_frozen_reference_contract() {
);
}

let unreleased = section(CHANGELOG, "## [Unreleased]", "\n## [");
let released = section(CHANGELOG, "## [1.16.0]", "\n## [");
assert!(
unreleased.contains("Pinned preview"),
"CHANGELOG.md must include the pinned-preview feature in Unreleased"
released.contains("Pinned preview"),
"CHANGELOG.md must include the pinned-preview feature in the 1.16.0 section"
);
}
Loading