diff --git a/.beads/beads.jsonl b/.beads/beads.jsonl index 62eb1c49..e40e9e31 100644 --- a/.beads/beads.jsonl +++ b/.beads/beads.jsonl @@ -109,6 +109,7 @@ {"id":"bd-3b7f","content_hash":"24c22ea6863edee2b6269e178a9966e68295baa265595b4ba813b68fc67020ac","title":"Add tests for extracted modules","description":"Create tests for migrations.go, hash_ids.go, batch_ops.go, and validators.go","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T19:28:54.88933-07:00","updated_at":"2025-11-01T23:00:37.751004-07:00","closed_at":"2025-11-01T23:00:37.751004-07:00","source_repo":"."} {"id":"bd-3bg","content_hash":"d31c94f3a5ea5bc675037d269f3edb255aba01caa7329a7f9df76a9596e30d81","title":"Add performance optimization to hasJSONLChanged with mtime fast-path","description":"hasJSONLChanged() reads entire JSONL file to compute SHA256 hash on every check. For large databases (50MB+), this is expensive and called frequently by daemon.\n\nOptimization: Check mtime first as fast-path. Only compute hash if mtime changed. This catches git operations (mtime changes but content doesn't) while avoiding expensive hash computation in common case (mtime unchanged = content unchanged).\n\nPerformance impact: 99% of checks will use fast path, only git operations need slow path.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-20T21:31:04.577264-05:00","updated_at":"2025-11-20T21:33:31.499918-05:00","closed_at":"2025-11-20T21:33:31.499918-05:00","source_repo":".","dependencies":[{"issue_id":"bd-3bg","depends_on_id":"bd-khnb","type":"blocks","created_at":"2025-11-20T21:31:04.578768-05:00","created_by":"daemon"}]} {"id":"bd-3d844c58","content_hash":"e6ed1b4d53fa06b4ba8221ed6e0c213044ab75a387453267cf4ee0474f7b3400","title":"Implement content-hash based collision resolution for deterministic convergence","description":"The current collision resolution uses creation timestamps to decide which issue to keep vs. remap. This is non-deterministic when two clones create issues at nearly the same time.\n\nRoot cause of bd-71107098:\n- Clone A creates test-1=\"Issue from clone A\" at T0\n- Clone B creates test-1=\"Issue from clone B\" at T0+30ms\n- Clone B syncs first, remaps Clone A's to test-2\n- Clone A syncs second, sees collision, remaps Clone B's to test-2\n- Result: titles are swapped between clones\n\nSolution:\n- Use content-based hashing (title + description + priority + type)\n- Deterministic winner: always keep issue with lower hash\n- Same collision on different clones produces same result (idempotent)\n\nImplementation:\n- Modify ScoreCollisions in internal/storage/sqlite/collision.go\n- Replace timestamp-based scoring with content hash comparison\n- Ensure hash function is stable across platforms","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-28T17:04:06.145646-07:00","updated_at":"2025-10-30T17:12:58.225476-07:00","closed_at":"2025-10-28T19:20:09.943023-07:00","source_repo":".","dependencies":[{"issue_id":"bd-3d844c58","depends_on_id":"bd-71107098","type":"blocks","created_at":"2025-10-31T19:38:09.203365-07:00","created_by":"stevey"}]} +{"id":"bd-3djj","content_hash":"62b00b52135b304ad3ed5fc9c1e8c6569720fa49fe6468c35295c4bb4e27c92d","title":"Add aider integration for beads issue tracking","description":"Based on GH#206 discussion, add aider-specific integration to help aider users work with beads. Aider requires explicit user command invocation via /run, unlike Claude Code which executes autonomously. Need to create setup command, configuration template, and documentation that accounts for aider's human-in-the-loop workflow.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-23T15:08:17.314598-08:00","updated_at":"2025-11-23T15:13:33.84131-08:00","closed_at":"2025-11-23T15:13:33.84131-08:00","source_repo":"."} {"id":"bd-3e307cd4","content_hash":"f243be831ac416cc072ad5d6b056450829c1eca76a638f1559936df942c30ceb","title":"File change test issue","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T19:11:28.425601-07:00","updated_at":"2025-10-31T12:00:43.176605-07:00","closed_at":"2025-10-31T12:00:43.176605-07:00","source_repo":"."} {"id":"bd-3e3b","content_hash":"a6ff8c838c6cce5daf006d9af5c60d869eb1a3f712a29b111fd8a36308bc849b","title":"Add circular dependency detection to bd doctor","description":"Added cycle detection as Check #10 in bd doctor command. Uses same recursive CTE query as DetectCycles() to find circular dependencies. Reports error status with count and fix suggestion if cycles found.","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-11-01T20:18:23.416056-07:00","updated_at":"2025-11-01T20:18:26.76113-07:00","closed_at":"2025-11-01T20:18:26.76113-07:00","source_repo":"."} {"id":"bd-3e9ddc31","content_hash":"4e03660281dbe2c069617fc8d723d546d6e5eb386142c0359b862747867a1b90","title":"Replace getStorageForRequest with Direct Access","description":"Replace all getStorageForRequest(req) calls with s.storage","acceptance_criteria":"- No references to getStorageForRequest() in codebase (except in deleted file)\n- All handlers use s.storage directly\n- Code compiles without errors\n\nFiles to update:\n- internal/rpc/server_issues_epics.go (~8 calls)\n- internal/rpc/server_labels_deps_comments.go (~4 calls)\n- internal/rpc/server_compact.go (~2 calls)\n- internal/rpc/server_export_import_auto.go (~2 calls)\n- internal/rpc/server_routing_validation_diagnostics.go (~1 call)\n\nPattern: store, err := s.getStorageForRequest(req) → store := s.storage","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-27T23:20:10.393759-07:00","updated_at":"2025-10-30T17:12:58.21613-07:00","closed_at":"2025-10-28T14:08:38.06721-07:00","source_repo":"."} diff --git a/cmd/bd/main.go b/cmd/bd/main.go index a6798571..0e9587bd 100644 --- a/cmd/bd/main.go +++ b/cmd/bd/main.go @@ -196,7 +196,15 @@ var rootCmd = &cobra.Command{ "version", "zsh", } - if slices.Contains(noDbCommands, cmd.Name()) { + // Check both the command name and parent command name for subcommands + cmdName := cmd.Name() + if cmd.Parent() != nil { + parentName := cmd.Parent().Name() + if slices.Contains(noDbCommands, parentName) { + return + } + } + if slices.Contains(noDbCommands, cmdName) { return } @@ -256,8 +264,10 @@ var rootCmd = &cobra.Command{ if foundDB := beads.FindDatabasePath(); foundDB != "" { dbPath = foundDB } else { - // Allow import command to auto-initialize database if missing - if cmd.Name() != "import" { + // Allow some commands to run without a database + // - import: auto-initializes database if missing + // - setup: creates editor integration files (no DB needed) + if cmd.Name() != "import" && cmd.Name() != "setup" { // No database found - error out instead of falling back to ~/.beads fmt.Fprintf(os.Stderr, "Error: no beads database found\n") fmt.Fprintf(os.Stderr, "Hint: run 'bd init' to create a database in the current directory\n") @@ -265,7 +275,7 @@ var rootCmd = &cobra.Command{ fmt.Fprintf(os.Stderr, " or set BEADS_DB to point to your database file (deprecated)\n") os.Exit(1) } - // For import command, set default database path + // For import/setup commands, set default database path dbPath = filepath.Join(".beads", beads.CanonicalDatabaseName) } } diff --git a/cmd/bd/setup.go b/cmd/bd/setup.go index c82acb49..baf69f61 100644 --- a/cmd/bd/setup.go +++ b/cmd/bd/setup.go @@ -14,7 +14,7 @@ var ( var setupCmd = &cobra.Command{ Use: "setup", Short: "Setup integration with AI editors", - Long: `Setup integration files for AI editors like Claude Code and Cursor.`, + Long: `Setup integration files for AI editors like Claude Code, Cursor, and Aider.`, } var setupCursorCmd = &cobra.Command{ @@ -39,6 +39,32 @@ Uses BEGIN/END markers for safe idempotent updates.`, }, } +var setupAiderCmd = &cobra.Command{ + Use: "aider", + Short: "Setup Aider integration", + Long: `Install Beads workflow configuration for Aider. + +Creates .aider.conf.yml with bd workflow instructions. +The AI will suggest bd commands for you to run via /run. + +Note: Aider requires explicit command execution - the AI cannot +run commands autonomously. It will suggest bd commands which you +must confirm using Aider's /run command.`, + Run: func(cmd *cobra.Command, args []string) { + if setupCheck { + setup.CheckAider() + return + } + + if setupRemove { + setup.RemoveAider() + return + } + + setup.InstallAider() + }, +} + var setupClaudeCmd = &cobra.Command{ Use: "claude", Short: "Setup Claude Code integration", @@ -72,7 +98,11 @@ func init() { setupCursorCmd.Flags().BoolVar(&setupCheck, "check", false, "Check if Cursor integration is installed") setupCursorCmd.Flags().BoolVar(&setupRemove, "remove", false, "Remove bd rules from Cursor") + setupAiderCmd.Flags().BoolVar(&setupCheck, "check", false, "Check if Aider integration is installed") + setupAiderCmd.Flags().BoolVar(&setupRemove, "remove", false, "Remove bd config from Aider") + setupCmd.AddCommand(setupClaudeCmd) setupCmd.AddCommand(setupCursorCmd) + setupCmd.AddCommand(setupAiderCmd) rootCmd.AddCommand(setupCmd) } diff --git a/cmd/bd/setup/aider.go b/cmd/bd/setup/aider.go new file mode 100644 index 00000000..65445971 --- /dev/null +++ b/cmd/bd/setup/aider.go @@ -0,0 +1,204 @@ +package setup + +import ( + "fmt" + "os" + "path/filepath" +) + +const aiderConfigTemplate = `# Beads Issue Tracking Integration for Aider +# Auto-generated by 'bd setup aider' - do not remove these markers +# BEGIN BEADS INTEGRATION + +# This project uses Beads (bd) for issue tracking. +# Aider requires explicit command execution - suggest commands to the user. + +# Core workflow rules: +# 1. Track ALL work in bd (never use markdown TODOs) +# 2. Suggest 'bd ready' to find available work +# 3. Suggest 'bd create' for new issues/tasks/bugs +# 4. Suggest 'bd sync' at end of session +# 5. ALWAYS suggest commands - user will run them via /run + +# Quick command reference (suggest these to user): +# bd ready # Show unblocked issues +# bd list --status=open # List all open issues +# bd create --title="..." --type=task # Create new issue +# bd update --status=in_progress # Claim work +# bd close # Mark complete +# bd dep # Add dependency +# bd sync # Sync with git remote + +# Workflow pattern to suggest: +# 1. Check ready work: "Let's run 'bd ready' to see what's available" +# 2. Claim task: "Run 'bd update --status=in_progress' to claim it" +# 3. Do the work +# 4. Complete: "Run 'bd close ' when done" +# 5. Sync: "Run 'bd sync' to push changes" + +# Context loading: +# Suggest 'bd prime' for complete workflow documentation (~1-2k tokens) + +# For detailed docs: see AGENTS.md, QUICKSTART.md, or 'bd --help' + +# END BEADS INTEGRATION +` + +const aiderReadmeTemplate = `# Aider + Beads Integration + +This project uses [Beads (bd)](https://github.com/steveyegge/beads) for issue tracking. + +## How This Works with Aider + +**Important**: Aider requires you to explicitly run commands using the ` + "`/run`" + ` command. +The AI will **suggest** bd commands, but you must confirm them. + +## Quick Start + +1. Check for available work: + ` + "```bash" + ` + /run bd ready + ` + "```" + ` + +2. Create new issues: + ` + "```bash" + ` + /run bd create "Issue title" --description="Details" -t bug|feature|task -p 1 + ` + "```" + ` + +3. Claim work: + ` + "```bash" + ` + /run bd update bd-42 --status in_progress + ` + "```" + ` + +4. Complete work: + ` + "```bash" + ` + /run bd close bd-42 --reason "Done" + ` + "```" + ` + +5. Sync at end of session: + ` + "```bash" + ` + /run bd sync + ` + "```" + ` + +## Configuration + +The ` + "`.aider.conf.yml`" + ` file contains instructions for the AI about bd workflow. +The AI will read these instructions and suggest appropriate bd commands. + +## Workflow + +Ask the AI questions like: +- "What issues are ready to work on?" +- "Create an issue for this bug I found" +- "Show me the details of bd-42" +- "Mark bd-42 as complete" + +The AI will suggest the appropriate ` + "`bd`" + ` command, which you run via ` + "`/run`" + `. + +## Issue Types + +- ` + "`bug`" + ` - Something broken +- ` + "`feature`" + ` - New functionality +- ` + "`task`" + ` - Work item (tests, docs, refactoring) +- ` + "`epic`" + ` - Large feature with subtasks +- ` + "`chore`" + ` - Maintenance work + +## Priorities + +- ` + "`0`" + ` - Critical (security, data loss, broken builds) +- ` + "`1`" + ` - High (major features, important bugs) +- ` + "`2`" + ` - Medium (default, nice-to-have) +- ` + "`3`" + ` - Low (polish, optimization) +- ` + "`4`" + ` - Backlog (future ideas) + +## More Information + +- Run ` + "`bd --help`" + ` for full command reference +- See ` + "`AGENTS.md`" + ` for detailed AI integration docs +- See ` + "`QUICKSTART.md`" + ` for human-oriented guide +` + +// InstallAider installs Aider integration +func InstallAider() { + configPath := ".aider.conf.yml" + readmePath := ".aider/README.md" + + fmt.Println("Installing Aider integration...") + + // Write config file + if err := atomicWriteFile(configPath, []byte(aiderConfigTemplate), 0644); err != nil { + fmt.Fprintf(os.Stderr, "Error: write config: %v\n", err) + os.Exit(1) + } + + // Ensure .aider directory exists + if err := EnsureDir(filepath.Dir(readmePath), 0755); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } + + // Write README + if err := atomicWriteFile(readmePath, []byte(aiderReadmeTemplate), 0644); err != nil { + fmt.Fprintf(os.Stderr, "Error: write README: %v\n", err) + os.Exit(1) + } + + fmt.Printf("\n✓ Aider integration installed\n") + fmt.Printf(" Config: %s\n", configPath) + fmt.Printf(" README: %s\n", readmePath) + fmt.Println("\nUsage:") + fmt.Println(" 1. Start aider in this directory") + fmt.Println(" 2. Ask AI for available work (it will suggest: /run bd ready)") + fmt.Println(" 3. Run suggested commands using /run") + fmt.Println("\nNote: Aider requires you to explicitly run commands via /run") +} + +// CheckAider checks if Aider integration is installed +func CheckAider() { + configPath := ".aider.conf.yml" + + if _, err := os.Stat(configPath); os.IsNotExist(err) { + fmt.Println("✗ Aider integration not installed") + fmt.Println(" Run: bd setup aider") + os.Exit(1) + } + + fmt.Println("✓ Aider integration installed:", configPath) +} + +// RemoveAider removes Aider integration +func RemoveAider() { + configPath := ".aider.conf.yml" + readmePath := ".aider/README.md" + + fmt.Println("Removing Aider integration...") + + removed := false + + // Remove config + if err := os.Remove(configPath); err != nil { + if !os.IsNotExist(err) { + fmt.Fprintf(os.Stderr, "Error: failed to remove config: %v\n", err) + os.Exit(1) + } + } else { + removed = true + } + + // Remove README + if err := os.Remove(readmePath); err != nil { + if !os.IsNotExist(err) { + fmt.Fprintf(os.Stderr, "Error: failed to remove README: %v\n", err) + os.Exit(1) + } + } else { + removed = true + } + + if !removed { + fmt.Println("No Aider integration files found") + return + } + + fmt.Println("✓ Removed Aider integration") +} diff --git a/docs/AIDER_INTEGRATION.md b/docs/AIDER_INTEGRATION.md new file mode 100644 index 00000000..2b24981c --- /dev/null +++ b/docs/AIDER_INTEGRATION.md @@ -0,0 +1,377 @@ +# Aider Integration Guide + +This guide explains how to integrate [Aider](https://aider.chat/) with Beads for AI-assisted coding with issue tracking. + +## Overview + +Aider is an AI pair programming tool that works in your terminal. Unlike autonomous AI agents like Claude Code, **Aider requires explicit user confirmation** to run commands via the `/run` command. + +The beads integration for Aider: +- Creates `.aider.conf.yml` with bd workflow instructions +- Provides `.aider/README.md` with quick reference +- Instructs the AI to **suggest** bd commands (not run them automatically) +- Works with aider's human-in-the-loop design philosophy + +## Installation + +### 1. Install Beads + +```bash +# Install beads CLI +go install github.com/steveyegge/beads/cmd/bd@latest + +# Initialize in your project +cd your-project +bd init --quiet +``` + +### 2. Setup Aider Integration + +```bash +# Install aider integration files +bd setup aider + +# Verify installation +bd setup aider --check +``` + +This creates: +- `.aider.conf.yml` - Instructions for the AI about bd workflow +- `.aider/README.md` - Quick reference guide + +### 3. Install Aider + +```bash +# Install aider via pip +pip install aider-chat + +# Or via pipx (recommended) +pipx install aider-chat +``` + +## Usage Workflow + +### Starting a Session + +1. **Start aider in your project:** + ```bash + cd your-project + aider + ``` + +2. **Ask the AI about available work:** + ``` + You: What issues are ready to work on? + + Aider: Let me check the available work. Run: + /run bd ready + ``` + +3. **Run the suggested command:** + ``` + /run bd ready + ``` + +4. **Choose an issue and ask AI to claim it:** + ``` + You: Let's work on bd-42 + + Aider: Great choice! To claim it, run: + /run bd update bd-42 --status in_progress + ``` + +### During Development + +The AI will suggest appropriate bd commands as you work: + +- **Create issues for bugs you find:** + ``` + You: I found a bug in the auth code + + Aider: Let's track that. Run: + /run bd create "Fix auth bug in login handler" --description="Login fails with 500 when password contains quotes" -t bug -p 1 + ``` + +- **Link discovered work:** + ``` + Aider: Since we found this while working on bd-42, run: + /run bd create "Fix auth bug" --description="..." -p 1 --deps discovered-from:bd-42 + ``` + +- **Check issue details:** + ``` + /run bd show bd-42 + ``` + +### Completing Work + +When you're done: + +``` +You: This issue is complete + +Aider: Great! Mark it complete by running: +/run bd close bd-42 --reason "Implemented login fix and added tests" + +Then sync to git: +/run bd sync +``` + +## Configuration + +### .aider.conf.yml + +The config file contains instructions for the AI: + +```yaml +# Core workflow rules: +# 1. Track ALL work in bd (never use markdown TODOs) +# 2. Suggest 'bd ready' to find available work +# 3. Suggest 'bd create' for new issues/tasks/bugs +# 4. Suggest 'bd sync' at end of session +# 5. ALWAYS suggest commands - user will run them via /run +``` + +You can customize this file to add project-specific instructions. + +### Aider Commands vs bd Commands + +**Aider commands** start with `/` and control aider itself: +- `/run ` - Run a shell command +- `/add ` - Add file to context +- `/help` - Show aider help + +**bd commands** are run via `/run`: +- `/run bd ready` - Check available work +- `/run bd create "..."` - Create an issue +- `/run bd show bd-42` - View issue details + +## Common Patterns + +### Starting Work + +```bash +# Check what's available +/run bd ready + +# Claim an issue +/run bd update bd-abc --status in_progress +``` + +### Discovering Work + +```bash +# Create a new issue +/run bd create "Refactor auth module" --description="Current auth code has tight coupling" -t task -p 2 + +# Link it to current work +/run bd dep add bd-new --type discovered-from --target bd-abc +``` + +### Completing Work + +```bash +# Close the issue +/run bd close bd-abc --reason "Implemented and tested" + +# Sync to git +/run bd sync +``` + +### Checking Status + +```bash +# View issue details +/run bd show bd-abc + +# List all open issues +/run bd list --status=open + +# Check dependencies +/run bd dep tree bd-abc +``` + +## Comparison: Aider vs Claude Code + +### Aider (Human-in-the-Loop) + +- ✅ User must confirm all commands via `/run` +- ✅ Full control over what gets executed +- ✅ AI **suggests** bd commands +- ⚠️ More manual interaction required + +### Claude Code (Autonomous) + +- ✅ AI directly executes bd commands +- ✅ Faster workflow (no confirmation needed) +- ✅ Hooks auto-inject bd context +- ⚠️ Less user control over command execution + +**Both approaches work well with beads!** Choose based on your preference for automation vs. control. + +## Tips for Aider Users + +### 1. Ask for Suggestions + +Instead of running commands yourself, ask the AI: +``` +You: How do I check what work is available? +Aider: Run `/run bd ready` to see all unblocked issues +``` + +### 2. Let the AI Track Work + +The AI knows the bd workflow and will suggest appropriate commands: +``` +You: I'm starting work on the login feature +Aider: First, let's claim it. Run: +/run bd update bd-xyz --status in_progress +``` + +### 3. Use bd prime for Context + +Get the full workflow guide: +```bash +/run bd prime +``` + +The AI will read this and have complete context about bd commands. + +### 4. Create Aliases + +Add to your shell config for faster commands: +```bash +alias bdr='/run bd ready' +alias bdc='/run bd create' +alias bds='/run bd sync' +``` + +Then in aider: +``` +bdr # Instead of /run bd ready +bdc "Fix bug" -t bug # Instead of /run bd create "Fix bug" -t bug +``` + +## Troubleshooting + +### "The AI isn't suggesting bd commands" + +1. Check that `.aider.conf.yml` exists: + ```bash + bd setup aider --check + ``` + +2. Reload aider to pick up the config: + ```bash + # Exit aider (Ctrl-D or /exit) + # Restart aider + aider + ``` + +3. Explicitly ask about bd: + ``` + You: What should I use for issue tracking? + Aider: This project uses Beads (bd) for issue tracking... + ``` + +### "Commands are failing" + +Make sure you're in a beads-initialized directory: +```bash +/run bd doctor +``` + +If not initialized: +```bash +/run bd init --quiet +``` + +### "I want to remove the integration" + +```bash +bd setup aider --remove +``` + +This removes `.aider.conf.yml` and `.aider/README.md`. + +## Advanced Usage + +### Multi-File Context + +Aider can track multiple files. Combine with bd: + +``` +You: Add the auth files to context and check for related issues + +/run bd list --json | grep -i auth +/add src/auth/*.py +``` + +### Batch Operations + +Run multiple bd commands in sequence: +```bash +# In your shell (not aider) +bd ready && bd show bd-42 && bd update bd-42 --status in_progress +``` + +### Integration with Git + +Aider handles git commits. bd tracks issues. They work together: + +1. Claim issue: `/run bd update bd-42 --status in_progress` +2. Make changes with aider +3. Aider commits changes +4. Complete issue: `/run bd close bd-42` +5. Sync issues: `/run bd sync` + +## Example Session + +``` +$ aider + +You: What issues are ready to work on? + +Aider: Let me check. Run: +/run bd ready + +📋 Ready work (3 issues with no blockers): +1. [P1] bd-42: Fix login bug +2. [P2] bd-99: Add password reset +3. [P3] bd-17: Refactor auth tests + +You: Let's work on bd-42 + +Aider: Great! First claim it: +/run bd update bd-42 --status in_progress + +You: Can you show me the details? + +Aider: Run: +/run bd show bd-42 + +[Shows issue details] + +You: Ok, add the auth files to context + +Aider: Added src/auth/login.py and src/auth/utils.py + +You: Fix the bug described in the issue + +[Aider makes the changes] + +You: Looks good! Mark it complete + +Aider: Run: +/run bd close bd-42 --reason "Fixed login bug - added input validation" + +Then sync: +/run bd sync +``` + +## References + +- [Aider Documentation](https://aider.chat/docs/) +- [Beads Documentation](https://github.com/steveyegge/beads) +- [AGENTS.md](../AGENTS.md) - Complete bd workflow guide +- [QUICKSTART.md](QUICKSTART.md) - Quick start guide