Add Aider integration for beads issue tracking
Implements GH#206 and bd-3djj: Add support for Aider AI pair programming tool with beads issue tracking. Changes: - Added cmd/bd/setup/aider.go with InstallAider, CheckAider, RemoveAider - Created .aider.conf.yml template with bd workflow instructions - Added .aider/README.md template with quick reference - Updated cmd/bd/setup.go to include aider subcommand - Fixed cmd/bd/main.go to allow setup subcommands without database by checking parent command name - Added comprehensive docs/AIDER_INTEGRATION.md documentation Key differences from Claude/Cursor integration: - Aider requires explicit command execution via /run - AI suggests bd commands rather than running autonomously - Documentation emphasizes human-in-the-loop workflow - Config instructs AI to always suggest, never execute Usage: bd setup aider # Install integration bd setup aider --check # Verify installation bd setup aider --remove # Remove integration Resolves bd-3djj Related to GH#206 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
204
cmd/bd/setup/aider.go
Normal file
204
cmd/bd/setup/aider.go
Normal file
@@ -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 <id> --status=in_progress # Claim work
|
||||
# bd close <id> # Mark complete
|
||||
# bd dep <from> <to> # 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 <id> --status=in_progress' to claim it"
|
||||
# 3. Do the work
|
||||
# 4. Complete: "Run 'bd close <id>' 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")
|
||||
}
|
||||
Reference in New Issue
Block a user