Lightweight command generation and terminal chat — a native popup assistant for Herdr that also works from any terminal.
Describe the command you need, review it, and insert it into your shell with one keypress. herdr-ask never executes commands — it only generates, previews, and inserts text, and only when you explicitly confirm.
herdr-ask COMMAND codex / auto fish ~/git/tesela
Describe the command you need:
> find files larger than 500 MB but ignore .git and node_modules
Enter submit Tab mode Ctrl+P backend Ctrl+M model Esc close
Backends: Ollama and any OpenAI-compatible server (no account needed), direct OpenAI / Anthropic APIs with keys in your OS keychain, and your existing Codex CLI, Claude Code, and Pi subscriptions through ephemeral headless invocations. No telemetry, no daemon, no stored conversations.
cargo install herdr-ask # or: brew install TaylorFinklea/tap/herdr-ask
herdr-ask setup # detects Herdr, CLIs, Ollama; writes configOr as a Herdr plugin (downloads the release binary and verifies its checksum):
herdr plugin install TaylorFinklea/herdr-askTry it immediately, no Herdr required:
herdr-ask command --print "compress this directory excluding node_modules"Bind the plugin action (recommended):
[[keys.command]]
key = "prefix+a"
type = "plugin_action"
command = "dev.herdr-ask.open"
description = "ask AI"Or bind the standalone binary as a direct popup:
[[keys.command]]
key = "prefix+a"
type = "popup"
command = "herdr-ask"
description = "ask AI"
width = "80%"
height = "70%"Either opens an 80%×70% popup over the focused pane. The popup knows which
pane it came from: Ctrl+Enter inserts the generated command back into that
pane — without pressing Enter for you.
With Ollama running locally, herdr-ask works out of the box with zero configuration and zero API keys:
ollama pull qwen3.6:35b-a3b-nvfp4 # any model you like
herdr-ask # opens the popup; Ctrl+M picks a modelmodel = "auto" remembers your last choice, auto-selects when exactly one
model exists, and opens the picker otherwise.
When a backend exposes many models (Pi discovers dozens via pi --list-models), the picker (Ctrl+M) opens on a scoped short list and
Tab toggles to the full list. Define the scoped set with model_scope glob
patterns per backend — "auto" and any models aliases are always scoped:
[backends.pi]
kind = "process"
adapter = "pi"
model_scope = ["openai-codex/*", "example-cloud/*"] # picker opens on theseNavigating the picker: arrow keys or j/k, g/G to jump to the
top/bottom, PageUp/PageDown to page. Press / to open a filter box and type
to narrow the list (Esc clears it), then Enter to select.
In the editor, ↑/↓ recall your previous prompts, with separate history
for Command and Chat mode. History is in-memory and discarded when the popup
closes (the spec keeps everything ephemeral by default).
To keep history across sessions, opt in — this writes your prompts (not responses) to an owner-only file under the state dir:
[history]
persist = true # off by default; crosses the ephemeral line deliberately
max_entries = 500Keys for direct OpenAI/Anthropic backends live in the native credential store (macOS Keychain, Linux Secret Service) — plaintext keys in config.toml are rejected:
herdr-ask auth set openai # prompts with echo off, stores in keychain
herdr-ask auth get-metadata openai
herdr-ask auth test openai
herdr-ask auth delete openaiExternal secret managers work too — the command runs without a shell, with a minimal environment and a 5-second timeout:
credential = { source = "command", command = ["op", "read", "op://Private/OpenAI/api-key"] }Reuse the CLIs you already pay for. Every request is a fresh, ephemeral, tool-free invocation in your source pane's working directory:
| Backend | Invocation |
|---|---|
codex |
codex exec --ephemeral --skip-git-repo-check --sandbox read-only --output-last-message <tmp> - |
claude |
claude --print --output-format text --no-session-persistence [--max-turns 1] --system-prompt … <prompt> |
pi |
pi --print --no-session --no-tools --no-context-files --no-extensions --no-skills --no-prompt-templates --system-prompt … <prompt> |
herdr-ask verifies these flags against the installed binary at runtime
(herdr-ask doctor). If a CLI cannot run ephemerally — e.g. an old Claude
without --no-session-persistence — the backend is marked unavailable rather
than silently persisting a session. Optional flags like --max-turns are
included only when the installed version supports them.
Any other CLI can be wired up as a custom process backend with configurable argv placeholders, prompt transport (stdin/argument/file), and output source (stdout/stderr/file).
- Never executes. There is no execute shortcut. Insertion uses Herdr's
literal
pane send-textand never appends Enter. - Suspicious output is gated. Responses containing prose or multiple code blocks cannot be inserted without an explicit "insert anyway".
- Ephemeral by default. Conversations live in memory and die with the popup. Process backends run in no-session modes. Nothing is logged.
- Secrets stay secret. Keys live in the OS keychain, are resolved at request time into zeroizing containers, are redacted from error messages, and are scrubbed from process-backend environments.
- Explicit context only. Terminal output is attached only via
Ctrl+O, after you choose how many lines. - TLS enforced except loopback; non-loopback plain HTTP requires
allow_insecure_http = true. - No shell interpolation anywhere — every subprocess is spawned by argv.
- No telemetry, no analytics, no accounts, no update checker.
herdr-ask config path prints the active location; precedence is
$HERDR_ASK_CONFIG → $HERDR_PLUGIN_CONFIG_DIR/config.toml (only when that
file exists) → the platform config directory. See the fully commented
examples/config.toml.
Popup vs standalone config. Herdr sets
HERDR_PLUGIN_CONFIG_DIRfor plugin popups. herdr-ask uses a plugin-scopedconfig.tomlthere only if one exists; otherwise it reads the same platform config as the standalone binary — so a single config serves both. Drop aconfig.tomlinto the plugin config dir (seeherdr plugin config-dir dev.herdr-ask) only if you want popup-specific settings.
Prompts are customizable at four levels (built-in → [prompts.<mode>] →
[backends.<id>.prompts] → --system-prompt/--append-system-prompt), with
template variables like {{shell}}, {{os}}, and {{cwd}}. Keybindings are
remappable under [keys].
CLI surface:
herdr-ask [command|chat] [--print] [--json] [REQUEST...]
herdr-ask setup | doctor [BACKEND] | backends | models [BACKEND]
herdr-ask auth set|get-metadata|delete|test BACKEND
herdr-ask config path|validate [--strict]|edit
Ctrl+X in the popup exports the current conversation to a markdown file in
the source directory — the only way prompts or responses ever touch disk.
Start with:
herdr-ask doctor # pass/warn/fail across config, Herdr, backends
herdr-ask doctor --json # machine-readable- "backend unavailable: does not support --no-session-persistence" — upgrade that CLI; herdr-ask refuses non-ephemeral fallbacks by design.
- Ctrl+Enter does nothing — your terminal may not support the kitty
keyboard protocol that distinguishes Ctrl+Enter from Enter. Rebind:
[keys] insert = "ctrl+i". - "multiple models; choose one" —
herdr-ask models <backend>then--model <id>, or pick once withCtrl+M(remembered). - Popup opens but insertion says the pane is missing — the source pane closed; the command is on your clipboard instead.
- Ollama not detected — check
curl http://127.0.0.1:11434/v1/models.
The repo ships a formula template in Formula/herdr-ask.rb. Tap workflow:
- Create/clone your tap repo (
github.com/<you>/homebrew-tap). - Copy
Formula/herdr-ask.rbinto itsFormula/directory. - Replace each
REPLACE_WITH_*_SHA256with the matching value from the release'sSHA256SUMS. brew install <you>/tap/herdr-ask.
herdr plugin uninstall dev.herdr-ask # plugin install
cargo uninstall herdr-ask # cargo install
brew uninstall herdr-ask # Homebrew
# optional cleanup:
herdr-ask auth delete openai # remove stored keys (repeat per backend)
rm -rf "$(dirname "$(herdr-ask config path)")"cargo test # unit + integration (mock HTTP, fixture CLIs)
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --check
cargo auditFor local plugin development:
HERDR_ASK_LOCAL_BINARY=target/release/herdr-ask sh scripts/install-release-binary.sh
then herdr plugin link ..
Dual-licensed under MIT or Apache-2.0, at your option.