Commit Graph

45 Commits

Author SHA1 Message Date
matt wilkie
e01b7412d9 feat: add Git worktree compatibility (PR #478)
Adds comprehensive Git worktree support for beads issue tracking:

Core changes:
- New internal/git/gitdir.go package for worktree detection
- GetGitDir() returns proper .git location (main repo, not worktree)
- Updated all hooks to use git.GetGitDir() instead of local helper
- BeadsDir() now prioritizes main repository's .beads directory

Features:
- Hooks auto-install in main repo when run from worktree
- Shared .beads directory across all worktrees
- Config option no-install-hooks to disable auto-install
- New bd worktree subcommand for diagnostics

Documentation:
- New docs/WORKTREES.md with setup instructions
- Updated CHANGELOG.md and AGENT_INSTRUCTIONS.md

Testing:
- Updated tests to use exported git.GetGitDir()
- Added worktree detection tests

Co-authored-by: Claude <noreply@anthropic.com>
Closes: #478
2025-12-13 12:50:33 -08: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
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
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
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
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
Steve Yegge
e5de1db585 feat(doctor): add --output flag to export diagnostics (bd-9cc)
Add ability to save doctor diagnostics to a JSON file for historical
analysis and bug reporting. The export includes timestamp and platform
info (OS, Go version, SQLite version) for tracking intermittent issues.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 11:41:00 -08:00
Steve Yegge
a4163e42e7 feat(doctor): add configuration value validation (bd-alz)
Add a new Config Values check to bd doctor that validates:
- flush-debounce: must be a valid duration (e.g., 30s, 1m)
- issue-prefix: must start with letter, alphanumeric with dashes/underscores
- routing.mode: must be auto, maintainer, or contributor
- sync-branch: must be a valid git branch name
- routing paths: warns if configured paths do not exist
- metadata.json database: should be filename (not path), with db extension
- metadata.json jsonl_export: should have .jsonl extension
- deletions_retention_days: must be non-negative if set

This catches misconfigurations before they cause runtime errors.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 10:31:50 -08:00
Steve Yegge
18191f5e54 feat(doctor): detect and fix stale sync branches (bd-6rf)
Add 'Sync Branch Health' check that detects:
1. Local sync branch diverged from remote (after force-push reset)
2. Sync branch significantly behind main on source files (20+ commits, 50+ files)

Add --fix support that:
- Handles worktree case (resets within worktree)
- Handles regular branch case (deletes and recreates from main)
- Pushes the reset branch to remote

This helps contributors whose local beads-sync becomes orphaned after
someone else resets the branch.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 23:51:20 -08:00
Steve Yegge
3df138445a fix(init): allow fresh clones with JSONL to run bd init (bd-4h9)
Previously, bd init blocked when JSONL existed with issues but no database,
telling users to run 'bd doctor --fix'. But doctor --fix just ran bd migrate
which requires an existing database - creating a circular dependency.

Now:
- bd init allows fresh clones (JSONL exists, no database) to proceed
- bd init creates the database and imports from JSONL automatically
- bd doctor --fix runs bd init (not migrate) when there's no database

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 21:18:23 -08:00
Steve Yegge
0b13a0df3c fix: support git worktrees in hooks installation
Use `git rev-parse --git-dir` instead of hardcoded `.git` path to find
the actual git directory. In worktrees, `.git` is a file containing a
gitdir pointer, not a directory.

Changes:
- Add getGitDir() helper in hooks.go
- Update installHooks(), uninstallHooks(), CheckGitHooks() to use it
- Update hooksInstalled(), detectExistingHooks(), installGitHooks() in init.go
- Update checkHooksQuick() in doctor.go
- Update GitHooks() in doctor/fix/hooks.go
- Update tests to use real git repos via `git init`

Fixes bd-63l

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 23:19:57 -08:00
Steve Yegge
d5f2d91d04 fix(ci): more changes to fix failing CI (#415)
Fixes from maphew including:
- Remove test for deleted isPathWithinDir function
- Add gosec nolint directives for safe file operations
- Add rm -rf .beads before init in CI workflow
- Simplify panic handling and file operations

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

Co-Authored-By: maphew <maphew@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 22:24:29 -08:00
Steve Yegge
f321857f18 Merge pull request #412 from joelklabo/fix/secure-jsonl-paths
Security fix for JSONL path handling - adds path traversal protection
2025-11-29 15:05:10 -08:00
Steve Yegge
13b2ab6c95 feat(doctor): add fresh clone detection check (bd-4ew)
Add CheckFreshClone function that detects when JSONL contains issues
but no database exists. Recommends 'bd init --prefix <detected-prefix>'
to hydrate the database. This check appears early in doctor output
to guide users on fresh clones.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 22:15:34 -08:00
Steve Yegge
eeab5e55e3 test(doctor): add test for beads.base.jsonl merge artifacts (bd-ov1)
Verify that beads.base.jsonl and beads.left.jsonl patterns are correctly
excluded from the 'multiple JSONL files' warning, same as issues.base.jsonl.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:52:48 -08:00
Joel Klabo
cb6ccef7c2 fix: harden JSONL path handling
- bound fresh-clone JSONL discovery to the .beads dir (abs path, traversal guard) before reading counts
- add safeWorkspacePath/isWithinWorkspace helpers and use in doctor fixes (database_config, untracked) to reject absolute/traversal inputs and confine .gitattributes edits
- normalize git status paths and path-guard tests for cross-OS (Windows) compatibility
- add regression tests for the new guards
2025-11-28 18:58:04 -08:00
Steve Yegge
86d6ffe57d fix(doctor): exclude merge artifacts from multiple JSONL warning
Add .base.jsonl, .left.jsonl, and .right.jsonl patterns to the skip list
in CheckLegacyJSONLFilename. These are legitimate git merge conflict
artifacts that should not trigger a warning about multiple JSONL files.

Fixes: bd-nsb

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 17:42:23 -08:00
Steve Yegge
3f609267d4 fix: doctor deletions check and onboard docs improvements
- Fix doctor to treat empty deletions.jsonl as valid (0 entries OK status)
- Fix HydrateDeletionsManifest to create empty file when no deletions found
- Add --parent flag documentation to onboard command
- Add CLI --help tip throughout onboard documentation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 13:23:14 -08:00
Steve Yegge
ff3352ab23 bd-6xd: Standardize on issues.jsonl as canonical filename
- Change default JSONL filename from beads.jsonl to issues.jsonl
- Add bd doctor check and fix to auto-migrate legacy beads.jsonl configs
- Update FindJSONLPath to prefer issues.jsonl over beads.jsonl
- Add CheckLegacyJSONLConfig and CheckLegacyJSONLFilename checks
- Add LegacyJSONLConfig fix to rename files and update config
- Update .gitattributes to reference issues.jsonl
- Fix tests to expect new canonical filename
- Add bd-6xd to v0.25.1 release notes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 22:02:59 -08:00
Steve Yegge
8ad0144142 bd sync: 2025-11-26 20:33:12 2025-11-26 20:33:12 -08:00
Steve Yegge
c3b4243450 fix: bd doctor no longer warns about deletions.jsonl
The multiple JSONL files check was incorrectly flagging deletions.jsonl
as a problem, even though it is a valid system file for tracking deleted
issues. Added deletions.jsonl to the skip list alongside backups and
merge artifacts.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 17:48:16 -08:00
Steve Yegge
ddced40153 fix: add nosec annotations for gosec lint warnings 2025-11-25 18:22:05 -08:00
Steve Yegge
e4f9c3556f feat(sync): prevent zombie resurrection from stale clones
Add JSONL sanitization after git pull to remove deleted issues that
git's 3-way merge may resurrect. Also add bd doctor check to hydrate
deletions.jsonl from git history for pre-v0.25.0 deletions.

Changes:
- Add sanitizeJSONLWithDeletions() in sync.go (Step 3.6)
- Add checkDeletionsManifest() in doctor.go (Check 18)
- Add HydrateDeletionsManifest() fix in doctor/fix/deletions.go
- Add looksLikeIssueID() validation to prevent false positives
- Add comprehensive tests for sanitization logic

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-25 18:11:45 -08:00
Steve Yegge
45464ca3f9 fix: skip file permission tests on Windows
Windows doesn't support Unix-style file permissions, so these tests
will always fail. Skip the permission verification on Windows while
still testing the core functionality (file creation, content).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 22:23:45 -08:00
Steve Yegge
9767e57024 bd doctor: add Claude integration verification checks
Add two new checks to verify Claude Code integration:
- CheckBdInPath: verifies 'bd' is in PATH (needed for hooks)
- CheckDocumentationBdPrimeReference: checks if docs reference 'bd prime'
  and verifies the command exists (detects version mismatches)

Closes bd-o78

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 22:10:58 -08:00
Steve Yegge
76e3f27eb0 fix: CI test failures and lint errors
- Fixed test file naming: issues.jsonl -> beads.jsonl
  - beads_test.go: Update expected path in TestFindJSONLPath
  - internal/beads/beads_test.go: Update TestFindJSONLPathDefault
  - cmd/bd/main_test.go: Update TestAutoFlushJSONLContent

- Fixed lint errors (gosec):
  - G304: Added nosec comments for file operations with user-provided paths
  - G204: Added nosec comment for subprocess with controlled binary path

- Fixed lint errors (errcheck):
  - cmd/bd/test_wait_helper.go: Acknowledge error return values with _
  - cmd/bd/onboard.go: Handle fmt.Fprintf error return

All tests passing locally. All lint checks passing.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 00:21:01 -08:00
Steve Yegge
d1641c7d2e Fix bd-afd: Auto-fix metadata.json jsonl_export mismatch
## Summary

When metadata.json gets deleted (git clean, merge conflict, rebase), the
version tracking code auto-recreates it using DefaultConfig() which hardcoded
jsonl_export to 'issues.jsonl'. But many repos (including beads itself) use
'beads.jsonl', causing a mismatch between config and actual JSONL file.

## Changes

1. **bd doctor --fix auto-detection** (cmd/bd/doctor/fix/database_config.go)
   - New DatabaseConfig() fix function that auto-detects actual JSONL file
   - Prefers beads.jsonl over issues.jsonl (canonical name)
   - Skips backup files and merge artifacts
   - Wired into doctor.go applyFixes()

2. **Version tracking auto-detection** (cmd/bd/version_tracking.go)
   - trackBdVersion() now scans for existing JSONL files before defaulting
   - Prevents mismatches when metadata.json gets recreated
   - Added findActualJSONLFile() helper function

3. **Canonical default name** (internal/configfile/configfile.go)
   - DefaultConfig() changed from issues.jsonl to beads.jsonl
   - Aligns with canonical naming convention

4. **FindJSONLPath preference** (internal/beads/beads.go)
   - Now prefers beads.jsonl over issues.jsonl when scanning
   - Default changed from issues.jsonl to beads.jsonl

5. **Test coverage**
   - Added comprehensive tests for DatabaseConfig fix
   - Updated configfile tests for new default
   - Verified backup file skipping logic

## Testing

- All existing tests pass
- New tests verify auto-fix behavior
- Integration tested with simulated mismatches

Closes: bd-afd
2025-11-23 23:11:08 -08:00
Steve Yegge
ae5a4ac6ea Add security tests for WriteFile permissions in doctor command
Resolves bd-ee1: Add security tests for WriteFile permissions in doctor command

Added comprehensive security tests for the FixGitignore function to verify:
- Files are created with 0600 permissions (secure, owner-only read/write)
- Existing files with insecure permissions are fixed
- Read-only files can be updated (permissions fixed first)
- File ownership is correct
- Permissions are enforced even on systems that respect umask

Also improved FixGitignore implementation to:
- Handle read-only files by fixing permissions before writing
- Explicitly set permissions after write to ensure 0600 regardless of umask
- Maintain secure permissions throughout the operation

Tests verify the gosec G306 security concern is properly addressed.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 21:19:14 -08:00
Steve Yegge
83609d5098 Add bd doctor check and fix for missing sync.branch config (bd-rsua)
Problem: Existing beads repositories initialized before commit a4c38d5 don't have sync.branch configured. This causes 'bd sync --status' to fail with a confusing error.

Solution: Added new check in 'bd doctor' that detects when sync.branch is not configured and provides automatic fix via 'bd doctor --fix'. The fix automatically sets sync.branch to the current branch using 'git symbolic-ref --short HEAD'.

Changes:
- Added checkSyncBranchConfig() function in doctor.go
- Created fix/sync_branch.go with SyncBranchConfig() fix handler
- Added comprehensive test coverage in doctor_test.go
- Integrated check into applyFixes() switch statement

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 21:09:55 -08:00
Steve Yegge
b409870ce5 Fix linter issues and test failures
- Fix spelling: cancelled → canceled, cancelling → canceling
- Remove unused error return from performFlush() function
- Check cmd.Help() error return in search.go
- Fix file permissions in gitignore.go (0644 → 0600)
- Update tests to match performFlush signature change
- Remove unused os import from flush_manager.go
2025-11-22 00:11:45 -08:00
Steve Yegge
87ee3a674e Improve bd doctor JSONL checks to focus on real problems
Previously bd doctor warned about using beads.jsonl vs issues.jsonl, but
users should be free to configure any name they want. The real problems are:
1. Having multiple JSONL files (sync/merge conflicts)
2. Configuration not matching reality

Changes:
- Rewrote CheckLegacyJSONLFilename to scan for ALL .jsonl files
- Now filters out merge artifacts (backup, .orig, .bak, etc.)
- Warns only when multiple real JSONL files exist
- Added CheckDatabaseConfig to detect when configured paths do not match
  what actually exists on disk
- Updated tests to verify backup files are ignored
- Added test cases for custom JSONL filenames

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 23:44:26 -08:00
Steve Yegge
c4c5c8063a Fix: Change default JSONL filename from beads.jsonl to issues.jsonl
The canonical beads database name is issues.jsonl. Tens of thousands of users
have issues.jsonl, and beads.jsonl was only used by the Beads project itself
due to git history pollution.

Changes:
- Updated bd doctor to warn about beads.jsonl instead of issues.jsonl
- Changed default config from beads.jsonl to issues.jsonl
- Reversed precedence in checkGitForIssues to prefer issues.jsonl
- Updated git merge driver config to use issues.jsonl
- Updated all tests to expect issues.jsonl as the default

issues.jsonl is now the canonical default; beads.jsonl is legacy

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 23:34:22 -08:00
Steve Yegge
6e702d3ecd Merge branch 'main' of https://github.com/steveyegge/beads 2025-11-21 20:40:23 -05:00
Steve Yegge
ddd209e26a fix: Correct git merge driver placeholders from %L/%R to %A/%B
Git merge drivers only support three placeholders:
- %O (ancestor/base)
- %A (current version)
- %B (other branch's version)

The code was incorrectly using %L and %R, which don't exist in git,
causing them to be passed through literally and breaking JSONL merges.

Changes:
- Fixed merge driver config in init.go, merge.go, README.md, docs
- Added detection in bd doctor with clear error messages
- Added auto-fix in bd doctor --fix
- Added proactive warning in bd sync before git pull
- Added reactive error detection after merge failures
- Updated all tests to use correct placeholders

Now users get helpful guidance at every step:
1. bd doctor detects the issue
2. bd doctor --fix auto-corrects it
3. bd sync warns before pulling if misconfigured
4. Error messages suggest bd doctor --fix when merge fails

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 20:40:18 -05:00
Steve Yegge
8efab3df87 chore: Move design/audit docs from cmd/bd to docs/
Relocate documentation files to centralize all .md files in docs/ directory
(except those with historical precedent in specific locations like commands/,
examples/, integrations/, etc.).

Files moved:
- cmd/bd/doctor/claude.md -> docs/CLAUDE_INTEGRATION.md
- cmd/bd/MAIN_TEST_REFACTOR_NOTES.md -> docs/MAIN_TEST_REFACTOR_NOTES.md
- cmd/bd/TEST_SUITE_AUDIT.md -> docs/TEST_SUITE_AUDIT.md

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 20:31:47 -05:00
Steve Yegge
e447acce9e Merge branch 'main' of https://github.com/steveyegge/beads 2025-11-20 19:37:01 -05:00
Steve Yegge
f01326832f Enhance bd doctor with bd prime migration recommendations (bd-0fvq)
Add comprehensive detection and migration guidance for old beads integration
patterns. This helps users adopt the more efficient bd prime approach.

Changes:
- Enhanced CheckLegacyBeadsSlashCommands with detailed migration steps
  and token efficiency benefits (99% reduction: ~10.5k → ~50 tokens)
- Added CheckAgentDocumentation to detect missing AGENTS.md/CLAUDE.md
  and suggest bd onboard or bd setup claude
- Enhanced CheckClaude to recommend bd prime hooks for MCP-only setups
  with clear token efficiency messaging
- Added comprehensive tests for all new checks

bd doctor now detects:
1. Old slash command patterns (/beads:*) and recommends bd prime hooks
2. Missing agent documentation and suggests creating it
3. MCP-only setups without hooks and shows token savings potential
4. Provides clear migration paths and benefits for all scenarios

Token efficiency messaging:
- MCP mode: ~50 tokens vs ~10.5k for full scan (99% reduction)
- CLI mode: ~1-2k tokens with automatic context recovery
- Hooks auto-refresh context on SessionStart and PreCompact

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 19:36:48 -05:00
Steve Yegge
7806937b0a Add bd doctor --fix flag to automatically repair issues (bd-ykd9)
Implements automatic fix capability for bd doctor with user confirmation
and security hardening.

Features:
- Organizes fix implementations under doctor/fix/ directory structure
- Shows all fixable issues and prompts for confirmation (Y/n) before applying
- Provides clear output about what was fixed and any errors encountered
- Re-runs diagnostics after fixes to show updated state
- Each fix is idempotent and safe to run multiple times

Automatic fixes implemented:
- Git hooks (runs bd hooks install)
- Daemon health issues (runs bd daemons killall)
- DB-JSONL sync problems (runs bd sync --import-only)
- File permissions (fixes .beads/ and database permissions)
- Database version mismatches (runs bd migrate)
- Schema compatibility issues (runs bd migrate)
- Gitignore updates (writes canonical template)

Security improvements:
- Prevents command injection by using os.Executable() instead of PATH lookup
- Prevents path traversal attacks with workspace validation
- Fixes race conditions by using cmd.Dir instead of os.Chdir()
- Corrects file permission logic (proper bit masking)
- Validates all operations run in beads workspaces only

Files changed:
- cmd/bd/doctor.go: Enhanced applyFixes() with confirmation and better UX
- cmd/bd/doctor/gitignore.go: Fixed permissions (0600 → 0644)
- cmd/bd/doctor/fix/common.go: Security helpers (getBdBinary, validateBeadsWorkspace)
- cmd/bd/doctor/fix/hooks.go: Git hooks fix
- cmd/bd/doctor/fix/daemon.go: Daemon health fix
- cmd/bd/doctor/fix/sync.go: DB-JSONL sync fix
- cmd/bd/doctor/fix/permissions.go: File permissions fix
- cmd/bd/doctor/fix/migrate.go: Database migration fixes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 19:33:12 -05:00
Codex Agent
bf9b2c83fb Annotate gosec-safe file accesses 2025-11-17 10:12:46 -07:00
Codex Agent
7b63b5a30b Fix CI regressions and stabilize tests 2025-11-17 10:06:35 -07:00
Ryan
690c73fc31 Performance Improvements (#319)
* feat: add performance testing framework foundation

Implements foundation for comprehensive performance testing and user
diagnostics for beads databases at 10K-20K scale.

Components added:
- Fixture generator (internal/testutil/fixtures/) for realistic test data
  * LargeSQLite/XLargeSQLite: 10K/20K issues with epic hierarchies
  * LargeFromJSONL/XLargeFromJSONL: test JSONL import path
  * Realistic cross-linked dependencies, labels, assignees
  * Reproducible with seeded RNG

- User diagnostics (bd doctor --perf) for field performance data
  * Collects platform info (OS, arch, Go/SQLite versions)
  * Measures key operation timings (ready, list, show, search)
  * Generates CPU profiles for bug reports
  * Clean separation in cmd/bd/doctor/perf.go

Test data characteristics:
- 10% epics, 30% features, 60% tasks
- 4-level hierarchies (Epic → Feature → Task → Subtask)
- 20% cross-epic blocking dependencies
- Realistic status/priority/label distributions

Supports bd-l954 (Performance Testing Framework epic)
Closes bd-6ed8, bd-q59i

* perf: optimize GetReadyWork with compound index (20x speedup)

Add compound index on dependencies(depends_on_id, type, issue_id) to
eliminate performance bottleneck in GetReadyWork recursive CTE query.

Performance improvements (10K issue database):
- GetReadyWork: 752ms → 36.6ms (20.5x faster)
- Target: <50ms ✓ ACHIEVED
- 20K database: ~1500ms → 79.4ms (19x faster)

Benchmark infrastructure enhancements:
- Add dataset caching in /tmp/beads-bench-cache/ to avoid regenerating
  10K-20K issues on every benchmark run (first run: ~2min, subsequent: <5s)
- Add progress logging during fixture generation (shows 10%, 20%... completion)
- Add database size logging (17.5 MB for 10K, 35.1 MB for 20K)
- Document rationale for only benchmarking large datasets (>10K issues)
- Add CPU/trace profiling with --profile flag for performance debugging

Schema changes:
- internal/storage/sqlite/schema.go: Add idx_dependencies_depends_on_type_issue

New files:
- internal/storage/sqlite/bench_helpers_test.go: Reusable benchmark setup with caching
- internal/storage/sqlite/sqlite_bench_test.go: Comprehensive benchmarks for critical operations
- Makefile: Convenient benchmark execution (make bench-quick, make bench)

Related:
- Resolves bd-5qim (optimize GetReadyWork performance)
- Builds on bd-6ed8 (fixture generator), bd-q59i (bd doctor --perf)

* perf: add WASM compilation cache to eliminate cold-start overhead

Configure wazero compilation cache for ncruces/go-sqlite3 to avoid
~220ms JIT compilation on every process start.

Cache configuration:
- Location: ~/.cache/beads/wasm/ (platform-specific via os.UserCacheDir)
- Automatic version management: wazero keys entries by its version
- Fallback: in-memory cache if directory creation fails
- No cleanup needed: old versions are harmless (~5-10MB each)

Performance impact:
- First run: ~220ms (populate cache)
- Subsequent runs: ~20ms (load from cache)
- Savings: ~200ms per cold start

Cache invalidation:
- Automatic when wazero version changes (upgrades use new cache dir)
- Manual cleanup: rm -rf ~/.cache/beads/wasm/ (safe to delete anytime)

This complements daemon mode:
- Daemon mode: eliminates startup cost by keeping process alive
- WASM cache: reduces startup cost for one-off commands or daemon restarts

Changes:
- internal/storage/sqlite/sqlite.go: Add init() with cache setup

* refactor: improve maintainability of performance testing code

Extract common patterns and eliminate duplication across benchmarks, fixture generation, and performance diagnostics. Replace magic numbers with explicit configuration to improve readability and make it easier to tune test parameters.

* docs: clarify profiling behavior and add missing documentation

Add explanatory comments for profiling setup to clarify why --profile
forces direct mode (captures actual database operations instead of RPC
overhead) and document the stopCPUProfile function's role in flushing
profile data to disk. Also fix gosec G104 linter warning by explicitly
ignoring Close() error during cleanup.

* fix: prevent bench-quick from running indefinitely

Added //go:build bench tags and skipped timeout-prone benchmarks to
prevent make bench-quick from running for hours.

Changes:
- Add //go:build bench tag to cycle_bench_test.go and compact_bench_test.go
- Skip Dense graph benchmarks (documented to timeout >120s)
- Fix compact benchmark prefix: bd- → bd (validation expects prefix without trailing dash)

Before: make bench-quick ran for 3.5+ hours (12,699s) before manual interrupt
After: make bench-quick completes in ~25 seconds

The Dense graph benchmarks are known to timeout and represent rare edge
cases that don't need optimization for typical workflows.
2025-11-15 12:46:13 -08:00
Steve Yegge
f4a2f87aff Fix #274: Add automatic .beads/.gitignore upgrade (#300)
* Fix #274: Add automatic .beads/.gitignore upgrade

Implements three mechanisms to ensure users get updated gitignore:

1. bd doctor --fix: Manually upgrade gitignore
2. Daemon auto-upgrade: Upgrades on startup if outdated
3. bd init idempotent: Safe to re-run, always updates gitignore

The gitignore template now lives in cmd/bd/doctor/gitignore.go
for consistent updates across all three mechanisms.

Fixes: #274

* Remove test binary

Amp-Thread-ID: https://ampcode.com/threads/T-7042cfcc-ac97-43d7-a40f-3fa1bb4e1c2b
Co-authored-by: Amp <amp@ampcode.com>

* Fix critical issues: remove merge artifact and apply gitignore template

- Remove .beads/beads.left.jsonl (merge artifact that shouldn't be committed)
- Apply new gitignore template to .beads/.gitignore (was missing patterns)

Amp-Thread-ID: https://ampcode.com/threads/T-7042cfcc-ac97-43d7-a40f-3fa1bb4e1c2b
Co-authored-by: Amp <amp@ampcode.com>

* bd sync: 2025-11-12 11:09:30

* Retrigger CI

Amp-Thread-ID: https://ampcode.com/threads/T-8d532264-6d5e-4b68-88e9-e4511851b64a
Co-authored-by: Amp <amp@ampcode.com>

* Fix duplicate DoctorCheck type definition

* Trigger CI after fixing type conflict

Amp-Thread-ID: https://ampcode.com/threads/T-8d532264-6d5e-4b68-88e9-e4511851b64a
Co-authored-by: Amp <amp@ampcode.com>

---------

Co-authored-by: Amp <amp@ampcode.com>
2025-11-12 12:46:27 -08:00
Ryan
f7e80dd80c feat: add context optimization features for AI agents (#297)
* feat: add bd prime and setup commands for AI agent integration

This commit consolidates context optimization features for AI agents:

## New Commands

**bd prime** - AI-optimized workflow context injection
- Outputs ~1-2k tokens of workflow context
- Context-aware: adapts to MCP vs CLI mode
- MCP mode: minimal reminders (~500 tokens)
- CLI mode: full command reference (~1-2k tokens)
- Warns against TodoWrite tool and markdown TODOs
- Designed for SessionStart/PreCompact hooks

**bd setup claude** - Claude Code integration installer
- Installs hooks via JSON configuration (not file scripts)
- Supports --project for project-only installation
- Supports --check to verify installation
- Supports --remove to uninstall hooks
- Idempotent (safe to run multiple times)
- Merges with existing settings

**bd setup cursor** - Cursor IDE integration installer
- Creates .cursor/rules/beads.mdc with workflow rules
- Simplified implementation (just overwrites file)

## bd doctor Enhancements

- New: CheckClaude() verifies Claude Code integration
- Detects plugin, MCP server, and hooks installation
- Provides actionable fix suggestions
- Extracted legacy pattern detection to doctor/legacy.go
- Detects JSONL-only mode and warns about legacy issues.jsonl

## Core Improvements

- FindBeadsDir() utility for cross-platform .beads/ discovery
- Works in JSONL-only mode (no database required)
- Sorted noDbCommands alphabetically (one per line for easy diffs)

## Testing

- Unit tests for setup command hook manipulation
- Tests for idempotency, adding/removing hooks
- All tests passing

## Documentation

- cmd/bd/doctor/claude.md - Documents why beads doesn't use Claude Skills
- commands/prime.md - Slash command for bd prime
- Fixed G304 gosec warnings with nosec comments

## Token Efficiency

The bd prime approach reduces AI context usage dramatically:
- MCP mode: ~500 tokens (vs ~10.5k for full MCP tool scan)
- CLI mode: ~1-2k tokens
- 80-99% reduction in standing context overhead

* fix: resolve linting errors in setup utils and remove obsolete test

- Add error check for tmpFile.Close() in setup/utils.go to fix golangci-lint G104
- Remove TestCheckMultipleJSONLFiles test that referenced deleted checkMultipleJSONLFiles function

Fixes golangci-lint errcheck violations introduced in the bd prime/setup feature.
2025-11-12 10:48:36 -08:00