hydra

command module
v0.0.0-...-348835b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 4, 2026 License: MIT Imports: 3 Imported by: 0

README

Hydra

Hydra example

AI-driven local pull request workflow where Claude is the only contributor.

tmux Integration

tmux window list showing hydra tasks

Hydra sets the xterm title for every command it runs, so terminal multiplexers like tmux automatically display the current operation in the window list. This makes it easy to run many tasks in parallel and see at a glance what each one is doing. See contrib/Makefile.tmux for a helper Makefile that spawns a tmux window per task.

What is Hydra?

You don't need a CI system, VM infrastructure, web interfaces, pull requests. You don't even need to push to do anything. You just need Claude.

Hydra turns markdown documents that describe desired changes into branches, code, and commits without you writing a line. Each task is just a markdown file describing what to build or fix. Hydra assembles context from your design docs, hands the full document to Claude Code — including instructions to run tests, lint, and commit — and pushes a branch ready for your review.

Concepts

Task — A markdown file describing a unit of work. Lives in tasks/ as a .md file, optionally inside a group subdirectory.

Group — A subdirectory of tasks/ containing related tasks. An optional group.md provides shared context injected into every task in the group.

Design Directory — The directory tree holding tasks, rules, configuration, and state. Registered at hydra init time.

State Machine — Every task moves through a fixed set of states:

                    ┌──────────┐
                    │ pending  │
                    └────┬─────┘
                         │  hydra run
                         v
                    ┌──────────┐
              ┌─────│  review  │─────┐
              │     └────┬─────┘     │
              │          │           │  hydra review rm /
              │          │  hydra    │  hydra merge rm
              │          │  merge    │
              │          │  run      v
              │     ┌────┴─────┐  ┌───────────┐
              │     │  merge   │  │ abandoned  │
              │     └────┬─────┘  └───────────┘
              │          │
              │          │  success
              v          v
         ┌─────────────────┐
         │   completed     │
         └─────────────────┘

Design Directory Structure

design-dir/
├── rules.md                          # Rules injected into every task context
├── lint.md                           # Code quality and linting rules
├── functional.md                     # Functional test requirements
├── hydra.yml                         # Configuration (commands, model, API type)
├── tasks/                            # Pending task files
│   ├── {name}.md                     # Individual task
│   ├── {group}/                      # Task group (subdirectory)
│   │   ├── group.md                  # Optional group heading (shared context)
│   │   └── {name}.md                 # Grouped task
│   └── issues/                       # Imported issues (created by hydra sync)
│       ├── group.md                  # Auto-generated group heading
│       └── {number}-{slug}.md        # Issue task files
├── other/                            # Miscellaneous supporting documents
├── state/
│   ├── record.json                   # SHA-to-task mapping for all completed runs
│   ├── review/                       # Tasks finished, awaiting review
│   ├── merge/                        # Tasks reviewed, ready to merge
│   ├── completed/                    # Tasks that completed the full lifecycle
│   └── abandoned/                    # Abandoned tasks
└── milestone/
    ├── {date}.md                     # Milestone target (e.g., 2025-06-01.md)
    ├── delivered/                    # Milestones marked as delivered
    │   └── {date}.md
    └── history/
        └── {date}-{grade}.md         # Historical score (e.g., 2025-06-01-B.md)

rules.md, lint.md, and functional.md are optional — empty or missing files are silently omitted from the assembled document.

Installation

go install github.com/erikh/hydra@latest
Credentials

Hydra supports two execution paths, chosen automatically:

  1. Claude Code CLI (preferred): If the claude CLI is installed and on your PATH, hydra shells out to it directly. This uses whatever authentication the CLI has configured (OAuth login via claude login, etc.) and provides Claude Code's own interactive terminal UI.
  2. Direct API (fallback): If the claude CLI is not found, hydra calls the Anthropic API directly using ANTHROPIC_API_KEY and provides its own built-in TUI.

Quick Example: Issue to Merge

# Initialize a project with a source repo and design directory
hydra init https://github.com/you/project.git ./my-design

# Import open issues from GitHub
hydra sync

# Run a task — Claude implements, tests, lints, and commits; branch pushed
hydra run issues/42-fix-bug

