fix: relocate daemon socket for deep paths (GH#1001)

On Unix systems, socket paths are limited to 104 chars (macOS) or 108 chars
(Linux). Deep workspace paths like /Volumes/External Drive/Dropbox/...
would exceed this limit and cause daemon startup failures.

This fix:
- Adds ShortSocketPath() which computes /tmp/beads-{hash}/bd.sock for
  paths that would exceed the limit
- Keeps backward compatibility: short paths still use .beads/bd.sock
- Updates daemon discovery to check both locations
- Uses SHA256 hash of canonical workspace path for unique directories

Closes GH#1001

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
wolf
2026-01-10 12:30:13 -08:00
committed by Steve Yegge
parent 77b9d4762f
commit 3ecffa111b
6 changed files with 334 additions and 6 deletions

View File

@@ -457,13 +457,17 @@ func recordDaemonStartFailure() {
// getSocketPath returns the daemon socket path based on the database location.
// If BD_SOCKET env var is set, uses that value instead (enables test isolation).
// Returns local socket path (.beads/bd.sock relative to database)
// On Unix systems, uses rpc.ShortSocketPath to avoid exceeding socket path limits
// (macOS: 104 chars) by relocating long paths to /tmp/beads-{hash}/ (GH#1001).
func getSocketPath() string {
// Check environment variable first (enables test isolation)
if socketPath := os.Getenv("BD_SOCKET"); socketPath != "" {
return socketPath
}
return filepath.Join(filepath.Dir(dbPath), "bd.sock")
// Get workspace path (parent of .beads directory)
beadsDir := filepath.Dir(dbPath)
workspacePath := filepath.Dir(beadsDir)
return rpc.ShortSocketPath(workspacePath)
}
// emitVerboseWarning prints a one-line warning when falling back to direct mode

View File

@@ -340,6 +340,11 @@ func TestDaemonAutostart_RestartDaemonForVersionMismatch_Stubbed(t *testing.T) {
t.Fatalf("getPIDFilePath: %v", err)
}
sock := getSocketPath()
// Create socket directory if needed (GH#1001 - socket may be in /tmp/beads-{hash}/)
sockDir := filepath.Dir(sock)
if err := os.MkdirAll(sockDir, 0o750); err != nil {
t.Fatalf("MkdirAll sockDir: %v", err)
}
if err := os.WriteFile(pidFile, []byte("999999\n"), 0o600); err != nil {
t.Fatalf("WriteFile pid: %v", err)
}