Add bd doctor --fix flag to automatically repair issues (bd-ykd9)
Implements automatic fix capability for bd doctor with user confirmation and security hardening. Features: - Organizes fix implementations under doctor/fix/ directory structure - Shows all fixable issues and prompts for confirmation (Y/n) before applying - Provides clear output about what was fixed and any errors encountered - Re-runs diagnostics after fixes to show updated state - Each fix is idempotent and safe to run multiple times Automatic fixes implemented: - Git hooks (runs bd hooks install) - Daemon health issues (runs bd daemons killall) - DB-JSONL sync problems (runs bd sync --import-only) - File permissions (fixes .beads/ and database permissions) - Database version mismatches (runs bd migrate) - Schema compatibility issues (runs bd migrate) - Gitignore updates (writes canonical template) Security improvements: - Prevents command injection by using os.Executable() instead of PATH lookup - Prevents path traversal attacks with workspace validation - Fixes race conditions by using cmd.Dir instead of os.Chdir() - Corrects file permission logic (proper bit masking) - Validates all operations run in beads workspaces only Files changed: - cmd/bd/doctor.go: Enhanced applyFixes() with confirmation and better UX - cmd/bd/doctor/gitignore.go: Fixed permissions (0600 → 0644) - cmd/bd/doctor/fix/common.go: Security helpers (getBdBinary, validateBeadsWorkspace) - cmd/bd/doctor/fix/hooks.go: Git hooks fix - cmd/bd/doctor/fix/daemon.go: Daemon health fix - cmd/bd/doctor/fix/sync.go: DB-JSONL sync fix - cmd/bd/doctor/fix/permissions.go: File permissions fix - cmd/bd/doctor/fix/migrate.go: Database migration fixes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
49
cmd/bd/doctor/fix/permissions.go
Normal file
49
cmd/bd/doctor/fix/permissions.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package fix
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// Permissions fixes file permission issues in the .beads directory
|
||||
func Permissions(path string) error {
|
||||
// Validate workspace
|
||||
if err := validateBeadsWorkspace(path); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
beadsDir := filepath.Join(path, ".beads")
|
||||
|
||||
// Check if .beads/ directory exists
|
||||
info, err := os.Stat(beadsDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to stat .beads directory: %w", err)
|
||||
}
|
||||
|
||||
// Ensure .beads directory has exactly 0700 permissions (owner rwx only)
|
||||
expectedDirMode := os.FileMode(0700)
|
||||
if info.Mode().Perm() != expectedDirMode {
|
||||
if err := os.Chmod(beadsDir, expectedDirMode); err != nil {
|
||||
return fmt.Errorf("failed to fix .beads directory permissions: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Fix permissions on database file if it exists
|
||||
dbPath := filepath.Join(beadsDir, "beads.db")
|
||||
if dbInfo, err := os.Stat(dbPath); err == nil {
|
||||
// Ensure database has exactly 0600 permissions (owner rw only)
|
||||
expectedFileMode := os.FileMode(0600)
|
||||
currentPerms := dbInfo.Mode().Perm()
|
||||
requiredPerms := os.FileMode(0600)
|
||||
|
||||
// Check if we have both read and write for owner
|
||||
if currentPerms&requiredPerms != requiredPerms {
|
||||
if err := os.Chmod(dbPath, expectedFileMode); err != nil {
|
||||
return fmt.Errorf("failed to fix database permissions: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user