# Add tests — Claude reads the task, adds missing tests, runs test/lint
hydra test 42-fix-bug

# Review the implementation — Claude validates commit messages and test coverage
hydra review run 42-fix-bug

# Merge — pre-merge verification, rebase onto main, push, close issue
hydra merge run 42-fix-bug

Command Reference

Most commands set the terminal (xterm) title to show what hydra is doing. Help commands (help, --help, -h) do not modify the terminal title.

hydra init <source-repo-url> <design-dir>

Initializes a hydra project. Clones the source repository into ./repo, registers the design directory, and creates .hydra/config.json. If the design directory is empty, scaffolds the full directory structure with placeholder files. A convenience symlink ./design is created pointing to the design directory.

hydra edit <task-name>

Opens your editor to create or edit a task file. The editor is resolved from $VISUAL, then $EDITOR. The task name must not contain /.

hydra run <task-name>

Executes the full task lifecycle:

  1. Finds the pending task by name (supports group/name for grouped tasks)
  2. Acquires a per-task file lock — only one instance of the same task runs at a time; different tasks run concurrently
  3. Clones the source repo into a per-task work directory (work/{task-name}/)
  4. Creates a git branch hydra/<task-name>
  5. Assembles a document from rules.md, lint.md, the task content, functional.md, and commit instructions
  6. Runs the before command if configured in hydra.yml
  7. Opens a Claude session — Claude implements the changes, runs tests/lint, and commits with a descriptive message (GPG-signed if a signing key is configured)
  8. Verifies Claude committed (HEAD moved), records the SHA, pushes, and moves the task to review

Flags:

  • --no-auto-accept / -Y — Disable auto-accept (prompt for each tool call)
  • --no-plan / -P — Disable plan mode (skip plan approval, run fully autonomously)
  • --no-notify / -N — Disable desktop notifications (by default, Claude is instructed to send desktop notifications when it needs user confirmation)
  • --model — Override the Claude model (e.g. --model claude-haiku-4-5-20251001)

By default, hydra auto-accepts all tool calls and starts Claude in plan mode.

hydra group

Manage and run task groups.

hydra group list                   # List available groups
hydra group tasks <group-name>     # List all tasks in a group (all states)
hydra group run <group-name>       # Run all pending tasks in a group sequentially
hydra group merge <group-name>     # Merge all review/merge tasks in a group sequentially

hydra group list discovers and prints unique group names from pending tasks.

hydra group tasks shows all tasks in the named group across all states, with state labels.

hydra group run executes all pending tasks in the named group in alphabetical order. Each task gets its own cloned work directory. Stops on the first error.

hydra group merge merges all tasks in review or merge state in the named group, in alphabetical order. Each task rebases onto the updated main. Stops on the first error.

run and merge flags: --no-auto-accept / -Y, --no-plan / -P, --no-notify / -N, --model

hydra review

Manage and run interactive review sessions on tasks that have been run.

hydra review list                  # List tasks in review or merge state
hydra review view <task-name>      # Print task content
hydra review edit <task-name>      # Open task in editor
hydra review rm <task-name>        # Move task to abandoned
hydra review run <task-name>       # Run interactive review session
hydra review dev <task-name>       # Run the dev command in the task's work directory

hydra review run runs the before command if configured, then opens a Claude session where Claude reviews the implementation and validates:

  • Commit messages — reads the git log and verifies commit messages accurately describe the changes per the task document; amends if needed
  • Test coverage — identifies every feature described in the task document and verifies each has test coverage; adds missing tests

If Claude commits changes, they are pushed automatically. The task stays in review state after the session.

hydra review dev runs the dev command from hydra.yml in the task's work directory. The process runs until it exits or is terminated with Ctrl+C (SIGINT), SIGTERM, or SIGHUP. Use this to start a local dev server, file watcher, or hot-reload process while reviewing a task.

run flags: --no-auto-accept / -Y, --no-plan / -P, --no-notify / -N, --rebase / -r, --model

  • --rebase / -r — Rebase the task branch onto origin/main before the review session. Fails early if there are conflicts.
hydra test <task-name>

