feat: Add 'bd stale' command to show and release orphaned executor claims

- Implements bd stale command to show issues with execution_state where executor is dead/stopped
- Adds --release flag to automatically release orphaned issues
- Adds --threshold flag to customize heartbeat staleness threshold (default: 300s/5min)
- Handles missing executor instances (LEFT JOIN) for cases where executor was deleted
- Adds QueryContext and BeginTx helper methods to SQLiteStorage for advanced queries
- Fixes ExternalRef comparison bug in import_shared.go (pointer vs string)
- Removes unused imports in import.go

Resolves vc-124
This commit is contained in:
Steve Yegge
2025-10-18 17:14:21 -07:00
parent a143efbd0e
commit 790233f748
7 changed files with 674 additions and 543 deletions

View File

@@ -712,12 +712,33 @@ func autoImportIfNewer() {
}
// Detect collisions before importing (bd-228 fix)
sqliteStore, ok := store.(*sqlite.SQLiteStorage)
if !ok {
// Not SQLite - skip auto-import to avoid silent data loss without collision detection
fmt.Fprintf(os.Stderr, "Auto-import disabled for non-SQLite backend (no collision detection).\n")
fmt.Fprintf(os.Stderr, "To import manually, run: bd import -i %s\n", jsonlPath)
return
// Auto-import needs direct SQLite access for collision detection
var sqliteStore *sqlite.SQLiteStorage
if store != nil {
// Direct mode - try to use existing store
var ok bool
sqliteStore, ok = store.(*sqlite.SQLiteStorage)
if !ok {
fmt.Fprintf(os.Stderr, "Auto-import disabled for non-SQLite backend (no collision detection).\n")
fmt.Fprintf(os.Stderr, "To import manually, run: bd import -i %s\n", jsonlPath)
return
}
} else {
// Daemon mode - open direct connection for auto-import
if dbPath == "" {
if os.Getenv("BD_DEBUG") != "" {
fmt.Fprintf(os.Stderr, "Debug: auto-import skipped, no database path\n")
}
return
}
var err error
sqliteStore, err = sqlite.New(dbPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Auto-import failed: could not open database: %v\n", err)
return
}
defer sqliteStore.Close()
}
collisionResult, err := sqlite.DetectCollisions(ctx, sqliteStore, allIssues)