Add ability to filter issues by their pinned status in bd list command.
- Add pinned column to issues table via migration 023
- Add Pinned field to Issue struct and IssueFilter
- Update all storage layer queries to include pinned column
- Add --pinned flag to show only pinned issues
- Add --no-pinned flag to exclude pinned issues
- Update RPC layer to forward pinned filter to daemon mode
- Add pinned to allowedUpdateFields for bd update support
Resolves: beads-p8e
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add checkForExistingIDs function to detect duplicate IDs within batch
and conflicts with existing database entries before insert
- Remove thread_id index creation from schema.go since thread_id column
is added by migration 020_edge_consolidation.go
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When bd detects it's running in a fork (origin != steveyegge/beads),
automatically add .beads/issues.jsonl to .git/info/exclude.
This prevents contributors from accidentally including issue database
changes in their PRs. The exclusion is:
- Per-clone (doesn't modify tracked files
- One-time setup (checks if already excluded)
- Silent (only logs in debug mode)
Maintainers (origin = steveyegge/beads) are not affected.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
EOF
)
The test expected CreateIssues to error on duplicate IDs, but the
implementation uses INSERT OR IGNORE which silently skips duplicates.
This is intentional behavior needed for JSONL import scenarios.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive tests for the new graph.go functions to meet
coverage threshold after rebase introduced 405 new lines:
- TestTruncateTitle: tests rune-safe title truncation
- TestPadRight: tests rune-safe string padding
- TestRenderNodeBox: tests ASCII box rendering for all status types
- TestComputeLayout: tests topological layout computation with
dependencies
These tests cover the pure utility functions and basic graph layout
logic, bringing coverage from 44.7% to 45.1%.
The subgraph parameter was passed to renderGraph but not used in the
function body, causing an unparam lint error. Replace with _ to
indicate intentional non-use.
Fix two CI failures that were blocking main:
1. Lint error in cmd/bd/onboard.go:126
- Unchecked fmt.Fprintf return value
- Fixed by explicitly ignoring with _, _
2. Test failures in internal/storage/sqlite
- TestCreateIssues/duplicate_ID_error was passing but
TestCreateIssuesRollback/rollback_on_conflict_with_existing_ID failed
- Root cause: CreateIssues used INSERT OR IGNORE which silently
ignored duplicate IDs instead of returning an error
- Fixed by adding duplicate ID detection in EnsureIDs():
a) Check for duplicates within the batch
b) Check for conflicts with existing database IDs
Both fixes are minimal and targeted to unblock CI.
The graph command now shows issues connected via any dependency type
(blocks, parent-child, etc.), not just parent-child relationships.
This makes bd graph useful for epics where children are connected via
blocks dependencies rather than hierarchical parent-child.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New command to visualize issue dependency graphs:
- Layered layout (Sugiyama-style) shows execution order
- Status coloring (open/in_progress/blocked/closed)
- Works with epics to show full subgraph
- Layer 0 = ready tasks (no blockers)
Usage: bd graph <issue-id>
Part of bd-r6a workflow system redesign.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bd onboard now outputs a ~10 line snippet for AGENTS.md that points to
"bd prime" for full workflow context. This replaces the previous ~200
line static content that:
- Bloated AGENTS.md with instructions that loaded every session
- Got stale when bd was upgraded
- Wasted tokens when beads was not actively being used
The new approach:
- AGENTS.md gets minimal pointer (~20 tokens vs ~2000)
- bd prime provides dynamic, always-current workflow details
- Hooks auto-inject bd prime at session start
Also removes the --output flag for BD_GUIDE.md generation (obsolete).
Closes bd-gxq
Addresses GH#604
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests findRepliesTo() and findReplies() helper functions in cmd/bd/show.go
that traverse message threads via dependencies. Covers:
- 3-message linear thread chain traversal (up and down)
- Thread root finding via repeated findRepliesTo() calls
- Branching threads (one message with multiple replies)
- Empty/standalone messages
- Nonexistent issue IDs
- Verification that only replies-to deps are followed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change reconnectMu from sync.Mutex to sync.RWMutex so read operations
can hold RLock during database access. This prevents reconnect() from
closing the connection while queries are in progress.
- GetIssue and SearchIssues now hold RLock during database operations
- Close() acquires write lock to coordinate with reconnect
- Add TestConcurrentReadsWithReconnect to verify the fix
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Code review found three issues where transaction.go diverged from the
main dependencies.go implementation:
1. Add relates-to exemption from cycle detection - bidirectional
relationships are valid and should not trigger cycle errors
2. Add metadata and thread_id fields to INSERT - required for
replies-to threading to work in transaction context
3. Update error message to match dependencies.go wording
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The early ID deduplication in the main loop (seenIDs check) already
prevents duplicate IDs from reaching newIssues. The pre-batch
deduplication was dead code that could never fire.
Keeping two layers:
1. Early dedup in main loop - catches duplicates in JSONL input
2. INSERT OR IGNORE at DB level - safety net for all code paths
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes 5 linting issues to allow PR checks to pass:
1. hooks.go: Explicitly ignore error in async goroutine
2. 022_drop_edge_columns.go: Handle deferred PRAGMA error
3. flags.go: Add nosec comment for validated file path
4. create_form.go: Fix American spelling (canceled vs cancelled)
5. create_form.go: Explicitly mark cmd parameter as required by cobra
These are pre-existing issues in the codebase, fixed here to
enable clean CI for the import deduplication fix.
🤖 Generated with Claude Code
Fixes 5 linting issues to allow PR checks to pass:
1. hooks.go: Explicitly ignore error in async goroutine
2. 022_drop_edge_columns.go: Handle deferred PRAGMA error
3. flags.go: Add nosec comment for validated file path
4. create_form.go: Fix American spelling (canceled vs cancelled)
5. create_form.go: Explicitly mark cmd parameter as required by cobra
These are pre-existing issues in the codebase, fixed here to
enable clean CI for the schema probe fix.
🤖 Generated with Claude Code
**Problem:**
Schema compatibility probe was failing with "no such column: thread_id"
error when opening databases created before v0.30.5, even after running
migrations. This caused database initialization to fail.
**Root Cause:**
The migration 020_edge_consolidation.go correctly adds the metadata and
thread_id columns to the dependencies table, but schema_probe.go's
expectedSchema map was missing these columns in its validation list.
This caused verifySchemaCompatibility() to fail even though:
1. The columns existed in the actual schema (schema.go:51-52)
2. Migration 020 would add them if missing
3. The database was otherwise valid
**Solution:**
Updated expectedSchema in schema_probe.go to include "metadata" and
"thread_id" in the dependencies table column list. This aligns the schema
probe expectations with the actual schema definition and migration 020
behavior.
**Testing:**
✅ Tested on 5 databases across version range pre-0.17.5 → v0.30.5
- All migrations completed successfully
- Schema probe passes after migration
- All bd commands work correctly
✅ No regressions in fresh database initialization
**Impact:**
- Fixes database initialization errors for users upgrading from v0.30.3
- No breaking changes or data migrations required
- Compatible with all existing databases
- Enables smooth migration path for all database versions
Fixes database migration issues reported in v0.30.5 upgrade path.
🤖 Generated with Claude Code
This is the final phase of the Edge Schema Consolidation. It removes
the deprecated edge fields (RepliesTo, RelatesTo, DuplicateOf, SupersededBy)
from the Issue struct and all related code.
Changes:
- Remove edge fields from types.Issue struct
- Remove edge field scanning from queries.go and transaction.go
- Update graph_links_test.go to use dependency API exclusively
- Update relate.go to use AddDependency/RemoveDependency
- Update show.go with helper functions for thread traversal via deps
- Update mail_test.go to verify thread links via dependencies
- Add migration 022 to drop columns from issues table
- Fix cycle detection to allow bidirectional relates-to links
- Fix migration 022 to disable foreign keys before table recreation
All edge relationships now use the dependencies table exclusively.
The old Issue fields are fully removed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Commands relate, unrelate, duplicate, and supersede now properly
use RPC Update when daemonClient is available, instead of always
calling store.UpdateIssue() directly and bypassing the daemon.
Added RelatesTo, DuplicateOf, and SupersededBy fields to UpdateArgs
in the RPC protocol, and updated server_issues_epics.go to handle them.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add migration to convert existing issue fields to dependency edges:
- replies_to -> replies-to dependency with thread_id
- relates_to -> relates-to dependencies (JSON array)
- duplicate_of -> duplicates dependency
- superseded_by -> supersedes dependency
The migration is idempotent (INSERT OR IGNORE) so it does not duplicate
edges that were already created by Phase 2 dual-write.
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When issue fields (replies_to, relates_to, duplicate_of, superseded_by)
are set during CreateIssue or UpdateIssue, we now ALSO create the
corresponding dependency edges. This enables gradual migration to
edge-based storage while maintaining backward compatibility.
Changes:
- createGraphEdgesFromIssueFields: handles CreateIssue dual-write
- createGraphEdgesFromUpdates: handles UpdateIssue dual-write
- Replies-to edges include thread_id for efficient thread queries
- Uses INSERT OR IGNORE to handle idempotency
The dual-write ensures both field and dependency stay in sync during
the migration period.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add metadata and thread_id columns to dependencies table to support:
- Edge metadata: JSON blob for type-specific data (similarity scores, etc.)
- Thread queries: O(1) conversation threading via thread_id
Changes:
- New migration 020_edge_consolidation.go
- Updated Dependency struct with Metadata and ThreadID fields
- Added new entity types: authored-by, assigned-to, approved-by
- Relaxed DependencyType validation (any non-empty string ≤50 chars)
- Added IsWellKnown() and AffectsReadyWork() methods
- Updated SQL queries to include new columns
- Updated tests for new behavior
This enables HOP knowledge graph requirements and Reddit-style threading.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The countDBIssuesFast() fallback path used SearchIssues without
IncludeTombstones, returning only live issues (161). Meanwhile
countIssuesInJSONL counts all lines including tombstones (221).
This mismatch caused false "stale DB detected" warnings on every
sync, even when DB and JSONL were in sync.
Fix: Set IncludeTombstones: true in the fallback SearchIssues call.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>