Runs the before command if configured, then opens a test-focused Claude session on a task in review state. Claude reads the task description and existing implementation, then:

  1. Identifies every feature, behavior, and edge case described in the task document
  2. Checks which features already have test coverage
  3. Adds tests for any features or behaviors that lack coverage
  4. Runs test and lint commands from hydra.yml and fixes any issues

If Claude commits changes, they are pushed automatically. The task stays in review state.

Flags: --no-auto-accept / -Y, --no-plan / -P, --no-notify / -N, --rebase / -r, --model

  • --rebase / -r — Rebase the task branch onto origin/main before running. Fails early if there are conflicts.
hydra clean <task-name>

Runs the clean command from hydra.yml in the task's work directory, regardless of which state the task is in. Use this to reset build artifacts, remove generated files, or restore the work directory to a clean state.

The task can be in any state (pending, review, merge, completed, or abandoned). The clean command must be configured in hydra.yml.

hydra merge

Manage and run the merge workflow for reviewed tasks.

hydra merge list                   # List tasks in review or merge state
hydra merge view <task-name>       # Print task content
hydra merge edit <task-name>       # Open task in editor
hydra merge rm <task-name>         # Move task to abandoned
hydra merge run <task-name>        # Run merge workflow

hydra merge run performs:

  1. Fetches origin to get the latest remote state
  2. Checks out the task's feature branch
  3. Aborts any in-progress rebase from a previous failed attempt
  4. Attempts to rebase the feature branch onto origin/main; if conflicts occur, the rebase is aborted and the conflict file list is recorded
  5. Runs the before command if configured in hydra.yml
  6. Opens a Claude session on the feature branch. Claude is explicitly told to stay on the feature branch and not push — the tool handles all branch switching and pushing. The document covers: conflict resolution (if needed, with a report of decisions made), commit message validation, test coverage verification, and test/lint commands
  7. Force-pushes the feature branch
  8. Checks out main, rebases it against origin/main, then rebases it against the feature branch to incorporate the task's commits, and pushes main
  9. Records the SHA, moves the task to completed, closes the remote issue if applicable, and deletes the remote feature branch

run flags: --no-auto-accept / -Y, --no-plan / -P, --no-notify / -N, --model

hydra reconcile

Reads all completed task documents, uses Claude to synthesize their requirements into functional.md, then removes the completed task files. This keeps functional.md as the project's living specification — a concise description of what the software does, organized by feature area rather than by task.

The workflow:

  1. Collects all completed tasks from state/completed/
  2. Clones/syncs the source repo into work/_reconcile/
  3. Fetches origin and rebases against origin/main to ensure the latest code is used
  4. Copies functional.md into the work directory for Claude to edit
  5. Opens a Claude session with the current functional spec, all completed task contents, and instructions to merge them
  6. Claude reads the codebase to understand what was actually implemented, then updates functional.md
  7. The updated functional.md is copied back to the design directory
  8. Completed task files are deleted

If no completed tasks exist, the command exits with an error. If Claude fails, no tasks are deleted and functional.md is not modified.

Flags: --no-auto-accept / -Y, --no-plan / -P, --no-notify / -N, --model

hydra verify

Uses Claude to verify that every requirement in functional.md is satisfied by the current codebase. This checks both implementation and test coverage — Claude verifies that each functional requirement is implemented correctly and has adequate test coverage.

The workflow:

  1. Reads functional.md (errors if empty)
  2. Clones/syncs the source repo into work/_verify/
  3. Fetches origin and rebases against origin/main to ensure the latest code is used
  4. Opens a Claude session where Claude reads the code and runs tests
  5. Claude checks that each requirement is implemented and has test coverage
  6. If the codebase has implemented and tested functionality not yet described in functional.md, Claude updates the specification file directly (at its absolute path) to keep it in sync with reality
  7. Claude creates verify-passed.txt if all requirements are met, or verify-failed.txt listing failures

If verification passes, prints a success message and automatically runs a sync (importing open issues and cleaning up completed tasks). If sync fails, a warning is printed but the verify command still succeeds. If verification fails, prints the failure details and exits with an error.

Flags: --no-auto-accept / -Y, --no-plan / -P, --no-notify / -N, --model

hydra other

Manage miscellaneous files in the other/ directory.

