From 61e9a36dfdf9d46f7304a7aab4ac323a5733c547 Mon Sep 17 00:00:00 2001 From: Dustin Smith Date: Mon, 19 Jan 2026 20:43:41 +0700 Subject: [PATCH] fix: create boot directory on install and make fixable - Add boot directory creation to install.go (avoids warning on fresh install) - Make boot-health check fixable via 'gt doctor --fix' - Update FixHint to reference the fix command --- internal/cmd/install.go | 7 +++++++ internal/doctor/boot_check.go | 30 ++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/internal/cmd/install.go b/internal/cmd/install.go index cf0e68da..afc3f09c 100644 --- a/internal/cmd/install.go +++ b/internal/cmd/install.go @@ -221,6 +221,13 @@ func runInstall(cmd *cobra.Command, args []string) error { fmt.Printf(" ✓ Created deacon/.claude/settings.json\n") } + // Create boot directory (deacon/dogs/boot/) for Boot watchdog. + // This avoids gt doctor warning on fresh install. + bootDir := filepath.Join(deaconDir, "dogs", "boot") + if err := os.MkdirAll(bootDir, 0755); err != nil { + fmt.Printf(" %s Could not create boot directory: %v\n", style.Dim.Render("⚠"), err) + } + // Initialize git BEFORE beads so that bd can compute repository fingerprint. // The fingerprint is required for the daemon to start properly. if installGit || installGitHub != "" { diff --git a/internal/doctor/boot_check.go b/internal/doctor/boot_check.go index e8c95679..cc2ed565 100644 --- a/internal/doctor/boot_check.go +++ b/internal/doctor/boot_check.go @@ -11,20 +11,37 @@ import ( // BootHealthCheck verifies Boot watchdog health. // "The vet checks on the dog." type BootHealthCheck struct { - BaseCheck + FixableCheck + missingDir bool // track if directory is missing for Fix() } // NewBootHealthCheck creates a new Boot health check. func NewBootHealthCheck() *BootHealthCheck { return &BootHealthCheck{ - BaseCheck: BaseCheck{ - CheckName: "boot-health", - CheckDescription: "Check Boot watchdog health (the vet checks on the dog)", - CheckCategory: CategoryInfrastructure, + FixableCheck: FixableCheck{ + BaseCheck: BaseCheck{ + CheckName: "boot-health", + CheckDescription: "Check Boot watchdog health (the vet checks on the dog)", + CheckCategory: CategoryInfrastructure, + }, }, } } +// CanFix returns true only if the directory is missing (we can create it). +func (c *BootHealthCheck) CanFix() bool { + return c.missingDir +} + +// Fix creates the missing boot directory. +func (c *BootHealthCheck) Fix(ctx *CheckContext) error { + if !c.missingDir { + return nil + } + b := boot.New(ctx.TownRoot) + return b.EnsureDir() +} + // Run checks Boot health: directory, session, status, and marker freshness. func (c *BootHealthCheck) Run(ctx *CheckContext) *CheckResult { b := boot.New(ctx.TownRoot) @@ -33,12 +50,13 @@ func (c *BootHealthCheck) Run(ctx *CheckContext) *CheckResult { // Check 1: Boot directory exists bootDir := b.Dir() if _, err := os.Stat(bootDir); os.IsNotExist(err) { + c.missingDir = true return &CheckResult{ Name: c.Name(), Status: StatusWarning, Message: "Boot directory not present", Details: []string{fmt.Sprintf("Expected: %s", bootDir)}, - FixHint: "Boot directory is created on first daemon run", + FixHint: "Run 'gt doctor --fix' to create it", } }