Add BEADS_NO_DAEMON escape hatch and improve daemon detection

Changes to cmd/bd/main.go:
- Add BEADS_NO_DAEMON env var to explicitly disable daemon (single-user mode)
- Keep BEADS_AUTO_START_DAEMON for backward compatibility
- Lower global daemon threshold from 4+ repos to 2+ repos
- Document always-daemon mode as default behavior

Also create bd-161 epic for label enhancements with child tasks.

Amp-Thread-ID: https://ampcode.com/threads/T-675a2db5-b1b3-480d-a108-b003d8139d08
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-19 20:45:50 -07:00
parent 84a5ef7bf8
commit 8a48b599ae

View File

@@ -359,13 +359,19 @@ func emitVerboseWarning() {
} }
func shouldAutoStartDaemon() bool { func shouldAutoStartDaemon() bool {
// Check environment variable (default: true) // Check BEADS_NO_DAEMON first (escape hatch for single-user workflows)
noDaemon := strings.ToLower(strings.TrimSpace(os.Getenv("BEADS_NO_DAEMON")))
if noDaemon == "1" || noDaemon == "true" || noDaemon == "yes" || noDaemon == "on" {
return false // Explicit opt-out
}
// Check legacy BEADS_AUTO_START_DAEMON for backward compatibility
autoStart := strings.ToLower(strings.TrimSpace(os.Getenv("BEADS_AUTO_START_DAEMON"))) autoStart := strings.ToLower(strings.TrimSpace(os.Getenv("BEADS_AUTO_START_DAEMON")))
if autoStart != "" { if autoStart != "" {
// Accept common falsy values // Accept common falsy values
return autoStart != "false" && autoStart != "0" && autoStart != "no" && autoStart != "off" return autoStart != "false" && autoStart != "0" && autoStart != "no" && autoStart != "off"
} }
return true // Default to enabled return true // Default to enabled (always-daemon mode)
} }
// shouldUseGlobalDaemon determines if global daemon should be preferred // shouldUseGlobalDaemon determines if global daemon should be preferred
@@ -388,7 +394,7 @@ func shouldUseGlobalDaemon() bool {
var countRepos func(string, int) error var countRepos func(string, int) error
countRepos = func(dir string, depth int) error { countRepos = func(dir string, depth int) error {
if depth > maxDepth || repoCount > 3 { if depth > maxDepth || repoCount > 1 {
return filepath.SkipDir return filepath.SkipDir
} }
@@ -421,7 +427,7 @@ func shouldUseGlobalDaemon() bool {
dbPath := filepath.Join(path, "db.sqlite") dbPath := filepath.Join(path, "db.sqlite")
if _, err := os.Stat(dbPath); err == nil { if _, err := os.Stat(dbPath); err == nil {
repoCount++ repoCount++
if repoCount > 3 { if repoCount > 1 {
return filepath.SkipDir return filepath.SkipDir
} }
} }
@@ -448,18 +454,19 @@ func shouldUseGlobalDaemon() bool {
for _, dir := range projectDirs { for _, dir := range projectDirs {
if _, err := os.Stat(dir); err == nil { if _, err := os.Stat(dir); err == nil {
countRepos(dir, 0) countRepos(dir, 0)
if repoCount > 3 { if repoCount > 1 {
break break
} }
} }
} }
if os.Getenv("BD_DEBUG") != "" { if os.Getenv("BD_DEBUG") != "" {
fmt.Fprintf(os.Stderr, "Debug: found %d beads repositories, prefer global: %v\n", repoCount, repoCount > 3) fmt.Fprintf(os.Stderr, "Debug: found %d beads repositories, prefer global: %v\n", repoCount, repoCount > 1)
} }
// Use global daemon if we found more than 3 repositories // Use global daemon if we found more than 1 repository (multi-repo workflow)
return repoCount > 3 // This prevents concurrency issues when multiple repos are being worked on
return repoCount > 1
} }
// tryAutoStartDaemon attempts to start the daemon in the background // tryAutoStartDaemon attempts to start the daemon in the background