hydra other list           # List files in other/
hydra other add <name>     # Create a new file via editor
hydra other view <name>    # Print file content
hydra other edit <name>    # Edit an existing file
hydra other rm <name>      # Remove a file
hydra sync

Imports open issues from GitHub or Gitea as task files under tasks/issues/. Existing issues (matched by number) are skipped. The API type is auto-detected from the source repo URL or can be set via api_type in hydra.yml.

After importing, sync cleans up completed and abandoned tasks: remote feature branches are deleted and the corresponding issues are closed with a comment that includes the merge commit SHA.

Flags: --label — Filter issues by label (repeatable)

Auth: Set GITHUB_TOKEN (GitHub) or GITEA_TOKEN (Gitea) for private repos.

hydra fix

Scans the project for issues, reports them all, then prompts for confirmation before applying fixes.

  • Duplicate task names — Detects the same task name appearing in multiple states and prompts you to choose which copy to keep
  • Stale locks — Removes lock files held by dead processes
  • Wrong branches — Checks that work directories are on the correct task branch and checks them out if needed
  • Mismatched remotes — Reports work directories whose origin remote doesn't match the configured source repo
  • Missing state directories — Creates any missing state directories (review, merge, completed, abandoned)
  • Orphaned work directories — Recursively removes work directories that have no corresponding task
  • Stuck merge tasks — Moves tasks stuck in merge state (with no active lock) back to review

Flags:

  • --yes / -y — Skip confirmation prompt and apply fixes immediately
hydra list

Lists all pending tasks sorted alphabetically. Grouped tasks are displayed as group/name, keeping groups together.

hydra status

Shows tasks grouped by state (pending, review, merge, completed, abandoned) and any currently running task. Tasks within each state are sorted alphabetically.

Flags:

  • --json / -j — Output as JSON instead of YAML
  • --no-color — Disable syntax highlighting

When stdout is a TTY, output is syntax-highlighted using the active color theme.

hydra milestone

Manage milestones and their promises. Each milestone is a date-based markdown file where ## headings are promises. Hydra creates tasks for each promise and tracks their completion.

hydra milestone create [date]         # Create a new milestone (opens editor)
hydra milestone edit <date>           # Edit an existing milestone
hydra milestone list                  # List outstanding, delivered, and historical milestones
hydra milestone list --outstanding    # List only undelivered milestones
hydra milestone verify                # Verify due milestones (auto-delivers if all kept)
hydra milestone repair <date>         # Create missing task files for promises
hydra milestone deliver <date>        # Mark a milestone as delivered

hydra milestone create normalizes the date, opens your editor with a template, then creates task files under tasks/milestone-{date}/ for each ## heading.

hydra milestone verify checks all undelivered milestones with a date on or before today. For each promise, it checks whether the corresponding task has reached the completed state. Milestones where all promises are kept are automatically marked as delivered.

hydra milestone repair re-scans the milestone file and creates task files for any promises that don't have one yet. Existing tasks are left untouched.

hydra notify

Sends a desktop notification. Used by Claude during task runs to alert the user when input is needed.

hydra notify "Build failed, need guidance on test approach"
hydra notify -t "add-feature" "Rebase conflict in main.go — which side should I keep?"

Flags:

  • --title / -t — Notification title (defaults to "hydra")

Uses D-Bus on Linux and Notification Center on macOS. If a notify field is set in hydra.yml, that command is executed instead (see hydra.yml).

hydra completion

Print or manage shell tab completion.

hydra completion bash        # Print bash completion script to stdout
hydra completion zsh         # Print zsh completion script to stdout
hydra completion install     # Inject completion into your shell RC file
hydra completion uninstall   # Remove completion from your shell RC file

install injects a one-liner into your RC file (~/.bashrc or ~/.zshrc) that evals hydra completion <shell> at startup, guarded by a command -v hydra check so it no-ops if hydra is not installed. Supports bash and zsh, detected from $SHELL. On first run, hydra automatically prompts to install completion; the decision is saved in ~/.hydra/completion.

hydra.yml

If hydra.yml does not exist in the design directory, it is automatically created with commented-out placeholder commands. This happens during hydra init and whenever a runner command is executed.

# Model to use for Claude API calls (default: claude-opus-4-6)
model: claude-opus-4-6

