Git knows what changed. Timbers captures why.
AI agents write more code every day. Git tracks what they changed. Commit messages hint at how. But the why — the reasoning, trade-offs, and decisions — lives in session logs that get compacted and PR comments nobody reads twice. Six months later, you're staring at agent-written code with no idea why it was done that way.
Timbers is a development ledger that captures what/why/how as structured JSON files in .timbers/ — portable, queryable, and durable. Agents document their reasoning at the moment it exists. Humans harvest insights whenever they need them.
# Record work (agents or humans)
timbers log "Switched to cursor-based pagination" \
--why "Offset pagination skips rows when items are inserted between pages" \
--how "Opaque cursor tokens encoding created_at + id" \
--notes "Offset was simpler but users reported duplicate items in feeds. Cursors are stable under concurrent writes."
# Generate artifacts from your ledger
timbers draft decision-log --last 20 --model opusWebsite · Tutorial · Examples · Dev Blog
# One-liner (Linux/macOS)
curl -fsSL https://raw.githubusercontent.com/gorewood/timbers/main/install.sh | bash
# Or with Go
go install github.com/gorewood/timbers/cmd/timbers@latesttimbers init # One-time setup
timbers log "what" \ # Record work
--why "why" --how "how"
timbers query --last 10 # Query your ledger| Command | Purpose |
|---|---|
log |
Record work with what/why/how (optional --notes for deliberation) |
pending |
Show commits awaiting documentation |
query |
Search entries by time, tags, or content |
show |
Display a single entry |
export |
Export as JSON or Markdown |
draft |
Generate documents from your ledger (changelogs, reports, blogs) |
prime |
Session context injection for agents |
status |
Repository and ledger state |
All commands support --json. Write operations support --dry-run.
The draft command renders templates with your ledger entries, producing changelogs, reports, decision logs, and more — either by piping to an LLM CLI or with built-in LLM execution via --model.
# Pipe to any LLM CLI (uses your subscription, not API tokens)
timbers draft changelog --since 7d | claude -p --model opus
timbers draft standup --since 1d | gemini
timbers draft pr-description --range main..HEAD | codex exec -m gpt-5-codex-mini -
# Built-in LLM execution (for CI/CD or when no CLI is available)
timbers draft standup --since 1d --model opus
# List available templates
timbers draft --listBuilt-in templates: changelog, decision-log, devblog, pr-description, release-notes, sprint-report, standup
The decision-log template is particularly valuable — it extracts the why behind each change into an architectural decision record, enriched by --notes when agents capture their deliberation process. No other tool produces this from structured commit data.
Model guidance: Use opus for best output quality. For local generation, pipe to your LLM CLI of choice (claude -p, gemini, codex exec) — this uses your subscription instead of API tokens. For CI/CD, use --model opus with an API key. For high-volume batch operations (e.g., catchup over hundreds of commits), haiku or local models offer a lower-cost alternative.
Timbers uses ~/.config/timbers/ as its global configuration directory (%AppData%\timbers on Windows, or $XDG_CONFIG_HOME/timbers if set).
~/.config/timbers/
├── env # API keys (loaded as fallback when not in environment)
├── templates/ # Global custom templates (available in all repos)
For LLM-powered commands (draft --model, generate, catchup), set API keys in ~/.config/timbers/env:
mkdir -p ~/.config/timbers
cat > ~/.config/timbers/env << 'EOF'
ANTHROPIC_API_KEY=sk-ant-...
# OPENAI_API_KEY=sk-...
# GOOGLE_API_KEY=...
EOFEnv file resolution (first match wins, environment variables always take precedence):
$CWD/.env.local— per-repo override$CWD/.env— per-repo~/.config/timbers/env— global fallback
Create custom templates for project-specific or personal reporting needs:
# Global (available in all repos)
mkdir -p ~/.config/timbers/templates
cat > ~/.config/timbers/templates/weekly-standup.md << 'EOF'
Summarize this week's work for a standup meeting.
Format as Completed / In Progress / Blockers (3-5 bullets each).
## Entries
EOF
# Per-repo (takes precedence over global)
mkdir -p .timbers/templates
# Same format, placed in .timbers/templates/<name>.mdTemplate resolution: .timbers/templates/ → ~/.config/timbers/templates/ → built-in.
Timbers is designed for agents to use directly:
# Session start: agent gets context
timbers prime
# After work: agent documents it
timbers pending
timbers log "Added write-through caching to product queries" \
--why "Read-aside cache served stale data after writes — write-through keeps it consistent" \
--how "Cache update in same transaction as DB write, TTL fallback" \
--notes "Write-behind was faster but risks data loss on crash. Consistency wins over throughput here."Agent-friendly features: --json everywhere, prime for context injection, pending for clear signals, --notes for capturing deliberation, structured errors with recovery hints.
Agent environment support: Timbers is built and tested with Claude Code, which has the deepest integration via hooks that auto-inject timbers prime at session start. The CLI itself is agent-agnostic — any agent that can run shell commands can use timbers.
For non-Claude agents (Gemini CLI, Cursor, Windsurf, Codex, Kilo Code, Continue, Aider, etc.), add this to your agent's instruction file (AGENTS.md, GEMINI.md, .cursor/rules/, .windsurfrules, etc.):
At the start of every session, run `timbers prime` and follow the workflow it describes.
After completing work, run `timbers pending` to check for undocumented commits,
then `timbers log "what" --why "why" --how "how"` to document your work.
Use `--notes` when you explored alternatives or made a real choice.
Native hooks and setup commands for additional agent environments are planned for a future release.
Entries are JSON files in .timbers/, committed to your repo alongside your code. Each timbers log creates its own git commit — you'll see timbers: document ... commits interleaved with your code commits. The optional pre-commit hook enforces documentation before each new commit, so with hooks enabled you'll see roughly one entry commit per code commit. If commits slip through without documentation (hook bypassed, batch workflow, or hooks not installed), timbers log gracefully falls back to batch mode — one entry covers all pending commits.
This is intentional: separate commits enable reliable tracking of what's been documented, survive rebases and squash merges cleanly, and ensure entries travel with every clone without special configuration.
The trade-off is a noisier git log (roughly 2x the commit count with hooks). Agents handle this automatically (timbers filters entry commits internally). For humans who want a clean view:
git log --invert-grep --grep="^timbers: document"See docs/design-decisions.md for the full rationale, including alternatives that were evaluated and why they were rejected.
- Tutorial — Setup, catching up history, agent integration
- Publishing Artifacts — CI/CD for changelogs, reports, blogs
- Agent Reference — Command reference for agent integration
- LLM Commands — Draft, generate, catchup commands
- Spec — Full specification
- Agent DX Guide — CLI design patterns for agents
Timbers' own development ledger is used to generate these examples via timbers draft. Each link is a live artifact produced from real data:
| Artifact | Description |
|---|---|
| Changelog | Keep a Changelog format, grouped by type |
| Decision Log | ADR-style architectural decisions extracted from the why field |
| Standup | Daily standup from recent work |
| Release Notes | User-facing release notes |
| Sprint Report | Categorized sprint summary with scope and highlights |
| Dev Blog | Weekly dev blog posts (Carmack .plan style) |
A note on quality: Most of these entries were backfilled using
timbers catchup, which infers what/why/how from commit messages and diffs. Projects that usetimbers logfrom day one will produce significantly richer output — especially in the decision-log, where the why field matters most.
just setup # First-time setup
just check # Lint + test (required before commit)
just fix # Auto-fix lint issues
just run # Run the CLITimbers was built and tracked with Beads, a lightweight issue tracker stored in Git refs. Beads' CLI design — structured output, agent-friendly ergonomics, Git-native storage — directly inspired the patterns in timbers' Agent DX Guide. If you're building tools that agents need to use, studying beads is a great place to start.