refactor(doctor): consolidate maintenance commands + improve daemon startup

Consolidate clean, repair-deps, validate into bd doctor:
- Add validation checks to doctor (merge artifacts, orphaned deps, duplicates, test pollution, git conflicts)
- Add auto-fix for merge artifacts and orphaned dependencies
- Delete obsolete command files: clean.go, repair_deps.go, validate.go
- Delete orphaned test files: clean_security_test.go, validate_test.go

Improve daemon startup performance:
- Add fast-fail detection when daemon crashed (check lock before retrying)
- Reduce graceful shutdown timeout from 5s to 1s
- Skip daemon connection for root command (just shows help)
- Extract shutdown timeout as constants (daemonShutdownTimeout, daemonShutdownPollInterval)

Other changes:
- Move rename-prefix command to Maintenance group in help
- Fix Makefile to inject git commit hash via ldflags

New files:
- cmd/bd/doctor/validation.go (5 check functions)
- cmd/bd/doctor/fix/validation.go (2 fix functions)
This commit is contained in:
Ryan Snodgrass
2025-12-22 19:39:51 -08:00
committed by Steve Yegge
parent e60dfaf1f1
commit cafc0b9dfb
16 changed files with 619 additions and 1374 deletions

View File

@@ -396,6 +396,22 @@ func applyFixList(path string, fixes []doctorCheck) {
continue
}
err = fix.SyncBranchHealth(path, syncBranch)
case "Merge Artifacts":
err = fix.MergeArtifacts(path)
case "Orphaned Dependencies":
err = fix.OrphanedDependencies(path)
case "Duplicate Issues":
// No auto-fix: duplicates require user review
fmt.Printf(" ⚠ Run 'bd duplicates' to review and merge duplicates\n")
continue
case "Test Pollution":
// No auto-fix: test cleanup requires user review
fmt.Printf(" ⚠ Run 'bd detect-pollution' to review and clean test issues\n")
continue
case "Git Conflicts":
// No auto-fix: git conflicts require manual resolution
fmt.Printf(" ⚠ Resolve conflicts manually: git checkout --ours or --theirs .beads/issues.jsonl\n")
continue
default:
fmt.Printf(" ⚠ No automatic fix available for %s\n", check.Name)
fmt.Printf(" Manual fix: %s\n", check.Fix)
@@ -749,6 +765,33 @@ func runDiagnostics(path string) doctorResult {
result.Checks = append(result.Checks, untrackedCheck)
// Don't fail overall check for untracked files, just warn
// Check 21: Merge artifacts (from bd clean)
mergeArtifactsCheck := convertDoctorCheck(doctor.CheckMergeArtifacts(path))
result.Checks = append(result.Checks, mergeArtifactsCheck)
// Don't fail overall check for merge artifacts, just warn
// Check 22: Orphaned dependencies (from bd repair-deps, bd validate)
orphanedDepsCheck := convertDoctorCheck(doctor.CheckOrphanedDependencies(path))
result.Checks = append(result.Checks, orphanedDepsCheck)
// Don't fail overall check for orphaned deps, just warn
// Check 23: Duplicate issues (from bd validate)
duplicatesCheck := convertDoctorCheck(doctor.CheckDuplicateIssues(path))
result.Checks = append(result.Checks, duplicatesCheck)
// Don't fail overall check for duplicates, just warn
// Check 24: Test pollution (from bd validate)
pollutionCheck := convertDoctorCheck(doctor.CheckTestPollution(path))
result.Checks = append(result.Checks, pollutionCheck)
// Don't fail overall check for test pollution, just warn
// Check 25: Git conflicts in JSONL (from bd validate)
conflictsCheck := convertDoctorCheck(doctor.CheckGitConflicts(path))
result.Checks = append(result.Checks, conflictsCheck)
if conflictsCheck.Status == statusError {
result.OverallOK = false
}
return result
}