Fix #349: Improve compact error messages, remove bogus merge suggestion, add daemon/maintenance docs

- bd-1h8: Add --no-daemon hint to compact error messages
- bd-8ql: Replace non-existent merge command with actionable guidance
- bd-ayw: Add 'When to use daemon mode' decision tree to daemon.md
- bd-keb: Add database maintenance section to QUICKSTART.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-11-20 20:58:56 -05:00
parent f20aec672d
commit 27c0c331ac
4 changed files with 65 additions and 12 deletions

View File

@@ -105,11 +105,13 @@ Examples:
if compactAnalyze { if compactAnalyze {
if err := ensureDirectMode("compact --analyze requires direct database access"); err != nil { if err := ensureDirectMode("compact --analyze requires direct database access"); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err) fmt.Fprintf(os.Stderr, "Error: %v\n", err)
fmt.Fprintf(os.Stderr, "Hint: Use --no-daemon flag to bypass daemon and access database directly\n")
os.Exit(1) os.Exit(1)
} }
sqliteStore, ok := store.(*sqlite.SQLiteStorage) sqliteStore, ok := store.(*sqlite.SQLiteStorage)
if !ok { if !ok {
fmt.Fprintf(os.Stderr, "Error: compact requires SQLite storage\n") fmt.Fprintf(os.Stderr, "Error: failed to open database in direct mode\n")
fmt.Fprintf(os.Stderr, "Hint: Ensure .beads/beads.db exists and is readable\n")
os.Exit(1) os.Exit(1)
} }
runCompactAnalyze(ctx, sqliteStore) runCompactAnalyze(ctx, sqliteStore)
@@ -120,6 +122,7 @@ Examples:
if compactApply { if compactApply {
if err := ensureDirectMode("compact --apply requires direct database access"); err != nil { if err := ensureDirectMode("compact --apply requires direct database access"); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err) fmt.Fprintf(os.Stderr, "Error: %v\n", err)
fmt.Fprintf(os.Stderr, "Hint: Use --no-daemon flag to bypass daemon and access database directly\n")
os.Exit(1) os.Exit(1)
} }
if compactID == "" { if compactID == "" {
@@ -132,7 +135,8 @@ Examples:
} }
sqliteStore, ok := store.(*sqlite.SQLiteStorage) sqliteStore, ok := store.(*sqlite.SQLiteStorage)
if !ok { if !ok {
fmt.Fprintf(os.Stderr, "Error: compact requires SQLite storage\n") fmt.Fprintf(os.Stderr, "Error: failed to open database in direct mode\n")
fmt.Fprintf(os.Stderr, "Hint: Ensure .beads/beads.db exists and is readable\n")
os.Exit(1) os.Exit(1)
} }
runCompactApply(ctx, sqliteStore) runCompactApply(ctx, sqliteStore)

View File

