4.6 KiB
AGENTS Instructions
goose is an AI agent framework in Rust with CLI and Electron desktop interfaces.
Setup
source bin/activate-hermit
cargo build
Commands
Build
cargo build # debug
cargo build --release # release
just release-binary # release + openapi
Test
cargo test # all tests
cargo test -p goose # specific crate
cargo test --package goose --test mcp_integration_test
just record-mcp-tests # record MCP
Lint/Format
cargo fmt
cargo clippy --all-targets -- -D warnings
UI
just generate-openapi # after server changes
just run-ui # start desktop
cd ui/desktop && pnpm test # test UI
Git
git commit -s # required for DCO sign-off
Structure
crates/
├── goose # core logic
├── goose-acp-macros # ACP proc macros
├── goose-cli # CLI entry
├── goose-server # backend (binary: goosed)
├── goose-mcp # MCP extensions
├── goose-test # test utilities
└── goose-test-support # test helpers
evals/open-model-gym/ # benchmarking / evals
ui/desktop/ # Electron app
Development Loop
# 1. source bin/activate-hermit
# 2. Make changes
# 3. cargo fmt
Run these only if the user has asked you to build/test your changes:
# 1. cargo build
# 2. cargo test -p <crate>
# 3. cargo clippy --all-targets -- -D warnings
# 4. [if server] just generate-openapi
Rules
Test: Prefer tests/ folder, e.g. crates/goose/tests/
Test: When adding features, update goose-self-test.yaml, rebuild, then run goose run --recipe goose-self-test.yaml to validate
Error: Use anyhow::Result
Provider: Implement Provider trait see providers/base.rs
MCP: Extensions in crates/goose-mcp/
Server: Changes need just generate-openapi
Code Quality
Comments: Write self-documenting code - prefer clear names over comments
Comments: Never add comments that restate what code does
Comments: Only comment for complex algorithms, non-obvious business logic, or "why" not "what"
Simplicity: Don't make things optional that don't need to be - the compiler will enforce
Simplicity: Booleans should default to false, not be optional
Errors: Don't add error context that doesn't add useful information (e.g., .context("Failed to X") when error already says it failed)
Simplicity: Avoid overly defensive code - trust Rust's type system
Logging: Clean up existing logs, don't add more unless for errors or security events
Ink / Terminal UI (ui/text)
Ink renders React to a fixed character grid — not a browser. Content that exceeds a Box's dimensions is NOT clipped; it visually overflows into neighboring cells and breaks the layout.
Ink-Text: Never use wrap="wrap" inside a fixed-height Box — wrapped text can exceed the
Box height and bleed into adjacent components. Use wrap="truncate" and pre-truncate the
string to fit the available character budget (lines × width).
Ink-Layout: When changing card/cell dimensions, always recalculate how much content fits.
Account for borders (2 chars), padding, margins, and sibling elements when computing the
remaining space for dynamic text.
Ink-Overflow: Ink has no overflow: hidden. The only way to prevent overflow is to ensure
content never exceeds the container size — truncate text, limit list items, or cap height.
Ink-FlexGrow: Avoid flexGrow={1} on text containers inside fixed-height cards — the text
will try to fill available space but Ink won't clip it if it exceeds the boundary.
Ink-HeightBudget: When computing how many rows/items fit vertically, count EVERY line used
by headers, footers, margins, borders, and scroll indicators. Under-reserving vertical
space (e.g., height - 8 when chrome actually uses 16 lines) causes Ink to squeeze out
margins between items, making borders collapse. Always audit the actual line count.
Ink-TrailingMargin: Don't apply marginBottom to the last item in a list — it wastes a
line and can push content out of the container. Use conditional margins or container gap.
Never
Never: Edit ui/desktop/openapi.json manually
Never: Edit Cargo.toml use cargo add
Never: Skip cargo fmt
Never: Merge without running clippy
Never: Comment self-evident operations (// Initialize, // Return result), getters/setters, constructors, or standard Rust idioms
Entry Points
- CLI: crates/goose-cli/src/main.rs
- Server: crates/goose-server/src/main.rs
- UI: ui/desktop/src/main.ts
- Agent: crates/goose/src/agents/agent.rs