# Issue sync API type: "github" or "gitea" (auto-detected from URL if omitted)
api_type: github

# Gitea instance URL (only needed for Gitea when URL can't be parsed)
gitea_url: https://gitea.example.com

# Optional timeout using Go duration strings (e.g. "30m", "2h").
# When set, Claude is instructed to commit partial progress and stop
# if running low on time.
timeout: "1h"

# Custom notification command. When set, `hydra notify` executes this
# command with title and message as arguments instead of using the
# built-in D-Bus/macOS notification.
notify: "my-notify-script"

# Teardown command. Run in a work directory before it is removed
# (e.g., during re-clone or orphan cleanup). Use this to stop services,
# release resources, or clean up external state tied to the work directory.
teardown: "docker compose down"

# Commands that Claude runs before committing.
#
# IMPORTANT: These commands may run concurrently across multiple hydra tasks,
# each in its own work directory (cloned repo). Make sure your test and lint
# commands are safe to run in parallel without trampling each other. Avoid
# commands that write to shared global state, fixed file paths outside the
# work directory, or shared network ports. Each invocation should be fully
# isolated to its own working tree.
commands:
  before: "make deps"
  clean: "make clean"
  dev: "npm run dev"
  test: "go test ./... -count=1"
  lint: "golangci-lint run ./..."

notify — An optional custom notification command. When set, hydra notify runs this command with the title and message as shell-quoted arguments (e.g., my-notify-script 'hydra' 'Build failed') instead of using the built-in D-Bus (Linux) or Notification Center (macOS) integration.

teardown — An optional command that runs in a work directory before it is removed. This is called when a work directory needs to be re-cloned (sync failure) or when hydra fix removes orphaned work directories. Use this for stopping services, releasing resources, or cleaning up external state tied to the work directory.

timeout — An optional duration string (using Go duration syntax, e.g. "30m", "2h", "1h30m") that sets a time limit for Claude sessions. When configured, Claude is instructed to commit any partial progress and stop gracefully if it is running low on time, rather than being killed mid-task.

Command keys:

  • before — Run by hydra before every Claude invocation (run, review run, test, merge run), after the git repository is cloned/prepared. Use this for dependency installation, code generation, or any setup that must happen before Claude starts working. If this command fails, the hydra command aborts.
  • clean — Run by hydra clean. Resets build artifacts or restores the work directory. Not run by Claude.
  • dev — Run by hydra review dev. Starts a long-lived process (dev server, file watcher, etc.) in the task's work directory. Not run by Claude.
  • test — Run by Claude before committing. Executes the project's test suite.
  • lint — Run by Claude before committing. Executes the project's linter.

Shell execution: All commands are executed via $SHELL -c "<command>" with the task's work directory as the current working directory. This means shell features like pipes, variable expansion, and subshells work in command strings. If $SHELL is not set, /bin/sh is used as a fallback.

Makefile fallback: If a command key is not configured in hydra.yml, hydra checks for a Makefile in the task's work directory. If a matching make target exists (e.g. before:, clean:, test:, lint:, dev:), hydra runs make <name> as a fallback. This means projects with a standard Makefile work out of the box without any hydra.yml configuration.

Concurrency safety: Hydra runs each task in its own cloned work directory under work/. Multiple tasks can run concurrently, so your test and lint commands must be safe to execute in parallel. Avoid hardcoded ports, shared temp directories, global lock files, or anything else that would collide when two instances run at the same time. Each command should operate entirely within the current working tree.

Dirty working tree tolerance: If a work directory has uncommitted changes (e.g., from a previously interrupted Claude session), hydra skips branch checkout and rebase operations and lets Claude continue working on the tree as-is. This prevents aborting a run due to leftover changes and allows Claude to pick up where it left off.

How Claude Commits

Hydra appends commit instructions to every document sent to Claude. These instructions tell Claude to:

  1. Run the test command if configured in hydra.yml
  2. Run the lint command if configured in hydra.yml
  3. Stage all changes with git add -A
  4. Commit with a descriptive message (GPG-signed if a signing key is available)

Claude is explicitly instructed to only use the exact test and lint commands from hydra.yml — it must not run individual test files, test functions, or lint checks outside of these commands.

