Features

Deep-dives into every major feature. Click a section to jump directly.


Dual Architecture

clhorde uses a hybrid approach: two different ways to spawn Claude depending on the prompt mode.

Interactive (PTY)

Spawns Claude in a real pseudo-terminal via portable-pty. The full Claude Code TUI is rendered through alacritty_terminal, a headless terminal emulator. You see colors, tool use, formatting—everything.

claude "your prompt" --dangerously-skip-permissions

One-shot (stream-json)

Passes the prompt as a CLI argument with stream-json output format. Lightweight, text-only. No embedded TUI. Process exits after responding.

claude -p "your prompt" \
  --output-format stream-json \
  --verbose \
  --dangerously-skip-permissions

When to use each:

Toggle between modes with m in Normal mode. The status bar shows the current default.

Worker Pool

clhorde's queue model is what sets it apart from session-based tools. You don't manage individual sessions—you queue prompts and let the worker pool handle dispatch.

  1. You type prompts (via TUI or clhorde-cli submit) → they enter the queue as Pending
  2. The daemon checks: active_workers < max_workers?
  3. If yes, the next pending prompt is dispatched to a new worker
  4. When a worker finishes, the next queued prompt is dispatched

Adjust the pool size with +/- in the TUI (range: 1–20). The status bar shows Workers: active/max.

Because workers are managed by the clhorded daemon, they survive TUI restarts. You can batch 50 prompts, set workers to 5, and walk away. Close the TUI, come back later, and the workers are still running.

Prompt Input & Multi-line Editor

Insert mode provides a full-featured text editor with multi-line support:

Multi-line editing

Press Shift+Enter or Alt+Enter to insert a newline. The input bar grows dynamically (up to 10 lines) and shows a line position indicator when multi-line. Arrow keys navigate within the buffer. Bracketed paste is enabled so pasting multi-line text works without triggering premature submit.

External editor

Press Ctrl+E to open the current prompt in $EDITOR (or vi). When you save and exit, the content is loaded back into the input bar. This is useful for complex, multi-line prompts.

Templates

Type :name and press Tab to expand a template. A suggestion popup shows matching templates as you type. Define templates in templates.toml.

Directory suggestions

Type a path and press Tab to autocomplete directory names. Useful for setting a working directory prefix.

History

Press Up/Down (when no suggestions are visible) to cycle through previously submitted prompts.

Tags

Include @tag anywhere in your prompt to tag it. Tags are stripped from the prompt text sent to Claude but stored for filtering.

@backend @urgent Fix the database connection pooling issue

Worktree toggle

Press Ctrl+W to enable git worktree isolation. The input bar turns cyan and shows [WT]. See Git Worktrees.

Batch Operations

Select multiple prompts and operate on them at once.

Selection

KeyAction
SpaceToggle select on current prompt
vStart visual select (extend with j/k)
VSelect all visible (filtered) prompts
EscClear selection

Batch actions

With prompts selected, these actions apply to all selected:

KeyAction
rRetry all selected completed/failed prompts
xKill all selected running prompts
dDelete selected prompts (with confirmation dialog)
mToggle mode on selected prompts

The help bar changes to show selection-aware actions when prompts are selected.

Git Worktrees

When running multiple workers against the same repo, they can conflict by modifying the same files. Git worktrees solve this by giving each worker its own isolated directory that shares the git object database.

How to use

  1. Press i to enter insert mode
  2. Type your prompt
  3. Press Ctrl+W — the input bar turns cyan and shows [WT]
  4. Press Enter to submit

The worker runs in a new worktree at ../<repo-name>-wt-<prompt-id>/, a sibling directory of your repo.

Cleanup

By default, worktrees persist after the worker finishes. Control this with the worktree_cleanup setting:

[settings]
worktree_cleanup = "manual"  # default — worktrees persist
worktree_cleanup = "auto"    # remove worktrees when workers finish

To manually clean up:

$ clhorde-cli store clean-worktrees

Quick Prompts

Send predefined messages to a running worker with a single keypress. No need to enter interact mode.

Configure in keymap.toml:

[quick_prompts]
g = "let's go"
c = "continue"
y = "yes"
n = "no"

When viewing a running or idle prompt, press the configured key to send the message instantly. The message is echoed in the output panel.

Press Ctrl+P in view mode to see a popup of all configured quick prompts.

Quick prompt keys must not conflict with view mode bindings. If they do, the view binding takes priority.

Manage quick prompts from the CLI:

$ clhorde-cli qp list
$ clhorde-cli qp add g "let's go"
$ clhorde-cli qp remove g

Filtering & Tags

Press / to enter filter mode. Type to filter prompts by text. Case-insensitive. The list updates live as you type.

Tag filtering

Include @tag in your filter to filter by tags. Multiple @tag tokens use AND logic—only prompts matching all specified tags are shown.

# Show prompts tagged @backend AND @urgent:
@backend @urgent

# Combine text and tags:
@frontend fix login

Press Enter to apply the filter and return to Normal mode. Press Esc to clear the filter.

Queue Reordering

Move pending prompts up or down in the queue to prioritize them.

KeyAction
JMove selected pending prompt down
KMove selected pending prompt up

Only works on pending prompts. Running and completed prompts cannot be reordered. The new position is persisted.

Retry & Resume

Two ways to re-run a completed or failed prompt:

r — Retry

Creates a new prompt with the same text and settings. A fresh Claude session. Good for: retrying after a failure, getting a different response.

R — Resume

Continues the existing Claude session using --resume with the stored session ID. The conversation context is preserved. Good for: continuing where you left off.

Both work on completed and failed prompts. With batch selection, r retries all selected prompts.

Persistence

Every prompt is saved to disk as a JSON file named with a UUID v7 in ~/.local/share/clhorde/prompts/. Persistence is managed by the clhorded daemon.

Persisted data includes: prompt text, mode, state, tags, session ID, worktree path, and queue rank.

On daemon startup, all prompt files are loaded and restored as Completed or Failed (no auto-dispatch). This means you never lose your prompt history across restarts.

Pruning

The max_saved_prompts setting controls automatic pruning (default: 100). When the count exceeds the limit, the oldest completed prompts are removed first.

[settings]
max_saved_prompts = 100

Manage stored prompts with the clhorde-cli store CLI commands.

Split View

The main area shows a split between the prompt list (left) and output panel (right).

KeyAction
hShrink prompt list panel (Normal mode)
lGrow prompt list panel (Normal mode)
tToggle split view on/off (View mode)

The default split ratio is 40% list / 60% output. Customize with the list_ratio setting (10–90):

[settings]
list_ratio = 40

Export

Press w in View mode to export the current prompt's output to a markdown file.

The file is saved to ~/clhorde-output-{id}-{timestamp}.md.

Prompt from Files

Load prompts from files and launch the TUI with them pre-queued. Each file becomes one pending prompt. All prompts automatically run with worktree isolation, so each gets its own git worktree for safe parallel execution.

$ clhorde prompt-from-files tasks/*.md                          # Shell glob expansion
$ clhorde prompt-from-files --run-path /path/to/repo tasks/*.md # Target a specific repo
$ clhorde prompt-from-files a.txt b.txt c.txt                   # Multiple file arguments
$ clhorde prompt-from-files a.txt,b.txt c.txt                   # Comma-separated + space-separated

Empty files are skipped with a warning. Unreadable files are also skipped. The TUI launches with all loaded prompts in the queue, ready for worker dispatch.

Use --run-path <path> to specify the working directory (and git repo) for all prompts. This is useful when the prompt files live in a different location than the target repository.

This is useful for batch workflows where you prepare prompts in advance as individual files.