BD_GUIDE.md generation was removed in 125e36d5 when bd onboard was
simplified to output a minimal snippet pointing to bd prime.
This commit:
- Removes stale BD_GUIDE.md references from CLAUDE.md
- Removes dead checkAndSuggestBDGuideUpdate() code from version_tracking.go
- Removes BD_GUIDE.md from UNINSTALLING.md file list
Closes#660 (already fixed in v0.30.7 via f1380e8b)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The 'bd pin' command was failing with "invalid field for update: pinned"
because the pinned field was missing from allowedUpdateFields.
Fixes:
- Add 'pinned' to allowedUpdateFields in queries.go
- Update importer to include pinned field in updates during import
- Add equalBool comparator for IssueDataChanged to detect pinned changes
- Fix stats query to count pinned=1 instead of status='pinned'
- Fix pinIndicator in list.go to check issue.Pinned instead of status
This unblocks gt mail --pinned functionality.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ResolveForWrite helper that resolves symlinks before writing, so
atomic writes go to the symlink target instead of replacing the symlink.
This prevents `bd setup claude` from overwriting nix/home-manager
managed ~/.claude/settings.json symlinks.
Closes#665
Co-authored-by: qmx <qmx@qmx.me>
Mail is orchestration, not data plane. The bd mail commands were just
sugar over bd create/list/show with type=message. Gas Town (gt) now
owns mail routing and delivery.
Removed:
- cmd/bd/mail.go - all mail subcommands (send, inbox, read, ack, reply)
- cmd/bd/mail_test.go - mail command tests
- docs/messaging.md - dedicated mail documentation
- EventMessage hook - no longer triggered
Kept (data plane):
- type=message as valid issue type
- Sender, Ephemeral fields on issues
- replies_to dependency type for threading
Coordination: gt-9xg implements native mail in Gas Town.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The doctor's version tracking check was looking at metadata.json:LastBdVersion,
but version tracking was moved to .local_version file (gitignored). This caused
the "LastBdVersion field is empty" warning to persist even after running bd
commands, because those commands update .local_version but not metadata.json.
- Update CheckMetadataVersionTracking to read from .local_version
- Rename check from "Metadata Version Tracking" to "Version Tracking"
- Update tests to use .local_version instead of metadata.json
- Remove unused configfile import
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add 'deferred' as a valid issue status for issues that are deliberately
put on ice - not blocked by dependencies, just postponed for later.
Changes:
- Add StatusDeferred constant and update IsValid() validation
- Add DeferredIssues to Statistics struct with counting in both SQLite
and memory storage
- Add 'bd defer' command to set status to deferred
- Add 'bd undefer' command to restore status to open
- Update help text across list, search, count, dep, stale, and config
- Update MCP server models and tools to accept deferred status
- Add deferred to blocker status checks (schema, cache, ready, compact)
- Add StatusDeferred to public API exports (beads.go, internal/beads)
- Add snowflake styling for deferred in dep tree and graph views
Semantics:
- deferred vs blocked: deferred is a choice, blocked is forced
- deferred vs closed: deferred will be revisited, closed is done
- Deferred issues excluded from 'bd ready' (already works since
default filter only includes open/in_progress)
- Deferred issues still block dependents (they are not done!)
- Deferred issues visible in 'bd list' and 'bd stale'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Consolidate `bd stats` and `bd status` into a unified command:
- Add `stats` as alias for `status` command
- Add colorized output with emoji header
- Include all Statistics fields (tombstones, pinned, epics, lead time)
- Add `--no-activity` flag to skip git activity parsing
- Remove standalone statsCmd from ready.go (~90 lines)
- Update StatusOutput to use types.Statistics directly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements gt-0ei3: Template molecules now live in a separate molecules.jsonl
file, distinct from work items in issues.jsonl.
Key changes:
- Add internal/molecules package for loading molecule catalogs
- Implement hierarchical loading: built-in → town → user → project
- Molecules use their own ID namespace (mol-*) with prefix validation skipped
- Templates are marked with is_template: true and are read-only
- bd list excludes templates by default (existing functionality)
The hierarchical loading allows:
- Built-in molecules shipped with bd binary (placeholder for future)
- Town-level: ~/gt/.beads/molecules.jsonl (Gas Town)
- User-level: ~/.beads/molecules.jsonl
- Project-level: .beads/molecules.jsonl
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds automatic label filtering based on current working directory:
- New config option: directory.labels (maps directory patterns to labels)
- bd ready and bd list auto-apply label filtering when in matching directory
- Uses --label-any semantics (shows issues with any of the matching labels)
Config example:
```yaml
directory:
labels:
packages/maverick: maverick
packages/agency: agency
```
When running `bd ready` from `packages/maverick/`, issues labeled
"maverick" are automatically shown first, without needing --label-any.
Closes#541🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds configuration options for beads git commits:
- git.author: Override commit author (e.g., "beads-bot <beads@example.com>")
- git.no-gpg-sign: Disable GPG signing for beads commits
This is useful for users with Touch ID commit signing (like Secretive)
who get prompted for every beads auto-commit.
Config example:
```yaml
git:
author: "beads-bot <beads@example.com>"
no-gpg-sign: true
```
Environment variables: BD_GIT_AUTHOR, BD_GIT_NO_GPG_SIGN
Closes#600🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(doctor): add comprehensive tests for fix and check functions
Add edge case tests, e2e tests, and improve test coverage for:
- database_test.go: database integrity and sync checks
- git_test.go: git hooks, merge driver, sync branch tests
- gitignore_test.go: gitignore validation
- prefix_test.go: ID prefix handling
- fix/fix_test.go: fix operations
- fix/e2e_test.go: end-to-end fix scenarios
- fix/fix_edge_cases_test.go: edge case handling
* docs: add testing philosophy and anti-patterns guide
- Create TESTING_PHILOSOPHY.md covering test pyramid, priority matrix,
what NOT to test, and 5 anti-patterns with code examples
- Add cross-reference from README_TESTING.md
- Document beads-specific guidance (well-covered areas vs gaps)
- Include target metrics (test-to-code ratio, execution time targets)
* chore: revert .beads/ to upstream/main state
* refactor(doctor): add category grouping and Ayu theme colors
- Add Category field to DoctorCheck for organizing checks by type
- Define category constants: Core, Git, Runtime, Data, Integration, Metadata
- Update thanks command to use shared Ayu color palette from internal/ui
- Simplify test fixtures by removing redundant test cases
* fix(doctor): prevent test fork bomb and fix test failures
- Add ErrTestBinary guard in getBdBinary() to prevent tests from
recursively executing the test binary when calling bd subcommands
- Update claude_test.go to use new check names (CLI Availability,
Prime Documentation)
- Fix syncbranch test path comparison by resolving symlinks
(/var vs /private/var on macOS)
- Fix permissions check to use exact comparison instead of bitmask
- Fix UntrackedJSONL to use git commit --only to preserve staged changes
- Fix MergeDriver edge case test by making both .git dir and config
read-only
- Add skipIfTestBinary helper for E2E tests that need real bd binary
* test(doctor): skip read-only config test in CI environments
GitHub Actions containers may have CAP_DAC_OVERRIDE or similar
capabilities that allow writing to read-only files, causing
the test to fail. Skip the test when CI=true or GITHUB_ACTIONS=true.
Replace full shell script hooks with thin shims that delegate to
'bd hooks run <hook-name>'. This eliminates hook version drift -
upgrading bd automatically updates hook behavior.
Changes:
- Add 'bd hooks run' subcommand with hook logic in Go
- Convert templates to minimal shims (~17 lines each)
- Shims use '# bd-shim v1' marker (format version, not bd version)
- Update version checking to recognize shim format
- Shims are never marked as "outdated"
Benefits:
- No more manual 'bd hooks install --force' after upgrades
- Hook logic always matches installed bd version
- Follows pattern used by husky, pre-commit, lefthook
Migration: Run 'bd hooks install --force' one final time.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add create.require-description config option that enforces descriptions
when creating issues. When enabled, bd create will error if no
description is provided (except for test issues).
- Config in .beads/config.yaml or ~/.config/bd/config.yaml
- Also supports BD_CREATE_REQUIRE_DESCRIPTION env var
- Default: false (preserves current behavior with warning)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The bd doctor command was pointing to a non-existent README anchor
(#claude-code-plugin). Updated to point to docs/PLUGIN.md which
contains the actual plugin installation instructions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The renderGraph function was being called with nil instead of the
loaded subgraph, causing a nil pointer dereference in
computeDependencyCounts when iterating over subgraph.Dependencies.
Changes:
- Pass subgraph variable to renderGraph instead of nil
- Add defensive nil check in computeDependencyCounts
- Add test case for nil subgraph handling
Fixes GH#657
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add omitempty JSON tags to Issue struct fields (Description, Status,
Priority, IssueType) and SetDefaults method to apply proper defaults
when importing JSONL with omitted fields.
This reduces JSONL file size for minimal issues like notifications
by not exporting empty/default values.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- graph.go: Pass subgraph to renderGraph() instead of nil (fixes#657)
The nil subgraph was dereferenced in computeDependencyCounts()
causing a panic when running `bd graph` on epics.
- postinstall.js: Wait for file.close() callback before resolving (fixes#652)
On Windows, the file was still locked when extraction started
because resolve() was called immediately after file.close()
without waiting for the close to complete.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add `bd molecule list` to list template molecules
- Add `bd molecule show` to show molecule details
- Add `bd molecule instantiate` to create work items from templates
- Exclude templates from `bd list` by default (use --include-templates)
- Reject mutations (update/close/delete) to template issues
- Add IncludeTemplates to RPC ListArgs for daemon mode
Templates are marked with is_template=true and are read-only.
Use `bd molecule instantiate` to create editable work items.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The schema_probe.go and doctor/database.go had different column lists
for validating database schemas. Neither included the pinned column
added in migration 023, causing:
- Doctor to report "All required tables and columns present" on
databases missing the pinned column
- Potential failures when using `gt mail send` on databases without
the pinned column
Changes:
- Add pinned, sender, ephemeral to doctor's criticalChecks
- Add metadata, thread_id to dependencies check
- Add all missing columns to schema_probe.go's expectedSchema:
source_repo, close_reason, deleted_at, deleted_by, delete_reason,
original_type, sender, ephemeral, pinned
Fixes: beads-9yc
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Molecules are composable workflow templates used by Gas Town (gt) for
defining multi-step processes like bootstrap, engineer-in-box, etc.
Changes:
- Add TypeMolecule constant to internal/types/types.go
- Add molecule to IsValid() switch case
- Add molecule and merge-request to validation/bead.go validTypes map
- Update help text in create.go, show.go, list.go
- Add test cases for molecule and merge-request types
Closes gt-qn4l
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Add Linear integration CLI with sync and status commands
- Add `bd linear sync` for bidirectional issue sync with Linear
- Add `bd linear status` to show configuration and sync state
- Stub pull/push functions pending GraphQL client (bd-b6b.2)
* Implement Linear GraphQL client with full sync support
- Add LinearClient with auth, fetch, create, update methods
- Implement pull/push operations with Beads type mapping
- Clean up redundant comments and remove unused code
* Add configurable data mapping and dependency sync for Linear
- Add LinearMappingConfig with configurable priority/state/label/relation maps
- Import parent-child and issue relations as Beads dependencies
- Support custom workflow states via linear.state_map.* config
* Add incremental sync support for Linear integration
- Add FetchIssuesSince() method using updatedAt filter in GraphQL
- Check linear.last_sync config to enable incremental pulls
- Track sync mode (incremental vs full) in LinearPullStats
* feat(linear): implement push updates for existing Linear issues
Add FetchIssueByIdentifier method to retrieve single issues by identifier
(e.g., "TEAM-123") for timestamp comparison during push.
Update doPushToLinear to:
- Fetch Linear issue to get internal ID and UpdatedAt timestamp
- Compare timestamps: only update if local is newer
- Build update payload with title, description, priority, and state
- Call UpdateIssue for issues where local has newer changes
Closes bd-b6b.5
* Implement Linear conflict resolution strategies
- Add true conflict detection by fetching Linear timestamps via API
- Implement --prefer-linear resolution (re-import from Linear)
- Implement timestamp-based resolution (newer wins as default)
- Fix linter issues: handle resp.Body.Close() and remove unused error return
* Add Linear integration tests and documentation
- Add comprehensive unit tests for Linear mapping (priority, state, labels, relations)
- Update docs/CONFIG.md with Linear configuration reference
- Add examples/linear-workflow guide for bidirectional sync
- Remove AI section header comments from tests
* Fix Linear GraphQL filter construction and improve test coverage
- Refactor filter handling to combine team ID into main filter object
- Add test for duplicate issue relation mapping
- Add HTTP round-trip helper for testing request payload validation
* Refactor Linear queries to use shared constant and add UUID validation
- Extract linearIssuesQuery to deduplicate FetchIssues/FetchIssuesSince
- Add linearMaxPageSize constant and UUID validation with regex
- Expand test coverage for new functionality
* Refactor Linear integration into internal/linear package
- Extract types, client, and mapping logic from cmd/bd/linear.go
- Create internal/linear/ package for better code organization
- Update tests to work with new package structure
* Add linear teams command to list available teams
- Add FetchTeams GraphQL query to Linear client
- Refactor config reading to support daemon mode
- Add tests for teams listing functionality
* Refactor Linear config to use getLinearConfig helper
- Consolidate config/env var lookup using getLinearConfig function
- Add LINEAR_TEAM_ID environment variable support
- Update error messages to include env var configuration options
* Add hash ID generation and improve Linear conflict detection
- Add configurable hash ID mode for Linear imports (matches bd/Jira)
- Improve conflict detection with content hash comparison
- Enhance conflict resolution with skip/force update tracking
* Fix test for updated doPushToLinear signature
- Add missing skipUpdateIDs parameter to test call
* fix(sync): respect sync.branch config when no upstream tracking
When sync.branch is explicitly configured, bd sync should use worktree-based
sync even if the current branch has no upstream tracking. This fixes the
issue where jj (Jujutsu) colocated repos and git worktrees without upstream
would incorrectly fall back to --from-main mode.
The fix checks for sync.branch configuration BEFORE the upstream check,
allowing the configured sync branch to take precedence.
Affected workflows:
- jj colocated repos (always use detached HEAD)
- Git worktrees not tracking a remote
- Temporary checkouts for testing
Fixes#638
* test(sync): add regression tests for sync.branch priority over upstream check
Add tests verifying that when sync.branch is configured, bd sync does NOT
fall back to --from-main mode even without upstream tracking. This covers:
- sync.branch configured without upstream (should use worktree sync)
- No sync.branch and no upstream (should fallback to from-main)
- Detached HEAD with sync.branch (jj workflow, should use worktree sync)
These tests ensure the fix for GH#638 doesn't regress.
---------
Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
* fix(unix): handle Statfs field types for disk space check
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* fix(freebsd): build disk space check without type mismatch
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
---------
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* refactor(doctor): split doctor.go into modular package files
Split the 3,171-line doctor.go into logical sub-files within the
cmd/bd/doctor/ package, reducing the main file to 834 lines (74% reduction).
New package structure:
- types.go: DoctorCheck struct and status constants
- installation.go: CheckInstallation, CheckMultipleDatabases, CheckPermissions
- git.go: CheckGitHooks, CheckMergeDriver, CheckSyncBranch* checks
- database.go: CheckDatabaseVersion, CheckSchemaCompatibility, CheckDatabaseJSONLSync
- version.go: CheckCLIVersion, CheckMetadataVersionTracking, CompareVersions
- integrity.go: CheckIDFormat, CheckDependencyCycles, CheckTombstones
- daemon.go: CheckDaemonStatus, CheckVersionMismatch
- quick.go: Quick checks for sync-branch and hooks
Updated tests to use exported doctor.CheckXxx() functions and
doctor.StatusXxx constants.
* fix(doctor): suppress gosec G204 false positives
Add #nosec G204 comments to exec.Command calls in CheckSyncBranchHealth
where variables come from trusted sources (config files or hardcoded
values like "main"/"master"/"origin"), not untrusted user input.
Enables bd ready --type=merge-request for MQ integration.
The Engineer can now query for ready merge-requests.
Files changed:
- cmd/bd/ready.go: Add -t/--type flag
- internal/types/types.go: Add Type field to WorkFilter
- internal/rpc/protocol.go: Add Type to ReadyArgs
- internal/storage/sqlite/ready.go: Filter by issue_type column
Adds GGT compatibility flags to bd mail send:
- --priority N: Explicit priority (0-4), overrides --urgent
- --type: Message type (task, scavenge, notification, reply)
- --thread-id: Thread ID for conversation grouping
- --reply-to: Message ID for threading via dependency
This fixes UX inconsistency where gt mail send passed flags that
bd mail send did not support (gt-8j8e).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allows descriptions with apostrophes and other shell-problematic
characters by reading from stdin. Works with both --description=-
and --body=- (the GitHub CLI-style alias).
Example: echo "It's working" | bd create --title "Test" --description=-
Also fixes pre-existing duplicate pinned column/variable declarations.
Fixes beads-iwi
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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 Pinned field to Issue struct and database schema to protect
issues from accidental deletion via cleanup or compaction.
Changes:
- Add Pinned bool field to types.Issue
- Create migration 023_pinned_column.go for database schema
- Filter out pinned issues in cleanup command before deletion
- Add pinned check to GetTier1Candidates and GetTier2Candidates
- Add pinned check to CheckEligibility for compaction
- Update all SQL queries and scan functions to include pinned field
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add pushpin emoji (📌) prefix to pinned issues in bd list output.
Updates all four output paths: daemon/direct modes, compact/long formats.
🤝 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add pin.go and unpin.go to cmd/bd/ for managing pinned issues.
- bd pin <id> sets Pinned=true on an issue
- bd unpin <id> sets Pinned=false on an issue
Also adds Pinned field support to RPC UpdateArgs for daemon mode.
🤝 Slit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CRITICAL: Fixed dependency resurrection bug that caused removed/orphaned
dependencies to keep coming back after sync.
Root cause: mergeDependencies() was doing a union (additive only) and
completely ignored the base parameter. This meant any dependency present
in either left or right would be included, even if it was intentionally
removed.
Fix: Proper 3-way merge where REMOVALS ARE AUTHORITATIVE:
- If dep was in base and removed by left OR right → stays removed
- If dep wasn't in base and added by left OR right → included
- If dep was in base and both still have it → included
This fixes months of issues with orphaned parent-child relationships
being resurrected during git sync operations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add pinned status for beads that should stay open indefinitely:
- Add StatusPinned constant and update IsValid()
- Add PinnedIssues count to Statistics struct
- Protect pinned issues from bd close (requires --force)
- Show pinned count in bd stats output
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>