bd init: Default to YES for git hooks and merge driver

Fixes bd-bxha

Previously, bd init prompted users to install git hooks and merge driver,
which could result in incomplete setup if declined. Changed to install
both by default for better out-of-the-box experience.

Changes:
- Install git hooks automatically unless --skip-hooks is passed
- Install merge driver automatically unless --skip-merge-driver is passed
- Remove interactive prompts (no longer needed)
- Add warning messages on failure with suggestion to run bd doctor --fix
- Add --skip-hooks flag for explicit opt-out

Users who want to skip installation can now use:
  bd init --skip-hooks --skip-merge-driver

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-11-23 19:25:33 -08:00
parent 5c2597f7bd
commit ec4117d08a
2 changed files with 194 additions and 239 deletions

File diff suppressed because one or more lines are too long

View File

@@ -36,6 +36,7 @@ With --no-db: creates .beads/ directory and issues.jsonl file instead of SQLite
contributor, _ := cmd.Flags().GetBool("contributor") contributor, _ := cmd.Flags().GetBool("contributor")
team, _ := cmd.Flags().GetBool("team") team, _ := cmd.Flags().GetBool("team")
skipMergeDriver, _ := cmd.Flags().GetBool("skip-merge-driver") skipMergeDriver, _ := cmd.Flags().GetBool("skip-merge-driver")
skipHooks, _ := cmd.Flags().GetBool("skip-hooks")
// Initialize config (PersistentPreRun doesn't run for init command) // Initialize config (PersistentPreRun doesn't run for init command)
if err := config.Initialize(); err != nil { if err := config.Initialize(); err != nil {
@@ -317,24 +318,22 @@ With --no-db: creates .beads/ directory and issues.jsonl file instead of SQLite
} }
// Check if we're in a git repo and hooks aren't installed // Check if we're in a git repo and hooks aren't installed
// Do this BEFORE quiet mode return so hooks get installed for agents // Install by default unless --skip-hooks is passed
if isGitRepo() && !hooksInstalled() { if !skipHooks && isGitRepo() && !hooksInstalled() {
if quiet { if err := installGitHooks(); err != nil && !quiet {
// Auto-install hooks silently in quiet mode (best default for agents) yellow := color.New(color.FgYellow).SprintFunc()
_ = installGitHooks() // Ignore errors in quiet mode fmt.Fprintf(os.Stderr, "\n%s Failed to install git hooks: %v\n", yellow("⚠"), err)
} else { fmt.Fprintf(os.Stderr, "You can try again with: %s\n\n", color.New(color.FgCyan).Sprint("bd doctor --fix"))
// Defer to interactive prompt below
} }
} }
// Check if we're in a git repo and merge driver isn't configured // Check if we're in a git repo and merge driver isn't configured
// Do this BEFORE quiet mode return so merge driver gets configured for agents // Install by default unless --skip-merge-driver is passed
if !skipMergeDriver && isGitRepo() && !mergeDriverInstalled() { if !skipMergeDriver && isGitRepo() && !mergeDriverInstalled() {
if quiet { if err := installMergeDriver(); err != nil && !quiet {
// Auto-install merge driver silently in quiet mode (best default for agents) yellow := color.New(color.FgYellow).SprintFunc()
_ = installMergeDriver() // Ignore errors in quiet mode fmt.Fprintf(os.Stderr, "\n%s Failed to install merge driver: %v\n", yellow("⚠"), err)
} else { fmt.Fprintf(os.Stderr, "You can try again with: %s\n\n", color.New(color.FgCyan).Sprint("bd doctor --fix"))
// Defer to interactive prompt below
} }
} }
@@ -345,56 +344,11 @@ With --no-db: creates .beads/ directory and issues.jsonl file instead of SQLite
green := color.New(color.FgGreen).SprintFunc() green := color.New(color.FgGreen).SprintFunc()
cyan := color.New(color.FgCyan).SprintFunc() cyan := color.New(color.FgCyan).SprintFunc()
yellow := color.New(color.FgYellow).SprintFunc()
fmt.Printf("\n%s bd initialized successfully!\n\n", green("✓")) fmt.Printf("\n%s bd initialized successfully!\n\n", green("✓"))
fmt.Printf(" Database: %s\n", cyan(initDBPath)) fmt.Printf(" Database: %s\n", cyan(initDBPath))
fmt.Printf(" Issue prefix: %s\n", cyan(prefix)) fmt.Printf(" Issue prefix: %s\n", cyan(prefix))
fmt.Printf(" Issues will be named: %s\n\n", cyan(prefix+"-1, "+prefix+"-2, ...")) fmt.Printf(" Issues will be named: %s\n\n", cyan(prefix+"-1, "+prefix+"-2, ..."))
// Interactive git hooks prompt for humans
if isGitRepo() && !hooksInstalled() {
fmt.Printf("%s Git hooks not installed\n", yellow("⚠"))
fmt.Printf(" Install git hooks to prevent race conditions between commits and auto-flush.\n")
fmt.Printf(" Run: %s\n\n", cyan("./examples/git-hooks/install.sh"))
// Prompt to install
fmt.Printf("Install git hooks now? [Y/n] ")
var response string
_, _ = fmt.Scanln(&response) // ignore EOF on empty input
response = strings.ToLower(strings.TrimSpace(response))
if response == "" || response == "y" || response == "yes" {
if err := installGitHooks(); err != nil {
fmt.Fprintf(os.Stderr, "Error installing hooks: %v\n", err)
fmt.Printf("You can install manually with: %s\n\n", cyan("./examples/git-hooks/install.sh"))
} else {
fmt.Printf("%s Git hooks installed successfully!\n\n", green("✓"))
}
}
}
// Interactive git merge driver prompt for humans
if !skipMergeDriver && isGitRepo() && !mergeDriverInstalled() {
fmt.Printf("%s Git merge driver not configured\n", yellow("⚠"))
fmt.Printf(" bd merge provides intelligent JSONL merging to prevent conflicts.\n")
fmt.Printf(" This will configure git to use 'bd merge' for .beads/beads.jsonl\n\n")
// Prompt to install
fmt.Printf("Configure git merge driver now? [Y/n] ")
var response string
_, _ = fmt.Scanln(&response) // ignore EOF on empty input
response = strings.ToLower(strings.TrimSpace(response))
if response == "" || response == "y" || response == "yes" {
if err := installMergeDriver(); err != nil {
fmt.Fprintf(os.Stderr, "Error configuring merge driver: %v\n", err)
} else {
fmt.Printf("%s Git merge driver configured successfully!\n\n", green("✓"))
}
}
}
fmt.Printf("Run %s to get started.\n\n", cyan("bd quickstart")) fmt.Printf("Run %s to get started.\n\n", cyan("bd quickstart"))
}, },
} }
@@ -405,7 +359,8 @@ func init() {
initCmd.Flags().StringP("branch", "b", "", "Git branch for beads commits (default: current branch)") initCmd.Flags().StringP("branch", "b", "", "Git branch for beads commits (default: current branch)")
initCmd.Flags().Bool("contributor", false, "Run OSS contributor setup wizard") initCmd.Flags().Bool("contributor", false, "Run OSS contributor setup wizard")
initCmd.Flags().Bool("team", false, "Run team workflow setup wizard") initCmd.Flags().Bool("team", false, "Run team workflow setup wizard")
initCmd.Flags().Bool("skip-merge-driver", false, "Skip git merge driver setup (non-interactive)") initCmd.Flags().Bool("skip-hooks", false, "Skip git hooks installation")
initCmd.Flags().Bool("skip-merge-driver", false, "Skip git merge driver setup")
rootCmd.AddCommand(initCmd) rootCmd.AddCommand(initCmd)
} }