Agentic coding
harness.
Herder drives a model through native tool calls until the job is done. One agent core — a terminal TUI on top, a browser UI beside it, headless underneath.
Provider-agnostic: any OpenAI-compatible /v1 endpoint —
infr, llama.cpp, OpenAI, OpenRouter — plus a
native Anthropic Messages backend with prompt caching and extended thinking,
and a Codex Responses backend you sign into with a ChatGPT subscription.
Adaptive tool set + MCP, sub-agents, skills, persistent memory, an OS
sandbox on by default, guardrails that hard-block foot-guns. The vim layer
is hjkl.
add a --json flag to the status command read src/cli.rs grep "fn status" src/ edit src/cli.rs - pub struct StatusArgs {} + pub struct StatusArgs { + /// Emit machine-readable JSON + #[arg(long)] + pub json: bool, + } bash cargo test --quiet test result: ok. 42 passed; 0 failed ✔ Added --json to the status command — serializes via serde_json, tests pass.
why
One agent core. Every provider.
Provider-agnostic
Point it at any /v1/chat/completions endpoint —
infr, OpenAI, llama.cpp, OpenRouter.
Built-in presets plus custom [providers.*] with their own
model, key, and headers. Azure supported too.
Claude and Codex, natively
A native Anthropic Messages API backend, auto-selected for
api.anthropic.com — unlocking native prompt caching and
extended thinking, streamed to the reasoning pane. A Codex Responses
backend does the same for a ChatGPT subscription: /login
opens a browser OAuth flow instead of asking for an API key.
TUI, browser, or headless
A UI-agnostic core (hrdr-app) drives the ratatui TUI;
hrdr serve puts the same session behind an HTTP+WebSocket
API with an optional Dioxus WASM SPA (token auth on loopback by default,
HTTP Basic or a SQLite user store with TLS for remote); and
hrdr run --json goes headless — NDJSON events for scripting
and CI. Same agent underneath.
Adaptive tool set
read, write, edit,
replace (project-wide substitution with a diff and a
dry_run), todo, verify,
fetch, search, memory,
skill, a shell — plus any MCP server's tools. Deliberately
small: a dedicated tool earns its place only when it carries a guarantee
the shell cannot, so mv/cp/rm and
rg stay shell commands (grep,
find, ls and tree survive only in
the shell-less jail mode). Presence-aware: the model is
only offered tools it can actually run, and read tools keep credential
files off-limits. After every edit the file's language server hands its
errors straight back with the tool result.
Sub-agents
The task tool spawns sub-agents with their own context.
Every one runs detached — the call returns a task id at once, several
run in parallel, and a finished result is delivered back into the
conversation, waking an idle agent. Cross-provider profiles let an Opus
main agent delegate to a cheaper model.
Persistent memory
A memory tool with project and global scopes — plain
Markdown under the XDG data dir, greppable and git-diffable. The bounded
index survives /clear and /compact.
Foot-guns hard-blocked
The shell mechanically rejects git add -A, force-push,
reset --hard, whole-tree deletes, and
curl | sh before they run. Edits refuse files the model
hasn't read. Add your own [[guardrails]] rules.
Context and spend under control
Prompt-cache breakpoints across turns, tool-output pruning before each
request, and auto-compaction when the window fills — recent turns kept
verbatim. A max_cost cap (or run --max-cost)
stops the session before the next call once estimated spend, sub-agents
included, reaches your ceiling. All tunable in config.toml.
The vim layer is hjkl
--vim swaps the plain input for a real
hjkl vim editor behind an FSM-agnostic
EditorEngine seam. TUI colors come from any hjkl theme.
Confined by the kernel, on by default
Writes are held inside the working directory by a path guard on the file
tools plus kernel confinement for shell children — Landlock on Linux,
Seatbelt on macOS. Four modes: write (the default, package
caches granted so cargo build still works),
read, jail (no shell, no network tools, reads
limited to one directory — for auditing code you don't trust), and
none. Reads stay broad on purpose. A machine with no
backend is told so rather than pretending.
Reusable procedures
A skill is a Markdown prompt template invoked with
:name args — ten ship built in (:review,
:audit, :commit, :test,
:plan, :release and more), and your own land
in .hrdr/skills/ or the Claude Code / opencode command
directories. The model can reach for one itself through the
skill tool; mark a skill
model_invocable: false and only you can start it.
agents
Six built-ins. Or bring your own as Markdown files.
Selected with the task tool's agent argument,
@name-mentioned in a message, or run as the main loop with
hrdr --agent <name>. Agents are also discovered from
Markdown files — .hrdr/agents/, and Claude Code
(.claude/agents/) and opencode locations work as-is.
Code investigator — read/search tools only. Traces files, types, and call paths and reports back.
Code reviewer — audits a change for bugs, edge cases, and security
issues, with path:line findings.
Planner — investigates read-only, then returns a concrete, step-by-step implementation plan in its report. Changes nothing.
Implementer — hand it a precise spec (exact files, symbols, before → after) and it implements that, verifies, and commits. No scope creep.
Audits code you do not trust under
sandbox = "jail" — no shell, no network, reads confined to
the directory you hand it. Injection-resistant, and it overrides the
session's mode, --yolo included.
Open-ended multi-step tasks — explore and modify. The default when
task names no agent.
install
Prebuilt binaries on every tagged release.
Linux (gnu + musl, x86_64/aarch64), macOS (Apple Silicon + Intel), and
Windows binaries ship with every GitHub Release, alongside
.deb, .rpm, and Alpine .apk
packages. Also on crates.io, Homebrew tap, AUR, and Scoop.
hrdr targets UNIX workflows — the shell tool runs
bash (or POSIX sh), so on Windows run it under WSL
or install Git Bash. Without one of those there's no shell tool and the
agent can't run commands; PowerShell is intentionally not supported.
$ brew install kryptic-sh/tap/hrdr $ hrdr
$ yay -S hrdr-bin $ hrdr
$ scoop bucket add kryptic-sh https://github.com/kryptic-sh/scoop-bucket $ scoop install hrdr
# grab the .deb / .rpm from the latest release, then: $ sudo dpkg -i hrdr_*.deb $ sudo rpm -i hrdr-*.rpm
# crates.io $ cargo install hrdr # or build from the repo $ git clone https://github.com/kryptic-sh/hrdr $ cd hrdr $ cargo build --release