After Claude returns, hydra verifies that a commit was made (HEAD moved). If Claude didn't commit, the run fails with an error. This approach lets Claude write meaningful commit messages that describe the actual changes rather than using a generic task name.

Interactive TUI

When hydra run, hydra review run, or hydra merge run starts a Claude session, it opens a full-screen terminal UI with streaming output and tool approval.

Keybindings
Key Action
Ctrl+C Cancel and quit
a Toggle auto-accept mode
Enter / y Approve tool call
Esc / n Reject tool call
Up / Down Scroll viewport
Left / Right Navigate Accept/Reject buttons

Work Directory Structure

Each task gets its own cloned repository under work/:

project/
├── work/
│   ├── add-feature/              # Ungrouped task work directory
│   ├── backend/
│   │   ├── add-api/              # Grouped task work directory
│   │   └── add-db/               # Another grouped task
│   └── issues/
│       └── 42-fix-bug/           # Issue task work directory

Work directories persist between runs. On subsequent runs, hydra syncs the existing directory (fetch) instead of re-cloning.

Global Configuration (~/.hydra.yml)

A global config file at ~/.hydra.yml lets you customize the TUI color scheme. Colors defined here override pywal and the built-in defaults.

colors:
  bg: "#1a1b26"
  fg: "#c0caf5"
  accent: "#7aa2f7"
  success: "#9ece6a"
  error: "#f7768e"
  warning: "#e0af68"
  muted: "#565f89"
  highlight: "#bb9af7"

All fields are optional. Missing fields fall through to pywal (~/.cache/wal/colors.json) if available, then to the built-in defaults.

Color priority (highest to lowest):

  1. ~/.hydra.yml
  2. pywal
  3. Built-in defaults

Shell Completion

Hydra supports tab completion for task names. All commands that accept a task name complete with the appropriate tasks for their state (e.g. hydra run completes pending tasks, hydra review run completes review tasks).

On first run, hydra prompts to inject completion into your shell RC file (~/.bashrc or ~/.zshrc, based on $SHELL). The decision is recorded in ~/.hydra/completion so you're only asked once. The injected line evals hydra completion <shell> at startup, guarded by command -v hydra so it no-ops if hydra is uninstalled.

You can also manage completion manually:

hydra completion bash        # Print bash completion script to stdout
hydra completion zsh         # Print zsh completion script to stdout
hydra completion install     # Inject eval into your shell RC file
hydra completion uninstall   # Remove it from your shell RC file

Both bash and zsh are supported. The shell type is detected from $SHELL.

Building & Releasing

# Build snapshot binaries locally
make snapshot

# Tag, push, and release via goreleaser
make full-release

# Override the version (default: vYYYY.MM.DD)
make full-release VERSION=v2026.02.26.1

License

MIT

Documentation

Overview

Package main is the entry point for the hydra CLI.

Directories

Path Synopsis
Package cmd defines the hydra CLI commands.
Package cmd defines the hydra CLI commands.
internal
claude
Package claude provides direct Anthropic API integration for hydra.
Package claude provides direct Anthropic API integration for hydra.
config
Package config manages hydra project configuration stored in the .hydra/ directory.
Package config manages hydra project configuration stored in the .hydra/ directory.
design
Package design handles reading and assembling design directory documents.
Package design handles reading and assembling design directory documents.
issues
Package issues imports open issues from GitHub or Gitea as design tasks.
Package issues imports open issues from GitHub or Gitea as design tasks.
lock
Package lock provides file-based locking with stale PID detection.
Package lock provides file-based locking with stale PID detection.
notify
Package notify provides desktop notification support.
Package notify provides desktop notification support.
repo
Package repo provides git operations via go-git with shell-out fallback.
Package repo provides git operations via go-git with shell-out fallback.
runner
Package runner orchestrates the full hydra task lifecycle.
Package runner orchestrates the full hydra task lifecycle.
taskrun
Package taskrun loads and executes named commands from a hydra.yml config.
Package taskrun loads and executes named commands from a hydra.yml config.
tui
Package tui provides the Bubbletea TUI for interactive Claude sessions.
Package tui provides the Bubbletea TUI for interactive Claude sessions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL