Project-specific guidance for the harvey coding agent (Go).
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.
When asked to read a file, Harvey handles these formats automatically:
pages parameter to read a subset
(e.g. "1-10" or "5").Never ask the user to convert a PDF to text before reading it. Call
read_file with the .pdf path directly.
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.
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 cleanversion.go is generated by
cmt — do not edit by hand.bin/, dist/, man/,
testout/ are gitignored build artifacts.harvey/*.go); CLI
entry points go under cmd/<program>/.CLAUDE.md for full toolchain dependencies
and release targets.