@@ -82,9 +82,13 @@ Example:
sources = append(sources, issue.ID) sources = append(sources, issue.ID)
} }
} }
// TODO: performMerge implementation pending // Generate actionable command suggestion
// For now, just generate the command suggestion cmd := fmt.Sprintf("# Duplicate: %s (same content as %s)\n# Suggested action: bd close %s && bd dep add %s %s --type related",
cmd := fmt.Sprintf("bd merge %s --into %s", strings.Join(sources, " "), target.ID) strings.Join(sources, " "),
target.ID,
strings.Join(sources, " "),
strings.Join(sources, " "),
target.ID)
mergeCommands = append(mergeCommands, cmd) mergeCommands = append(mergeCommands, cmd)
if autoMerge || dryRun { if autoMerge || dryRun {
@@ -134,8 +138,9 @@ Example:
sources = append(sources, issue.ID) sources = append(sources, issue.ID)
} }
} }
fmt.Printf(" %s bd merge %s --into %s\n\n", fmt.Printf(" %s Duplicate: %s (same content as %s)\n", cyan("Note:"), strings.Join(sources, " "), target.ID)
cyan("Suggested:"), strings.Join(sources, " "), target.ID) fmt.Printf(" %s bd close %s && bd dep add %s %s --type related\n\n",
cyan("Suggested:"), strings.Join(sources, " "), strings.Join(sources, " "), target.ID)
} }
if autoMerge { if autoMerge {
if dryRun { if dryRun {
@@ -245,11 +250,12 @@ func formatDuplicateGroupsJSON(groups [][]*types.Issue, refCounts map[string]int
} }
} }
result = append(result, map[string]interface{}{ result = append(result, map[string]interface{}{
"title": group[0].Title, "title": group[0].Title,
"issues": issues, "issues": issues,
"suggested_target": target.ID, "suggested_target": target.ID,
"suggested_sources": sources, "suggested_sources": sources,
"suggested_merge_cmd": fmt.Sprintf("bd merge %s --into %s", strings.Join(sources, " "), target.ID), "suggested_action": fmt.Sprintf("bd close %s && bd dep add %s %s --type related", strings.Join(sources, " "), strings.Join(sources, " "), target.ID),
"note": fmt.Sprintf("Duplicate: %s (same content as %s)", strings.Join(sources, " "), target.ID),
}) })
} }
return result return result

View File

@@ -19,6 +19,24 @@ Each project runs its own daemon at `.beads/bd.sock` for complete database isola
**Note:** Global daemon support was removed in v0.16.0. The `--global` flag is no longer functional. **Note:** Global daemon support was removed in v0.16.0. The `--global` flag is no longer functional.
## When to Use Daemon Mode
**✅ You SHOULD use daemon mode if:**
- Working in a team with git remote sync
- Want automatic commit/push of issue changes
- Need background auto-sync (5-second debounce)
- Making frequent bd commands (performance benefit from connection pooling)
**❌ You DON'T need daemon mode if:**
- Solo developer with local-only tracking
- Working in git worktrees (use --no-daemon to avoid conflicts)
- Running one-off commands or scripts
- Debugging database issues (direct mode is simpler)
**Local-only users:** Direct mode (default without daemon) is perfectly fine. The daemon mainly helps with git sync automation. You can still use `bd sync` manually when needed.
**Performance note:** For most operations, the daemon provides minimal performance benefit. The main value is automatic JSONL export (5s debounce) and optional git sync (--auto-commit, --auto-push).
## Common Operations ## Common Operations
- **Start**: `bd daemon` (auto-starts on first `bd` command) - **Start**: `bd daemon` (auto-starts on first `bd` command)

View File

@@ -172,6 +172,31 @@ After upgrading bd, use `bd migrate` to check for and migrate old database files
**AI agents:** Use `--inspect` to analyze migration safety before running. The system verifies required config keys and data integrity invariants. **AI agents:** Use `--inspect` to analyze migration safety before running. The system verifies required config keys and data integrity invariants.
## Database Maintenance
As your project accumulates closed issues, the database grows. Manage size with these commands:
```bash
# View compaction statistics
bd compact --stats
# Preview compaction candidates (30+ days closed)
bd compact --analyze --json --no-daemon
# Apply agent-generated summary
bd compact --apply --id bd-42 --summary summary.txt --no-daemon
# Immediately delete closed issues (CAUTION: permanent!)
bd cleanup --force
```
**When to compact:**
- Database file > 10MB with many old closed issues
- After major project milestones when old issues are no longer relevant
- Before archiving a project phase
**Note:** Compaction is permanent graceful decay. Original content is discarded but viewable via `bd restore <id>` from git history.
## Advanced: Agent Mail (Optional) ## Advanced: Agent Mail (Optional)
For **multi-agent workflows** (2+ AI agents working concurrently), Agent Mail provides real-time coordination: For **multi-agent workflows** (2+ AI agents working concurrently), Agent Mail provides real-time coordination: