# Detailed Agent Instructions for Beads Development **For project overview and quick start, see [AGENTS.md](AGENTS.md)** This document contains detailed operational instructions for AI agents working on beads development, testing, and releases. ## Development Guidelines ### Code Standards - **Go version**: 1.24+ - **Linting**: `golangci-lint run ./...` (baseline warnings documented in [docs/LINTING.md](docs/LINTING.md)) - **Testing**: All new features need tests (`go test -short ./...` for local, full tests run in CI) - **Documentation**: Update relevant .md files ### File Organization ``` beads/ ├── cmd/bd/ # CLI commands ├── internal/ │ ├── types/ # Core data types │ └── storage/ # Storage layer │ └── sqlite/ # SQLite implementation ├── examples/ # Integration examples └── *.md # Documentation ``` ### Testing Workflow **IMPORTANT:** Never pollute the production database with test issues! **For manual testing**, use the `BEADS_DB` environment variable to point to a temporary database: ```bash # Create test issues in isolated database BEADS_DB=/tmp/test.db ./bd init --quiet --prefix test BEADS_DB=/tmp/test.db ./bd create "Test issue" -p 1 # Or for quick testing BEADS_DB=/tmp/test.db ./bd create "Test feature" -p 1 ``` **For automated tests**, use `t.TempDir()` in Go tests: ```go func TestMyFeature(t *testing.T) { tmpDir := t.TempDir() testDB := filepath.Join(tmpDir, ".beads", "beads.db") s := newTestStore(t, testDB) // ... test code } ``` **Warning:** bd will warn you when creating issues with "Test" prefix in the production database. Always use `BEADS_DB` for manual testing. ### Before Committing 1. **Run tests**: `go test -short ./...` (full tests run in CI) 2. **Run linter**: `golangci-lint run ./...` (ignore baseline warnings) 3. **Update docs**: If you changed behavior, update README.md or other docs 4. **Commit**: Issues auto-sync to `.beads/issues.jsonl` and import after pull ### Commit Message Convention When committing work for an issue, include the issue ID in parentheses at the end: ```bash git commit -m "Fix auth validation bug (bd-abc)" git commit -m "Add retry logic for database locks (bd-xyz)" ``` This enables `bd doctor` to detect **orphaned issues** - work that was committed but the issue wasn't closed. The doctor check cross-references open issues against git history to find these orphans. ### Git Workflow **Auto-sync provides batching!** bd automatically: - **Exports** to JSONL after CRUD operations (30-second debounce for batching) - **Imports** from JSONL when it's newer than DB (e.g., after `git pull`) - **Daemon commits/pushes** every 5 seconds (if `--auto-commit` / `--auto-push` enabled) The 30-second debounce provides a **transaction window** for batch operations - multiple issue changes within 30 seconds get flushed together, avoiding commit spam. ### Git Integration **Auto-sync**: bd automatically exports to JSONL (30s debounce), imports after `git pull`, and optionally commits/pushes. **Protected branches**: Use `bd init --branch beads-metadata` to commit to separate branch. See [docs/PROTECTED_BRANCHES.md](docs/PROTECTED_BRANCHES.md). **Git worktrees**: Enhanced support with shared database architecture. Use `bd --no-daemon` if daemon warnings appear. See [docs/GIT_INTEGRATION.md](docs/GIT_INTEGRATION.md). **Merge conflicts**: Rare with hash IDs. If conflicts occur, use `git checkout --theirs/.beads/issues.jsonl` and `bd import`. See [docs/GIT_INTEGRATION.md](docs/GIT_INTEGRATION.md). ## Landing the Plane **When the user says "let's land the plane"**, you MUST complete ALL steps below. The plane is NOT landed until `git push` succeeds. NEVER stop before pushing. NEVER say "ready to push when you are!" - that is a FAILURE. **MANDATORY WORKFLOW - COMPLETE ALL STEPS:** 1. **File beads issues for any remaining work** that needs follow-up 2. **Ensure all quality gates pass** (only if code changes were made): - Run `make lint` or `golangci-lint run ./...` (if pre-commit installed: `pre-commit run --all-files`) - Run `make test` or `go test ./...` - File P0 issues if quality gates are broken 3. **Update beads issues** - close finished work, update status 4. **PUSH TO REMOTE - NON-NEGOTIABLE** - This step is MANDATORY. Execute ALL commands below: ```bash # Pull first to catch any remote changes git pull --rebase # If conflicts in .beads/issues.jsonl, resolve thoughtfully: # - git checkout --theirs .beads/issues.jsonl (accept remote) # - bd import -i .beads/issues.jsonl (re-import) # - Or manual merge, then import # Sync the database (exports to JSONL, commits) bd sync # MANDATORY: Push everything to remote # DO NOT STOP BEFORE THIS COMMAND COMPLETES git push # MANDATORY: Verify push succeeded git status # MUST show "up to date with origin/main" ``` **CRITICAL RULES:** - The plane has NOT landed until `git push` completes successfully - NEVER stop before `git push` - that leaves work stranded locally - NEVER say "ready to push when you are!" - YOU must push, not the user - If `git push` fails, resolve the issue and retry until it succeeds - The user is managing multiple agents - unpushed work breaks their coordination workflow 5. **Clean up git state** - Clear old stashes and prune dead remote branches: ```bash git stash clear # Remove old stashes git remote prune origin # Clean up deleted remote branches ``` 6. **Verify clean state** - Ensure all changes are committed AND PUSHED, no untracked files remain 7. **Choose a follow-up issue for next session** - Provide a prompt for the user to give to you in the next session - Format: "Continue work on bd-X: [issue title]. [Brief context about what's been done and what's next]" **REMEMBER: Landing the plane means EVERYTHING is pushed to remote. No exceptions. No "ready when you are". PUSH IT.** **Example "land the plane" session:** ```bash # 1. File remaining work bd create "Add integration tests for sync" -t task -p 2 --json # 2. Run quality gates (only if code changes were made) go test -short ./... golangci-lint run ./... # 3. Close finished issues bd close bd-42 bd-43 --reason "Completed" --json # 4. PUSH TO REMOTE - MANDATORY, NO STOPPING BEFORE THIS IS DONE git pull --rebase # If conflicts in .beads/issues.jsonl, resolve thoughtfully: # - git checkout --theirs .beads/issues.jsonl (accept remote) # - bd import -i .beads/issues.jsonl (re-import) # - Or manual merge, then import bd sync # Export/import/commit git push # MANDATORY - THE PLANE IS STILL IN THE AIR UNTIL THIS SUCCEEDS git status # MUST verify "up to date with origin/main" # 5. Clean up git state git stash clear git remote prune origin # 6. Verify everything is clean and pushed git status # 7. Choose next work bd ready --json bd show bd-44 --json ``` **Then provide the user with:** - Summary of what was completed this session - What issues were filed for follow-up - Status of quality gates (all passing / issues filed) - Confirmation that ALL changes have been pushed to remote - Recommended prompt for next session **CRITICAL: Never end a "land the plane" session without successfully pushing. The user is coordinating multiple agents and unpushed work causes severe rebase conflicts.** ## Agent Session Workflow **WARNING: DO NOT use `bd edit`** - it opens an interactive editor ($EDITOR) which AI agents cannot use. Use `bd update` with flags instead: ```bash bd update --description "new description" bd update --title "new title" bd update --design "design notes" bd update --notes "additional notes" bd update --acceptance "acceptance criteria" ``` **IMPORTANT for AI agents:** When you finish making issue changes, always run: ```bash bd sync ``` This immediately: 1. Exports pending changes to JSONL (no 30s wait) 2. Commits to git 3. Pulls from remote 4. Imports any updates 5. Pushes to remote **Example agent session:** ```bash # Make multiple changes (batched in 30-second window) bd create "Fix bug" -p 1 bd create "Add tests" -p 1 bd update bd-42 --status in_progress bd close bd-40 --reason "Completed" # Force immediate sync at end of session bd sync # Now safe to end session - everything is committed and pushed ``` **Why this matters:** - Without `bd sync`, changes sit in 30-second debounce window - User might think you pushed but JSONL is still dirty - `bd sync` forces immediate flush/commit/push **STRONGLY RECOMMENDED: Install git hooks for automatic sync** (prevents stale JSONL problems): ```bash # One-time setup - run this in each beads workspace bd hooks install ``` This installs: - **pre-commit** - Flushes pending changes immediately before commit (bypasses 30s debounce) - **post-merge** - Imports updated JSONL after pull/merge (guaranteed sync) - **pre-push** - Exports database to JSONL before push (prevents stale JSONL from reaching remote) - **post-checkout** - Imports JSONL after branch checkout (ensures consistency) **Why git hooks matter:** Without the pre-push hook, you can have database changes committed locally but stale JSONL pushed to remote, causing multi-workspace divergence. The hooks guarantee DB ↔ JSONL consistency. **Note:** Hooks are embedded in the bd binary and work for all bd users (not just source repo users). ## Common Development Tasks ### CLI Design Principles **Minimize cognitive overload.** Every new command, flag, or option adds cognitive burden for users. Before adding anything: 1. **Recovery/fix operations → `bd doctor --fix`**: Don't create separate commands like `bd recover` or `bd repair`. Doctor already detects problems - let `--fix` handle remediation. This keeps all health-related operations in one discoverable place. 2. **Prefer flags on existing commands**: Before creating a new command, ask: "Can this be a flag on an existing command?" Example: `bd list --stale` instead of `bd stale`. 3. **Consolidate related operations**: Related operations should live together. Daemon management uses `bd daemons {list,health,killall}`, not separate top-level commands. 4. **Count the commands**: Run `bd --help` and count. If we're approaching 30+ commands, we have a discoverability problem. Consider subcommand grouping. 5. **New commands need strong justification**: A new command should represent a fundamentally different operation, not just a convenience wrapper. ### Adding a New Command 1. Create file in `cmd/bd/` 2. Add to root command in `cmd/bd/main.go` 3. Implement with Cobra framework 4. Add `--json` flag for agent use 5. Add tests in `cmd/bd/*_test.go` 6. Document in README.md ### Adding Storage Features 1. Update schema in `internal/storage/sqlite/schema.go` 2. Add migration if needed 3. Update `internal/types/types.go` if new types 4. Implement in `internal/storage/sqlite/sqlite.go` 5. Add tests 6. Update export/import in `cmd/bd/export.go` and `cmd/bd/import.go` ### Adding Examples 1. Create directory in `examples/` 2. Add README.md explaining the example 3. Include working code 4. Link from `examples/README.md` 5. Mention in main README.md ## Building and Testing ```bash # Build go build -o bd ./cmd/bd # Test (short - for local development) go test -short ./... # Test with coverage (full tests - for CI) go test -coverprofile=coverage.out ./... go tool cover -html=coverage.out # Run locally ./bd init --prefix test ./bd create "Test issue" -p 1 ./bd ready ``` ## Version Management **IMPORTANT**: When the user asks to "bump the version" or mentions a new version number (e.g., "bump to 0.9.3"), use the version bump script: ```bash # Preview changes (shows diff, doesn't commit) ./scripts/bump-version.sh 0.9.3 # Auto-commit the version bump ./scripts/bump-version.sh 0.9.3 --commit git push origin main ``` **What it does:** - Updates ALL version files (CLI, plugin, MCP server, docs) in one command - Validates semantic versioning format - Shows diff preview - Verifies all versions match after update - Creates standardized commit message **User will typically say:** - "Bump to 0.9.3" - "Update version to 1.0.0" - "Rev the project to 0.9.4" - "Increment the version" **You should:** 1. Run `./scripts/bump-version.sh --commit` 2. Push to GitHub 3. Confirm all versions updated correctly **Files updated automatically:** - `cmd/bd/version.go` - CLI version - `claude-plugin/.claude-plugin/plugin.json` - Plugin version - `.claude-plugin/marketplace.json` - Marketplace version - `integrations/beads-mcp/pyproject.toml` - MCP server version - `README.md` - Documentation version - `PLUGIN.md` - Version requirements **Why this matters:** We had version mismatches (bd-66) when only `version.go` was updated. This script prevents that by updating all components atomically. See `scripts/README.md` for more details. ## Release Process (Maintainers) **Automated (Recommended):** ```bash # One command to do everything (version bump, tests, tag, Homebrew update, local install) ./scripts/release.sh 0.9.3 ``` This handles the entire release workflow automatically, including waiting ~5 minutes for GitHub Actions to build release artifacts. See [scripts/README.md](scripts/README.md) for details. **Manual (Step-by-Step):** 1. Bump version: `./scripts/bump-version.sh --commit` 2. Update CHANGELOG.md with release notes 3. Run tests: `go test -short ./...` (CI runs full suite) 4. Push version bump: `git push origin main` 5. Tag release: `git tag v && git push origin v` 6. Update Homebrew: `./scripts/update-homebrew.sh ` (waits for GitHub Actions) 7. Verify: `brew update && brew upgrade bd && bd version` See [docs/RELEASING.md](docs/RELEASING.md) for complete manual instructions. ## Checking GitHub Issues and PRs **IMPORTANT**: When asked to check GitHub issues or PRs, use command-line tools like `gh` instead of browser/playwright tools. **Preferred approach:** ```bash # List open issues with details gh issue list --limit 30 # List open PRs gh pr list --limit 30 # View specific issue gh issue view 201 ``` **Then provide an in-conversation summary** highlighting: - Urgent/critical issues (regressions, bugs, broken builds) - Common themes or patterns - Feature requests with high engagement - Items that need immediate attention **Why this matters:** - Browser tools consume more tokens and are slower - CLI summaries are easier to scan and discuss - Keeps the conversation focused and efficient - Better for quick triage and prioritization **Do NOT use:** `browser_navigate`, `browser_snapshot`, or other playwright tools for GitHub PR/issue reviews unless specifically requested by the user. ## Questions? - Check existing issues: `bd list` - Look at recent commits: `git log --oneline -20` - Read the docs: README.md, ADVANCED.md, EXTENDING.md - Create an issue if unsure: `bd create "Question: ..." -t task -p 2` ## Important Files - **README.md** - Main documentation (keep this updated!) - **EXTENDING.md** - Database extension guide - **ADVANCED.md** - JSONL format analysis - **CONTRIBUTING.md** - Contribution guidelines - **SECURITY.md** - Security policy