Complete implementation of signal-aware context propagation for graceful
cancellation across all commands and storage operations.
Key changes:
1. Signal-aware contexts (bd-rtp):
- Added rootCtx/rootCancel in main.go using signal.NotifyContext()
- Set up in PersistentPreRun, cancelled in PersistentPostRun
- Daemon uses same pattern in runDaemonLoop()
- Handles SIGINT/SIGTERM for graceful shutdown
2. Context propagation (bd-yb8):
- All commands now use rootCtx instead of context.Background()
- sqlite.New() receives context for cancellable operations
- Database operations respect context cancellation
- Storage layer propagates context through all queries
3. Cancellation tests (bd-2o2):
- Added import_cancellation_test.go with comprehensive tests
- Added export cancellation test in export_test.go
- Tests verify database integrity after cancellation
- All cancellation tests passing
Fixes applied during review:
- Fixed rootCtx lifecycle (removed premature defer from PersistentPreRun)
- Fixed test context contamination (reset rootCtx in test cleanup)
- Fixed export tests missing context setup
Impact:
- Pressing Ctrl+C during import/export now cancels gracefully
- No database corruption or hanging transactions
- Clean shutdown of all operations
Tested:
- go build ./cmd/bd ✓
- go test ./cmd/bd -run TestImportCancellation ✓
- go test ./cmd/bd -run TestExportCommand ✓
- Manual Ctrl+C testing verified
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Enhances rename-prefix command with --repair flag to consolidate databases
with multiple prefixes. Creates shared issue ID utilities to eliminate code
duplication across import and rename operations.
Key changes:
- Add --repair flag to detect and consolidate multiple issue prefixes
- Create internal/utils/issue_id.go with ExtractIssuePrefix() and ExtractIssueNumber()
- Update all duplicate prefix extraction code to use shared utilities
- Add comprehensive tests for repair functionality
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Problem: Incremental flush merged dirty issues with existing JSONL, leaving
old IDs when issues were renamed (e.g., test-3 remained after renumbering to test-2).
Solution:
- Add needsFullExport flag to force complete JSONL rebuild from DB
- Skip loading existing JSONL when fullExport=true (start with empty map)
- Use markDirtyAndScheduleFullExport() in renumber and rename-prefix commands
- PersistentPostRun flushes immediately before process exits (respects fullExport)
Test: Verified renumber with gaps correctly exports only current IDs to JSONL
These commands modify issues in bulk but weren't triggering auto-export
to JSONL. This caused database and JSONL to get out of sync.
Added markDirtyAndScheduleFlush() calls to:
- bd renumber (after renumbering completes)
- bd rename-prefix (after prefix rename completes)
- bd compact (after single/batch compaction)
- bd delete (already had it)
Fixes the issue where massive cleanups weren't exported to JSONL.
Amp-Thread-ID: https://ampcode.com/threads/T-a43dc9fa-e9bc-43c7-9055-33acc08bc642
Co-authored-by: Amp <amp@ampcode.com>
- Implement bd rename-prefix command with --dry-run and --json flags
- Add prefix validation (max 8 chars, lowercase, starts with letter)
- Update all issue IDs and text references atomically per issue
- Update dependencies, labels, events, and counters
- Fix counter merge to use MAX() to prevent ID collisions
- Update snapshot tables for FK integrity
- Add comprehensive tests for validation and rename workflow
- Document in README.md and AGENTS.md
Known limitation: Each issue updates in its own transaction.
A failure mid-way could leave mixed state. Acceptable for
intended use case (infrequent operation on small DBs).
Amp-Thread-ID: https://ampcode.com/threads/T-7e77b779-bd88-44f2-9f0b-a9f2ccd54d38
Co-authored-by: Amp <amp@ampcode.com>