HARVEY.md

Project-specific guidance for the harvey coding agent (Go).

Agent execution model

Harvey automatically executes certain structured outputs from your replies:

Tagged code blocks trigger a write proposal — if you include a fenced code block whose opening fence names a target file, Harvey proposes writing that file and asks the user to confirm (Y/n) before touching the filesystem. Parent directories are created as needed.

Two fence formats are recognized — pick whichever reads more naturally:

#!/bin/bash
echo "Hello World"

typescript libguides/auth.ts export async function authenticate(clientId: string): Promise<string> { // ... }

The file path must be on the opening fence line (after the language tag). A path in a comment inside the block (// libguides/auth.ts) is not picked up — Harvey only reads the fence tag.

Use this format whenever you want to create or update a file.

Session recording produces a .spmd screenplay script when active (-r flag at startup or /record start). Turns appear as USER / HARVEY dialogue blocks; actions and stats appear as Fountain notes ([[…]]).

Safe mode applies to all auto-executed commands. When safe mode is on (the default, shown as harvey > in the prompt), only commands in the configured allowlist will execute — others are blocked. When safe mode is off (shown as harvey [unsafe] > in red), all commands are permitted. Do not instruct the user to disable safe mode.

File reading capabilities

When asked to read a file, Harvey handles these formats automatically:

Never ask the user to convert a PDF to text before reading it. Call read_file with the .pdf path directly.

Documentation conventions

All exported functions, structs/types, interfaces, and constants must be documented with a /** ... */ block comment. Each comment must include:

/** Greet returns a greeting string for the given name.
 *
 * Parameters:
 *   name (string) — the person to greet
 *
 * Returns:
 *   string — a greeting message
 *
 * Example:
 *   msg := Greet("Alice")
 *   fmt.Println(msg) // "Hello, Alice!"
 */
func Greet(name string) string {
    return "Hello, " + name + "!"
}

Apply to every exported symbol — functions, structs, interfaces, type aliases, and constants. Do not omit the example section even for simple symbols.

Build & test

All commands should be run from inside harvey/.

# Build all programs
make build

# Run tests
go test

# Build a single program
go build -o bin/<name> cmd/<name>/*.go

# Generate version.go from codemeta.json
cmt codemeta.json version.go

# Build website (HTML from Markdown via pandoc)
make website

# Clean build artifacts
make clean

Key conventions