Fix bd-373c: Surface daemon errors when multiple .db files exist

When daemon detects multiple .db files (after filtering .backup and vc.db),
it now writes detailed error to .beads/daemon-error file before exiting.

The error file is checked and displayed when:
- Daemon discovery fails to connect
- Auto-start fails to yield a running daemon
- User runs 'bd daemons list'

This makes the error immediately visible without requiring users to check
daemon logs.

Changes:
- cmd/bd/daemon.go: Write daemon-error file on multiple .db detection
- internal/daemon/discovery.go: Read and surface daemon-error in DaemonInfo.Error
- cmd/bd/main.go: Display daemon-error when auto-start fails

Amp-Thread-ID: https://ampcode.com/threads/T-1005a8d1-7a5a-4844-ad2d-2b8a6145825f
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-31 22:01:30 -07:00
parent 31a936a4b4
commit 079effdaeb
3 changed files with 50 additions and 5 deletions

View File

@@ -149,10 +149,18 @@ func discoverDaemon(socketPath string) DaemonInfo {
client, err := rpc.TryConnectWithTimeout(socketPath, 500*time.Millisecond)
if err != nil {
daemon.Error = fmt.Sprintf("failed to connect: %v", err)
// Check for daemon-error file
if errMsg := checkDaemonErrorFile(socketPath); errMsg != "" {
daemon.Error = errMsg
}
return daemon
}
if client == nil {
daemon.Error = "daemon not responding or unhealthy"
// Check for daemon-error file
if errMsg := checkDaemonErrorFile(socketPath); errMsg != "" {
daemon.Error = errMsg
}
return daemon
}
defer client.Close()
@@ -204,6 +212,20 @@ func FindDaemonByWorkspace(workspacePath string) (*DaemonInfo, error) {
return nil, fmt.Errorf("no daemon found for workspace: %s", workspacePath)
}
// checkDaemonErrorFile checks for a daemon-error file in the .beads directory
func checkDaemonErrorFile(socketPath string) string {
// Socket path is typically .beads/bd.sock, so get the parent dir
beadsDir := filepath.Dir(socketPath)
errFile := filepath.Join(beadsDir, "daemon-error")
data, err := os.ReadFile(errFile)
if err != nil {
return ""
}
return string(data)
}
// CleanupStaleSockets removes socket files and PID files for dead daemons
func CleanupStaleSockets(daemons []DaemonInfo) (int, error) {
cleaned := 0