This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
CRITICAL: After finishing any code changes, you MUST run these quality checks:
make quality # Run tests, formatting, and lintingDo NOT skip these checks. Fix all errors before considering the task complete.
agent-exec is a Go CLI tool for automated iterative improvement with Claude Code, trading time and tokens for the best results.
- Designed for long-running AI agent tasks
- Runs Claude Code CLI in headless mode for automation
- Human-readable terminal output
- Cross-platform (macOS, Linux, Windows)
Critical dependency: Requires the claude CLI (Claude Code) installed and available in PATH.
make compile # Build to ./app executable
go build -o app ./cmd/agent-execmake install # Install to $GOPATH/bin
go install github.com/LinHanLab/agent-exec/cmd/agent-exec@latestmake quality # Run tests, formatting, and linting
go test ./... # Run all tests
go fmt ./... # Format code
golangci-lint run # Run lintergo test -v ./pkg/claude -run TestValidatePrompt
go test -v ./pkg/display -run TestFormatClaudeMessageThe tool executes Claude Code prompts via subprocess (claude CLI) and parses streaming JSON output to display formatted results and coordinate multi-step workflows.
cmd/agent-exec/ - CLI entry point using cobra
main.go- Application entryroot.go- Root command setupevolve.go- Evolve command configurationloop.go- Loop command configuration
pkg/claude/ - Claude CLI interaction
prompt.go- ExecutesclaudeCLI with system prompt optionsparser.go- Parses streaming JSON output (--output-format stream-json)validate.go- Input validationtypes.go- Type definitions
pkg/commands/ - Command implementations
evolve/evolve.go- Tournament evolution: creates competing git branches, runs improvement prompts, uses AI comparison to select winnersloop/loop.go- Simple iteration: runs same prompt N times with optional sleep
pkg/git/ - Git operations
branch.go- Branch creation, checkout, deletion, squashing
pkg/events/ - Event-driven architecture
emitter.go- Event emission interfacetypes.go- Event type definitions and data structures
pkg/display/ - Output formatting
console.go- Main display coordinatorformatter.go- Event-to-text conversionhandlers.go- Event-specific formatterscontent.go- Content filtering logictext.go- Text wrapping and formattingcolor.go- ANSI color helpers
The evolve command implements tournament-style code evolution:
- Initial Prompt: Creates branch A, runs initial prompt, squashes commits
- Evolution Loop (N iterations):
- Create challenger branch from current winner
- Run improvement prompt on challenger
- Switch to original branch, run comparison prompt
- Parse comparison result to determine loser
- Delete loser branch (unless
--debug-keep-branches) - Update current winner
- Result: Final branch contains best implementation
The comparison prompt asks Claude to identify which branch is worse. The parser in evolve.go:parseBranchFromResponse() expects the response to contain exactly one branch name.
Commands emit events through events.Emitter interface. The display package subscribes to these events and formats them for console output. This decouples command logic from presentation.
Event flow: Command → Emitter → Display → Formatter → Console
The tool spawns claude --verbose --output-format stream-json -p "<prompt>" as a subprocess and parses its stdout line-by-line. Each line is a JSON event (assistant_message, tool_use, tool_result, etc.). The parser extracts and emits these as internal events.
System prompts can be customized per command:
--system-prompt: Replace entire system prompt--append-system-prompt: Append to default system prompt
Both loop and evolve commands handle SIGINT/SIGTERM gracefully. They check for interrupts before each iteration and during sleep periods, emitting appropriate interrupt events before exiting with code 130.
Requires Go 1.25.3 (as specified in go.mod).
github.com/spf13/cobra- CLI frameworkgolang.org/x/term- Terminal utilities