Commit Graph

885 Commits

Author SHA1 Message Date
Steve Yegge
97500a8de0 fix(sync): prevent daemon race condition from dirtying working directory
After bd sync completes with sync.branch mode, the daemon or next CLI
command could see a hash mismatch between the restored JSONL file and
the DB metadata, triggering auto-import which then schedules re-export,
dirtying the working directory.

Two fixes:
1. sync.go: Update jsonl_content_hash after restoreBeadsDirFromBranch
   to match the restored file hash
2. daemon_sync.go: Update jsonl_content_hash after performAutoImport
   succeeds (was missing, unlike CLI import path)

Fixes: bd-lw0x, bd-hxou

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 06:54:46 -08:00
Ryan Stortz
4254c3f2f5 feat(config): add BD_NO_INSTALL_HOOKS environment variable to disable git hook installation (#500)
* feat(config): add no-install-hooks config to disable git hook installation

Add `no-install-hooks` boolean config that prevents git hook installation
during `bd init`. This can be set via:
- Environment variable: BD_NO_INSTALL_HOOKS=1
- Global config: ~/.config/bd/config.yaml with `no-install-hooks: true`
- Local config: .beads/config.yaml with `no-install-hooks: true`

The existing `--skip-hooks` flag continues to work and takes precedence.
Default behavior unchanged: hooks install by default.

* docs: add no-install-hooks to configuration documentation

- Add no-install-hooks to Supported Settings table in CONFIG.md
- Add example in config file section
- Add "Disabling Hook Installation" section to GIT_INTEGRATION.md
  with examples for flag, env var, and config file methods
2025-12-13 06:38:26 -08:00
Steve Yegge
e72fe12bbc feat(reset): add integration tests and doctor reset suggestion
- Add 9 integration tests for bd reset command (reset_test.go)
- Tests cover: dry-run, force, skip-init, backup, confirmation,
  cancellation, no-beads-dir, multiple issues, verbose mode
- Enhance bd doctor to suggest reset when >= 3 unfixable errors found
- Addresses bd-aydr.7, bd-aydr.5, bd-aydr.8

Closes: #479 (via GitHub comment with solution)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 10:20:31 +11:00
Steve Yegge
9057aeba17 fix(gitignore): switch to whitelist approach for .beads/.gitignore (#473)
The .beads/.gitignore now ignores everything by default and explicitly
whitelists tracked files. This fixes confusion about which files to
commit when using protected branches workflow.

Changes:
- Use `*` to ignore all by default, then `!file` to whitelist
- Fix config.json -> config.yaml (wrong filename in negation)
- Update doctor check to validate new patterns
- Update PROTECTED_BRANCHES.md documentation
- Simplify git add instructions to just `git add .beads/`

Fixes #473

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 10:14:05 +11:00
Steve Yegge
df84e3f531 fix: skip symlink/permissions tests on Windows
These tests fail on Windows because:
- os.Symlink requires elevated privileges
- Unix-style permissions (0700, 0600) don't apply

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 10:08:34 +11:00
Steve Yegge
2fd1d1fb87 fix: resolve golangci-lint warnings
- Handle ignored errors with explicit _ assignment (errcheck)
- Add #nosec comments for false positive G304/G204 warnings (gosec)
- Fix misspelling: cancelled -> canceled

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 10:07:36 +11:00
matt wilkie
2a3a53531c docs: Add comprehensive documentation for version reporting changes 2025-12-13 10:04:01 +11:00
matt wilkie
0423fc689f fix: Add commit and branch to bd version output (github #503)
- Update Makefile install target to extract and pass git commit/branch via ldflags
- Add -X main.Commit and -X main.Branch to all build configurations in .goreleaser.yml
- Create scripts/install.sh helper for explicit version control during installation
- Add comprehensive tests for commit/branch resolution and output formatting

Fixes github #503: 'bd version' now reports as-built commit hash and branch
information regardless of installation method (make install, go install, or
released binaries from goreleaser).
2025-12-13 10:04:01 +11:00
Steve Yegge
88153f224f feat(reset): implement bd reset CLI command with unit tests
Implements the bd reset command for GitHub issue #479:
- CLI command with flags: --hard, --force, --backup, --dry-run, --skip-init, --verbose
- Impact summary showing issues/tombstones to be deleted
- Confirmation prompt (skippable with --force)
- Colored output for better UX
- Unit tests for reset.go and git.go
- Fix: use --force flag in git rm to handle staged files

Part of epic bd-aydr.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 10:00:47 +11:00
Steve Yegge
ca9d306ef0 feat(reset): implement core reset package for bd reset command
Phase 1 implementation of bd reset (GitHub #479):

- internal/reset/reset.go: Core reset logic with ResetOptions, ResetResult,
  ImpactSummary structs. Handles daemon killing, backup, file removal,
  git operations, and re-initialization.

- internal/reset/backup.go: CreateBackup() for timestamped .beads/ backups
  with permission preservation.

- internal/reset/git.go: Git state detection and operations for --hard mode.
  CheckGitState(), GitRemoveBeads(), GitCommitReset(), GitAddAndCommit().

- cmd/bd/doctor/gitignore.go: Add .beads-backup-*/ to gitignore template.

Code review fixes applied:
- Git rm now runs BEFORE file deletion (was backwards)
- Removed stderr output from core package (CLI-agnostic)
- IsDirty now checks only .beads/ changes, not entire repo
- GitCommitReset handles nothing to commit gracefully
2025-12-13 09:47:26 +11:00
Steve Yegge
7fd11f352c fix(setup): correct allowedTools pattern from "bd:*" to "bd *"
The Claude Code allowedTools pattern uses prefix matching with space separator,
not colon. "Bash(bd *)" matches "bd ready", "bd create", etc.

Follow-up to 3d48458.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 09:46:38 +11:00
Steve Yegge
493ebb451c fix(doctor): make sync-branch warning optional
Users with workflows that don't need sync-branch (e.g., Graphite PR
stacking, single-clone setups) were seeing confusing warnings.

Changes:
- Remove checkSyncBranchQuick() - no longer warn on every bd command
- Change bd doctor from warning to OK status for missing sync-branch
- Update message to "Not configured (optional)"

Fixes #498

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 09:44:23 +11:00
Steve Yegge
3d484587e3 fix(setup): auto-allowlist bd commands in Claude Code (#511)
Add bd to Claude Code allowedTools when running `bd setup claude` so
that all bd commands (create, update, close, etc.) can run without
requiring per-command approval.

Changes:
- Add addAllowedTool() and removeAllowedTool() helper functions
- InstallClaude() now adds "Bash(bd:*)" to allowedTools
- RemoveClaude() cleans up the allowedTools entry
- Add tests for new functionality

Users who have already run `bd setup claude` can run it again to add
the missing allowedTools entry while keeping their existing hooks.

Fixes #511

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 09:42:52 +11:00
Steve Yegge
4f44265f1d fix: make hook tests worktree-aware by using getGitDir()
Tests were hardcoding '.git' paths directly, which fails in git worktrees
where .git is a file (not a directory) containing a pointer to the actual
git directory.

Changes:
- Replace hardcoded '.git' paths with getGitDir() calls in all hook tests
- Add os.MkdirAll() calls to ensure hooks directory exists before writing

Fixes test failures in:
- TestInstallHooks, TestInstallHooksBackup, TestInstallHooksForce,
  TestUninstallHooks, TestInstallHooksShared (hooks_test.go)
- TestDetectExistingHooks, TestInstallGitHooks_NoExistingHooks,
  TestInstallGitHooks_ExistingHookBackup (init_hooks_test.go)

Cherry-picked from PR #472

Co-Authored-By: matt wilkie <maphew@gmail.com>

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 08:42:26 +11:00
Rod Davenport
6985ea94e5 fix(sync): protect local issues from git-history-backfill during sync (#485)
Fix sync bug where newly created issues were incorrectly tombstoned during bd sync.

The root cause was git-history-backfill finding issues in local commits on the sync branch, then tombstoning them when they weren't in the merged JSONL. The fix protects issues from the left snapshot (local export) from git-history-backfill.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-12-12 13:28:48 -08:00
Charles P. Cross
8af08460a7 Enable daemon RPC support for delete operations to trigger auto-sync, Fix for issue #527 (#528)
Enable daemon RPC support for delete operations to trigger auto-sync.

This PR adds delete operation support to the RPC daemon, ensuring that delete operations emit mutation events and trigger auto-sync like other mutating operations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2025-12-12 13:19:31 -08:00
Charles P. Cross
056b989e46 Update pre-commit hook regression test for proper isolation
The TestSyncBranchCommitAndPush_WithPreCommitHook test needed fixes
to run correctly in isolation:

1. Set global dbPath variable so findJSONLPath() can locate the JSONL
   file during sync operations. Without this, the test failed with
   "JSONL path not found".

2. Add dummy git remote so hasGitRemote() returns true. The
   syncBranchCommitAndPush function skips sync branch operations
   when no remote is configured (local-only mode support).

3. Relax commit count assertion to check for "multiple commits"
   rather than exact count of 4, since sync branch initialization
   may add an extra commit depending on timing.

These changes ensure the regression test properly validates that
--no-verify bypasses pre-commit hooks in worktree commits.

Test verified:
- FAILS without --no-verify fix (confirms bug detection)
- PASSES with --no-verify fix (confirms fix works)
2025-12-11 07:11:42 -05:00
Charles P. Cross
eaec440358 Fix integration test compilation errors in cmd/bd
The integration tests were failing to compile due to several issues
introduced by API changes that weren't reflected in the test files:

1. daemon_test.go:
   - getPIDFilePath() signature changed: removed boolean parameter
   - getLogFilePath() signature changed: removed boolean parameter
   - Removed duplicate windowsOS constant (already in test_helpers_test.go)

2. daemon_parent_test.go:
   - Removed duplicate runGitCmd() function (already in git_sync_test.go
     with more functionality including date env vars)
   - Removed unused os/exec import

These fixes allow `go test -tags integration ./cmd/bd` to compile
successfully. The test suite can now be run to verify daemon and
sync branch functionality.

No behavioral changes - only fixing test compilation issues.
2025-12-11 07:11:15 -05:00
Charles P. Cross
c9dc0276aa Fix daemon sync branch commit failing with pre-commit hooks
When pre-commit hooks are installed (via "bd hooks install"), daemon auto-sync
to sync branches fails with "git commit failed in worktree: exit status 1".

Root cause:
- gitCommitInWorktree() was missing --no-verify flag
- Pre-commit hook runs "bd sync --flush-only" which fails in worktree context
- Worktree has .beads directory, triggering hook execution
- Hook fails because bd cannot find proper database in worktree path

The fix adds --no-verify to git commit in gitCommitInWorktree(), matching
the existing implementation in internal/syncbranch/worktree.go line 684.

This is correct because:
- Worktree commits are internal to bd sync operations
- Running pre-commit hooks in worktree context is semantically wrong
- The library function already skips hooks for this reason

Includes regression test that:
- Creates a repo with sync branch configured
- Installs a failing pre-commit hook (simulating bd hook behavior)
- Verifies commits succeed because --no-verify bypasses the hook
- Tests multiple consecutive commits to ensure consistent behavior

Tested manually by:
1. Creating issue with "bd create" (triggers mutation event)
2. Verifying daemon logs show successful commit to sync branch
3. Confirming push to remote sync branch completes
2025-12-09 22:17:23 -05:00
Steve Yegge
08d8353619 feat(tombstones): add migrate-tombstones command and compact pruning
- Add bd migrate-tombstones command (bd-8f9) to convert legacy
  deletions.jsonl entries to inline tombstones in issues.jsonl
  - Supports --dry-run to preview changes
  - Supports --verbose for detailed progress
  - Archives deletions.jsonl with .migrated suffix after migration

- Update bd compact to prune expired tombstones (bd-okh)
  - All compact modes now prune tombstones older than 30-day TTL
  - Reports count of pruned tombstones in output

- Add resurrection merge test (bd-bob)
  - Tests scenario where base is tombstone but both left/right resurrect

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 21:34:35 +11:00
Steve Yegge
cda4c42e11 test(export): add test for tombstone inclusion in JSONL export (bd-yk8w)
Verify that tombstones are properly included when exporting issues
to JSONL format, including all tombstone-specific fields like
DeletedAt, DeletedBy, DeleteReason, and OriginalType.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 21:14:13 +11:00
Steve Yegge
49bfdc2523 fix: use proper YAML parsing for no-db mode detection (bd-r6k2)
Replace fragile strings.Contains("no-db: true") with proper YAML parsing
to avoid false matches in comments or nested keys.

Changes:
- Add NoDb field to localConfig struct
- Add isNoDbModeConfigured() helper function
- Update main.go and doctor.go to use the helper
- Add 8 test cases for isNoDbModeConfigured

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 21:09:32 +11:00
Steve Yegge
cc89ce4914 chore: sync changes from beads-sync
- Close bd-6y5 (getLocalSyncBranch tests)
- Include tombstone export logic fix (bd-81x6)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 20:57:58 +11:00
Steve Yegge
99b2e7e4c3 test(autoimport): add unit tests for getLocalSyncBranch (bd-6y5)
Tests cover:
- Missing config.yaml
- Config without sync-branch key
- Unquoted, double-quoted, and single-quoted values
- Environment variable precedence
- Empty files and whitespace-only content
- Comments (both full-line and inline)
- Special characters in branch names
- Nested sync-branch (should be ignored)
- Mixed config files

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 20:57:13 +11:00
Steve Yegge
519a0ffd99 fix(autoimport): use proper YAML parsing for sync-branch config (bd-0rh)
Replace fragile line-by-line parsing with yaml.Unmarshal to handle:
- Indented sync-branch values
- Comments containing sync-branch
- Multi-line values
- Values with special characters

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 20:44:44 +11:00
Steve Yegge
f4864c9cc4 feat(import/export): add tombstone support (bd-dve)
Update import/export to handle tombstones for deletion sync propagation:

Exporter:
- Include tombstones in JSONL output by setting IncludeTombstones: true
- Both single-repo and multi-repo exports now include tombstones

Importer:
- Tombstones from JSONL are imported as-is (they're issues with status=tombstone)
- Legacy deletions.jsonl entries are converted to tombstones via convertDeletionToTombstone()
- Non-tombstone issues in deletions manifest are still skipped (backward compat)
- purgeDeletedIssues() now creates tombstones instead of hard-deleting

This is Phase 2 of the tombstone implementation (bd-dli design), enabling
inline soft-delete tracking for cross-clone deletion synchronization.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 20:34:02 +11:00
Steve Yegge
2e40ae80fb Merge branch 'rig-e048/OchreFerret' 2025-12-07 20:24:12 +11:00
Steve Yegge
8b64917d59 feat(doctor): add configuration value validation (bd-alz)
Add comprehensive validation for config values in bd doctor:

YAML config (config.yaml) validations:
- actor: alphanumeric with dashes, underscores, dots, @
- db: valid database extension (.db, .sqlite, .sqlite3)
- Boolean flags: json, no-daemon, no-auto-flush, no-auto-import,
  no-db, auto-start-daemon validate as true/false/yes/no/1/0/on/off
- sync.require_confirmation_on_mass_delete: boolean validation
- repos.primary: must be a directory if path exists
- repos.additional: paths must be directories if they exist

Database config validations:
- status.custom: validates custom status names are lowercase
  alphanumeric with underscores, checks for conflicts with built-in
  statuses (open, in_progress, blocked, closed)
- sync.branch (legacy): validates as git branch name

Includes tests for all new validation functions.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 20:21:22 +11:00
Steve Yegge
213ed65175 test(doctor): add tests for export diagnostics feature (bd-9cc)
Add unit tests verifying the --output flag registration and
exportDiagnostics function for saving doctor results to JSON files.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 20:19:49 +11:00
Steve Yegge
e701e34c38 fix: resolve symlink paths in autoimport.go for macOS
Both findBeadsDir() and findGitRoot() now use filepath.EvalSymlinks()
to resolve to canonical paths before comparison. This fixes the issue
where filepath.Rel() fails on macOS because /var is a symlink to
/private/var, causing path mismatches.

Fixes: TestDatabaseReinitialization failures on macOS

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-05 16:52:16 -08:00
Steve Yegge
2adba0d8e0 feat(tombstone): implement delete-to-tombstone and TTL expiration (bd-3b4, bd-olt)
Phase 1 of tombstone migration: bd delete now creates tombstones instead
of hard-deleting issues.

Key changes:
- Add CreateTombstone() method to SQLiteStorage for soft-delete
- Modify executeDelete() to create tombstones instead of removing rows
- Add IsExpired() method with 30-day default TTL and clock skew grace
- Fix deleted_at schema from TEXT to DATETIME for proper time scanning
- Update delete.go to call CreateTombstone (single issue path)
- Still writes to deletions.jsonl for backward compatibility (dual-write)
- Dependencies are removed when creating tombstones
- Tombstones are excluded from normal searches (bd-1bu)

TTL constants:
- DefaultTombstoneTTL: 30 days
- MinTombstoneTTL: 7 days (safety floor)
- ClockSkewGrace: 1 hour

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 16:20:43 -08:00
Steve Yegge
5c49c25e9e feat(tombstone): add P2 code review improvements (bd-saa, bd-1bu, bd-nyt)
- Add partial index on deleted_at for efficient TTL queries
- Exclude tombstones from SearchIssues by default (new IncludeTombstones filter)
- Report tombstone count separately in GetStatistics
- Display tombstone count in bd stats output

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 15:48:46 -08:00
Steve Yegge
ce119551f6 fix(init): use correct gitRef in error message, remove unused var
Small fixes from code review:
- Error message now shows actual gitRef instead of hardcoded HEAD
- Removed unused lineNum variable in readFirstIssueFromGit

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 14:51:32 -08:00
Steve Yegge
0d2dc53c67 fix(init): bootstrap from sync-branch when configured (bd-0is)
When sync-branch is configured in config.yaml, bd init now reads from
that branch (origin/<branch> first, then local <branch>) instead of
HEAD. This ensures fresh clones correctly import issues from the sync
branch.

Key changes:
- checkGitForIssues() now returns gitRef (third return value)
- New getLocalSyncBranch() reads sync-branch directly from config.yaml
  (not cached global config) to handle test environments where CWD changes
- importFromGit() accepts gitRef parameter to read from correct branch
- Added readFirstIssueFromGit() for prefix auto-detection from git
- Fixed macOS symlink issue: filepath.EvalSymlinks() ensures /var and
  /private/var paths are normalized before filepath.Rel()

Part of GitHub issue #464 (beads deletes issues in multi-clone environments)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 14:47:02 -08:00
Darin
e0734e230f fix: NixOS symlink compatibility for mtime and permission checks (#459)
* fix: use os.Lstat for symlink-safe mtime and permission checks

On NixOS and other systems using symlinks heavily (e.g., home-manager),
os.Stat follows symlinks and returns the target's metadata. This causes:

1. False staleness detection when JSONL is symlinked - mtime of target
   changes unpredictably when symlinks are recreated
2. os.Chmod failing or changing wrong file's permissions when target
   is in read-only location (e.g., /nix/store)
3. os.Chtimes modifying target's times instead of the symlink itself

Changes:
- autoimport.go: Use Lstat for JSONL mtime in CheckStaleness()
- import.go: Use Lstat in TouchDatabaseFile() for JSONL mtime
- export.go: Skip chmod for symlinked files
- multirepo.go: Use Lstat for JSONL mtime cache
- multirepo_export.go: Use Lstat for mtime, skip chmod for symlinks
- doctor/fix/permissions.go: Skip permission fixes for symlinked paths

These changes are safe cross-platform:
- On systems without symlinks, Lstat behaves identically to Stat
- Symlink permission bits are ignored on Unix anyway
- The extra Lstat syscall overhead is negligible

Fixes symlink-related data loss on NixOS. See GitHub issue #379.

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

Co-Authored-By: Claude <noreply@anthropic.com>

* test: add symlink behavior tests for NixOS compatibility

Add tests that verify symlink handling behavior:
- TestCheckStaleness_SymlinkedJSONL: verifies mtime detection uses
  symlink's own mtime (os.Lstat), not target's mtime (os.Stat)
- TestPermissions_SkipsSymlinkedBeadsDir: verifies chmod is skipped
  for symlinked .beads directories
- TestPermissions_SkipsSymlinkedDatabase: verifies chmod is skipped
  for symlinked database files while still fixing .beads dir perms

Also adds devShell to flake.nix for local development with go, gopls,
golangci-lint, and sqlite tools.

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

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-05 13:22:09 -08:00
Tim Haasdyk
07c97a2b74 fix: make bd onboard output generic, not beads-specific (#465)
The copilotInstructionsContent in onboard.go contained content specific to
developing the beads project itself (Go tech stack, SQLite, Cobra, project
structure, release scripts, etc.). This content doesn't make sense when
running bd onboard in other repositories that use bd for issue tracking.

Removed:
- Tech Stack section (Go, SQLite, Cobra, etc.)
- Coding Guidelines section (beads development instructions)
- Project Structure section (beads directory tree)
- Scripts section (bump-version.sh, release.sh, etc.)
- Key Documentation section (beads-specific docs)
- Beads-specific rules (BEADS_DB testing, test issues in production DB)

Kept:
- All bd command examples and workflow (unchanged)
- Priorities and issue types
- MCP server instructions
- Generic rules applicable to any project using bd

The beads repo's own .github/copilot-instructions.md is manually maintained
and still contains the beads-specific development instructions.
2025-12-05 13:20:51 -08:00
Steve Yegge
6789e4fd9a feat: add hooks to plugin.json, eliminating need for global install
The beads plugin now provides SessionStart and PreCompact hooks directly
via plugin.json. Users no longer need to run 'bd setup claude' when using
the plugin - hooks are automatically available.

Changes:
- Add hooks section to .claude-plugin/plugin.json with SessionStart and
  PreCompact hooks that run 'bd prime'
- Update doctor/claude.go to recognize plugin-provided hooks as valid
- Update tips.go to check for plugin installation when determining if
  Claude integration is complete
- Update messaging to recommend plugin installation as primary option

The 'bd setup claude' command remains available for CLI-only users who
do not want to install the plugin.

Closes #462

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 22:44:42 -08:00
Steve Yegge
46abe8caf7 fix: add .local_version to GitignoreTemplate
Fixes #460 - .local_version was added for version tracking but not
included in the gitignore template, causing it to show as untracked.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 20:37:16 -08:00
Abhinav Gupta
ac8ef9b9e3 test: replace manual os.Chdir with t.Chdir in tests (#457)
Replaces manual working directory save/restore patterns
with Go's built-in `t.Chdir()` helper across 23 test files.

The manual pattern involved calling `os.Getwd()` to save
the original directory, using `defer os.Chdir(origWd)` for
restoration, and manually handling errors during directory
changes. This boilerplate has been replaced with single
`t.Chdir(path)` calls that handle cleanup automatically.

The `t.Chdir()` method automatically restores the working
directory when the test completes, eliminating the need for
manual defer statements and error handling.

Total:
~75 instances replaced (assuming Claude's math is right)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 11:21:43 -08:00
Steve Yegge
f4b8a7ad4f feat: change deletions TTL default from 7 to 3 days
Reduces the default retention period for deletion manifest entries.
Shorter TTL limits blast radius of stale deletions that can poison
beads installations when agents get out of sync.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 22:44:59 -08:00
Steve Yegge
7f1e45e3db Merge pull request #456 from abhinav/add-setup-stealth-flag
feat(setup claude): add --stealth flag
2025-12-03 20:46:52 -08:00
Steve Yegge
019a90f511 Merge pull request #455 from abhinav/add-prime-stealth-flag
feat(prime): add --stealth flag for flush-only workflow
2025-12-03 20:26:01 -08:00
Steve Yegge
6267f3b7f5 fix: add test parallelism and increase Windows CI timeout
- Increase Windows test timeout from 20m to 30m
- Add -parallel=4 flag to allow concurrent test execution
- Add t.Parallel() to safe table-driven tests in validate_test.go,
  autoimport_test.go, and sync_test.go

This should prevent the Windows CI timeout caused by the cumulative
runtime of cmd/bd tests exceeding 20 minutes.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 18:30:53 -08:00
Abhinav Gupta
4a7d7b0b41 feat(setup claude): add --stealth flag
Add a `--stealth` flag to `bd setup claude` that installs
Claude Code hooks using `bd prime --stealth` instead of
`bd prime`. This extends the stealth workflow introduced for
`bd prime` to the setup command, enabling workflows where git
operations should be deferred or handled separately from bd
database flushing.

When `--stealth` is specified, the installed hooks call
`bd prime --stealth`, which outputs only `bd sync --flush-only`
in the close protocol, omitting all git operations.

Update `RemoveClaude()` to remove both command variants
(`bd prime` and `bd prime --stealth`) for backwards
compatibility with existing installations. Update
`hasBeadsHooks()` to detect either variant as a valid
installation.

Add comprehensive test coverage for stealth mode: hook
installation with stealth command, removal of both variants,
detection of both variants, and idempotency with stealth mode.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 18:10:35 -08:00
Abhinav Gupta
09a9ffa922 feat(prime): add --stealth flag for flush-only workflow
Add a `--stealth` flag to `bd prime` that outputs a simplified
workflow using only `bd sync --flush-only`, omitting all git
operations (commit, push, pull).

This addresses use cases where git operations need to be deferred
or handled separately from the bd workflow (e.g. bd init --stealth),
where committing files is may not desired as part of the Claude
conversation.

In stealth mode, the close protocol shows only the flush step.

Includes tests for current and existing functionality.

To make testing easier,
refactor output functions to accept `io.Writer` parameters
instead of writing directly to `os.Stdout`,
and convert `isEphemeralBranch` from a function to a
variable for stubbing.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 18:08:33 -08:00
Steve Yegge
76f7341cf4 fix: resolve CI lint errors and Windows test timeout
- Fix gosec G204/G304 warnings by adding exclusions for safe subprocess
  launches and file reads in doctor.go, jira.go, migrate_sync.go, and
  syncbranch/worktree.go
- Fix misspell: "cancelled" -> "canceled" in sync.go
- Fix unparam: mark unused ctx params in jira.go placeholder functions
- Fix errcheck: explicitly ignore fmt.Sscanf return in doctor.go and
  use closure pattern for deferred os.RemoveAll in worktree.go
- Increase Windows test timeout from 10m to 20m to prevent CI timeouts

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 17:50:23 -08:00
Steve Yegge
c9eeecf0c3 chore: Bump version to 0.29.0
Updated all component versions:
- bd CLI: 0.28.0 → 0.29.0
- Plugin: 0.28.0 → 0.29.0
- MCP server: 0.28.0 → 0.29.0
- npm package: 0.28.0 → 0.29.0
- Documentation: 0.28.0 → 0.29.0

Generated by scripts/bump-version.sh
2025-12-03 16:24:46 -08:00
Steve Yegge
d451945b00 docs: update changelog and info.go for v0.29.0 release
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 16:24:24 -08:00
Steve Yegge
a1fba65c67 feat: add --estimate flag to bd create/update commands (GH #443)
The estimated_minutes field existed in the Issue schema but wasn't exposed
via CLI. This adds:

- --estimate / -e flag to bd create (e.g., bd create "Task" --estimate 120)
- --estimate / -e flag to bd update (e.g., bd update bd-xyz --estimate 60)
- EstimatedMinutes field to RPC CreateArgs and UpdateArgs
- Server-side handling in handleCreate and updatesFromArgs
- Validation for non-negative values

The value is specified in minutes and is useful for planning and
prioritization. The vscode-beads extension already has an Estimate column
that can now be populated.

Fixes #443

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 15:55:35 -08:00
Ryan Snodgrass
49b3353688 docs: encourage batch close and parallel creation in bd prime output
- Update examples to show `bd close <id1> <id2> ...` for batch closing
- Add quick reference entry for closing multiple issues at once
- Add tip about using parallel subagents for creating multiple issues
- Add comment in example about running bd create in parallel

Cherry-picked from PR #452 (prime.go changes only)

Co-Authored-By: Ryan Snodgrass <rsnodgrass@gmail.com>

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 15:32:39 -08:00