Commit Graph

154 Commits

Author SHA1 Message Date
beads/crew/emma
4bc0b698a8 fix(staleness): skip auto-import when store is read-only (GH#1089)
Track whether the store was actually opened read-only (vs just requested)
since the fallback logic may change opts.ReadOnly. Use this to skip
auto-import in staleness checks - importing would fail anyway if the
store is read-only.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 18:25:50 -08:00
beads/crew/giles
97adc19cf5 fix(main): move noDbCommands check before expensive git operations
Fixes #1093: `bd version` was spawning 5-7 git subprocesses before
checking if it even needed database access.

Moved the noDbCommands early-return check to run BEFORE:
- ensureForkProtection() (spawns ~5 git commands)
- signalOrchestratorActivity() (spawns git config)

This eliminates unnecessary process churn for simple commands like
`bd version`, `bd help`, `bd completion`, etc.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 00:24:36 -08:00
Dmitry Verkhoturov
c1a9dda173 fix: allow shell completions to work without a database (#1118)
Add "__complete" to noDbCommands list so that Cobra's internal completion
command can run without requiring a beads database to be present.

Previously, running shell completions (e.g., `bd show <TAB>`) in a directory
without a .beads database would fail with "no beads database found" error.

Now completions return empty results gracefully when no database exists,
allowing basic command completion to work everywhere while issue ID
completion still requires a database.

Added integration test that verifies __complete command works without a database.
2026-01-15 19:22:55 -08:00
mayor
669ea40684 feat(storage): add --backend flag for Dolt backend selection
Phase 2 of Dolt integration - enables runtime backend selection:

- Add --backend flag to bd init (sqlite|dolt)
- Create storage factory for backend instantiation
- Update daemon and main.go to use factory with config detection
- Update database discovery to find Dolt backends via metadata.json
- Fix Dolt schema init to split statements for MySQL compatibility
- Add ReadOnly mode to skip schema init for read-only commands

Usage: bd init --backend dolt --prefix myproject

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 21:42:31 -08:00
Eugene Sukhodolin
a157def42d fix(export): remove export from read-only commands to fix dirty issue clearing (#1036)
The export command was incorrectly listed in readOnlyCommands, causing the SQLite database to be opened in read-only mode. This prevented export from clearing dirty issues and updating the JSONL file hash.
2026-01-12 16:40:01 -08:00
beads/crew/dave
ceb5769c75 feat: add owner field for human attribution in HOP CV chains
Add 'owner' field to Issue struct for tracking the human responsible
for the issue, distinct from 'created_by' which tracks the executor.
Owner is populated from git author email (GIT_AUTHOR_EMAIL or git
config user.email), per Decision 008 for CV accumulation.

Changes:
- Add Owner field to types.Issue with omitempty JSON tag
- Include Owner in content hash computation
- Add owner column migration (036_owner_column.go)
- Update all SQL queries to include owner field
- Add getOwner() helper using git author email fallback chain
- Populate owner in bd create command
- Add owner to RPC CreateArgs protocol

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

Executed-By: beads/crew/dave
Rig: beads
Role: crew
2026-01-10 19:28:08 -08:00
ohnotnow
bfae0e554c feat: add git user.name to actor fallback chain (#994)
- Insert git config user.name in fallback chain before final $USER default
- Consolidate duplicate actor resolution logic into single function
- Add BEADS_ACTOR as env var alias for MCP compatibility
- Add tests for actor resolution priority
- Update CONFIG.md with Actor Identity Resolution section

The new fallback order is:
  --actor flag > BD_ACTOR > BEADS_ACTOR > git user.name > $USER > "unknown"

Co-authored-by: Ohffs <ohffsnotnow@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 12:43:46 -08:00
Josh Nichols
5d1a8c2428 fix(autoimport): enable cold-start bootstrap for read-only commands (#977)
After devcontainer restart (cold-start), `bd --no-daemon show` failed to
find beads because:
1. Read-only commands skipped auto-import
2. Newly created DB had no issue_prefix set, causing import to fail

This fix enables seamless cold-start recovery by:
- Allowing read-only commands (show, list, etc.) to auto-bootstrap when
  JSONL exists but DB doesn't
- Setting needsBootstrap flag when falling back from read-only to
  read-write mode for missing DB
- Auto-detecting and setting issue_prefix from JSONL during auto-import
  when DB is uninitialized

Fixes: gt-b09

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-09 12:38:18 -08:00
Peter Chanthamynavong
28ff9fe991 fix(sync): canonicalize dbPath to fix filepath.Rel error (GH#959) (#960)
Problem:
- When dbPath is set to relative fallback (".beads/beads.db"),
  findJSONLPath() returns a relative path
- daemon_sync_branch.go calls filepath.Rel(absolutePath, relativePath)
  which fails with: "Rel: can't make .beads/issues.jsonl relative to ..."

Solution:
- Canonicalize dbPath at assignment in main.go:471 (source fix)
- Add defensive guard in findJSONLPath() (defense-in-depth)
- Use utils.CanonicalizePath() for OS-agnostic handling
  (symlinks, case normalization on macOS)

Testing:
- Add TestFindJSONLPath_RelativeDbPath (tracer bullet for bug)
- Add edge case tests for BEADS_JSONL and empty dbPath
- All sync mode tests pass including daemon E2E
2026-01-08 14:36:50 -08:00
fang
9cffdceb4e feat: add bd resolve-conflicts command for JSONL merge conflicts (bd-7e7ddffa.1)
Implements a new command to resolve git merge conflict markers in JSONL files.

Features:
- Mechanical mode (default): deterministic merge using updated_at timestamps
- Closed status wins over open
- Higher priority (lower number) wins
- Notes are concatenated when different
- Dependencies are unioned
- Dry-run mode to preview changes
- JSON output for agent integration
- Automatic backup creation before changes

The command defaults to resolving .beads/beads.jsonl but accepts any file path.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 21:41:29 -08:00
beads/crew/fang
6572654cdc fix: allow yaml-only config operations without database (GH#536)
Users could not run 'bd config set no-db true' without already having a
database, creating a chicken-and-egg problem. The PersistentPreRunE
would fail with 'no beads database found' before the config command
could even run.

The fix detects when a yaml-only config operation is being attempted
(config set/get with keys like no-db, no-daemon, sync.branch, etc.)
and allows it to proceed without requiring a database.

Before:
  $ bd config set no-db true
  Error: no beads database found

After:
  $ bd config set no-db true
  Set no-db = true (in config.yaml)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 00:02:20 -08:00
Steve Yegge
952944e295 Fix BD_ACTOR handling in direct mode paths
BUG: BD_ACTOR env var was only read in --no-db mode (lines 352-360)
and daemon RPC path. Normal direct mode and JSONL-only mode detection
paths fell back to $USER without checking BD_ACTOR.

Fix: Add explicit os.Getenv("BD_ACTOR") check in both:
- JSONL-only mode detection path (lines 393-402)
- Normal direct mode path (lines 440-450)

(gt-6r18e.2)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 16:51:14 -08:00
Steve Yegge
7d4e8e2db9 fix: read operations no longer modify database file (GH#804)
Add SQLite read-only mode for commands that only query data (list, ready,
show, stats, blocked, count, search, graph, duplicates, comments, export).

Changes:
- Add NewReadOnly() and NewReadOnlyWithTimeout() to sqlite package
  - Opens with mode=ro to prevent any file writes
  - Skips WAL pragma, schema init, and migrations
  - Skips WAL checkpoint on Close()
- Update main.go to detect read-only commands and use appropriate opener
- Skip auto-migrate, FlushManager, and auto-import for read-only commands
- Add tests verifying file mtime is unchanged after read operations

This fixes the issue where file watchers (like beads-ui) would go into
infinite loops because bd list/show/ready modified the database file.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 16:47:38 -08:00
Steve Yegge
f91d4fa975 Refactor: Introduce CommandContext to consolidate global variables (bd-qobn)
This addresses the code smell of 20+ global variables in main.go by:

1. Creating CommandContext struct in context.go that groups all runtime state:
   - Configuration (DBPath, Actor, JSONOutput, etc.)
   - Runtime state (Store, DaemonClient, HookRunner, etc.)
   - Auto-flush/import state
   - Version tracking
   - Profiling handles

2. Adding accessor functions (getStore, getActor, getDaemonClient, etc.)
   that provide backward-compatible access to the state while allowing
   gradual migration to CommandContext.

3. Updating direct_mode.go to demonstrate the migration pattern using
   accessor functions instead of direct global access.

4. Adding test isolation helpers (ensureCleanGlobalState, enableTestModeGlobals)
   to prevent test interference when multiple tests manipulate global state.

Benefits:
- Reduces global count from 20+ to 1 (cmdCtx)
- Better testability (can inject mock contexts)
- Clearer state ownership (all state in one place)
- Thread safety (mutexes grouped with the data they protect)

Note: Two pre-existing test failures (TestTrackBdVersion_*) are unrelated to
this change and fail both with and without these modifications.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 16:29:28 -08:00
Steve Yegge
087a9dd984 Show actor on status/pinned change events in activity feed
Added actor field to RPC client and set it before daemon requests.
This ensures status changes (like pinned events) show who performed
the action in bd activity output.

Changes:
- Added actor field to Client struct
- Added SetActor method to set actor for audit trail
- Modified ExecuteWithCwd to include actor in RPC requests
- Updated main.go to call SetActor after daemon connection

Fixes gt-1ydd9

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 15:56:52 -08:00
Steve Yegge
5f3cb0fdf3 refactor: remove Gas Town references from codebase
Replace Gas Town-specific terminology with generic orchestrator concepts:
- "Gas Town" → "orchestrator" or "multi-clone"
- Hardcoded ~/gt/ paths → GT_ROOT environment variable
- signalGasTownActivity → signalOrchestratorActivity
- GUPP → hook-based work assignment

Updated 21 files across CHANGELOG, cmd/bd/, internal/, docs/, scripts.

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

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

Executed-By: beads/crew/dave
Rig: beads
Role: crew
2025-12-30 14:13:32 -08:00
kraitsura
e5d1e721ed Add bd human command for focused help menu
bd has 70+ commands, which can be overwhelming for human users who just
want to track issues. The new `bd human` command displays a curated list
of ~15 essential commands organized by workflow:

- Working With Issues: create, list, show, update, close, reopen, comment
- Finding Work: ready, search, status, stats
- Dependencies: dep add/remove/tree, graph, blocked
- Setup & Sync: init, sync, doctor
- Getting Help: quickstart, help, --help

Also includes quick examples showing common workflows.

Changes:
- Add cmd/bd/human.go with curated help output
- Add "human" to noDbCommands list in main.go (no database needed)
2025-12-29 14:33:19 -08:00
Steve Yegge
1facf7fb83 feat: Add bd repair command for orphaned foreign key refs (hq-2cchm)
When the database has orphaned dependencies or labels, the migration
invariant check fails and prevents the database from opening. This
creates a chicken-and-egg problem where bd doctor --fix cannot run.

The new bd repair command:
- Opens SQLite directly, bypassing invariant checks
- Deletes orphaned dependencies (issue_id or depends_on_id not in issues)
- Deletes orphaned labels (issue_id not in issues)
- Runs WAL checkpoint to persist changes
- Supports --dry-run to preview what would be cleaned

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 12:43:22 -08:00
Steve Yegge
6c14fd2225 refactor: Split large cmd/bd files to meet 800-line limit (bd-xtf5)
Split 6 files exceeding 800 lines by extracting cohesive function groups:

- show.go (1592→578): extracted show_thread.go, close.go, edit.go, update.go
- doctor.go (1295→690): extracted doctor_fix.go, doctor_health.go, doctor_pollution.go
- sync.go (1201→749): extracted sync_git.go
- compact.go (1199→775): extracted compact_tombstone.go, compact_rpc.go
- linear.go (1190→641): extracted linear_sync.go, linear_conflict.go
- main.go (1148→800): extracted main_help.go, main_errors.go, main_daemon.go

All files now under 800-line acceptance criteria.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 18:43:09 -08:00
Steve Yegge
f46cc2e798 chore: remove issue ID references from comments and changelogs
Strip (bd-xxx), (gt-xxx) suffixes from code comments and changelog
entries. The descriptions remain meaningful without the ephemeral
issue IDs.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 10:05:16 -08:00
Steve Yegge
ad39aaeff5 feat: auto-bypass daemon for wisp operations (bd-ta4r)
Wisp operations (mol wisp *, mol burn, mol squash) and commands operating on
ephemeral issue IDs (bd-eph-*, gt-eph-*, eph-*) now auto-bypass the daemon.

Since wisps are ephemeral (Ephemeral=true) and never exported to JSONL,
the daemon cannot help with them anyway. This eliminates the need to manually
add --no-daemon for every wisp operation.

Changes:
- Add isWispOperation() helper to detect wisp commands and ephemeral IDs
- Add FallbackWispOperation constant for daemon status tracking
- Insert wisp detection in PersistentPreRunE daemon connection logic
- Update error messages in wisp.go, mol_burn.go, mol_squash.go
- Add comprehensive unit tests for isWispOperation()
2025-12-28 02:11:13 -08:00
Steve Yegge
1611f16751 refactor: remove unused bd pin/unpin/hook commands (bd-x0zl)
Analysis found these commands are dead code:
- gt never calls `bd pin` - uses `bd update --status=pinned` instead
- Beads.Pin() wrapper exists but is never called
- bd hook functionality duplicated by gt mol status
- Code comment says "pinned field is cosmetic for bd hook visibility"

Removed:
- cmd/bd/pin.go
- cmd/bd/unpin.go
- cmd/bd/hook.go

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 16:02:15 -08:00
Steve Yegge
c8b912cbe6 bd sync: 2025-12-27 15:56:42 2025-12-27 15:56:42 -08:00
Steve Yegge
05304e3ab1 Merge origin/main, fix test git init for modern git 2025-12-27 00:17:36 -08:00
Steve Yegge
daf539397e feat: add town-level activity signal for Gas Town daemon (bd-v8ku)
Writes activity.json to ~/gt/daemon/ when bd runs inside a Gas Town
workspace. This enables the daemon to detect bd usage and adjust its
polling frequency with exponential backoff.

Best-effort: silently skips if not in Gas Town or on any error.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 19:28:39 -08:00
Ryan Snodgrass
252de1cdba feat(daemon): add sync backoff and consolidate hints into tips
Daemon sync improvements:
- Adds exponential backoff on sync failures (30s → 1m → 2m → 5m → 10m → 30m cap)
- Tracks sync state in .beads/sync-state.json (NeedsManualSync, FailureCount, BackoffUntil)
- Resets backoff on daemon start and manual bd sync
- Adds sync-state.json to default .gitignore

Tips consolidation (following ox-cli pattern):
- Moves sync conflict hint from hints.go into tips.go
- Proactive health checks trump educational tips
- Uses InjectTip() with high priority (200) and 100% probability for urgent warnings
- Removes deprecated hints.go
2025-12-26 19:09:31 -05:00
Jordan Hubbard
1a4f06ef8c doctor: harden corruption repair and JSONL config
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2025-12-26 04:29:29 -04:00
Charles P. Cross
cdbca65ed4 feat(config): add override notification for config parameters (#731)
feat(config): add override notification for config parameters

Adds verbose logging when config values are overridden by flags/env vars.
2025-12-24 12:35:54 -08:00
Steve Yegge
92e6f4c079 refactor: remove legacy autoflush code paths (bd-xsl9)
Remove dual code paths in the autoflush system. FlushManager is now the
only code path for auto-flush operations.

Changes:
- Remove legacy globals: isDirty, needsFullExport, flushTimer
- Remove flushToJSONL() wrapper function (was backward-compat shim)
- Simplify markDirtyAndScheduleFlush/FullExport to just call FlushManager
- Update tests to use FlushManager or flushToJSONLWithState directly

FlushManager handles all flush state internally in its run() goroutine,
eliminating the need for global state. Sandbox mode and tests that do
not need flushing get a no-op when FlushManager is nil.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 01:56:19 -08:00
Ryan Snodgrass
cafc0b9dfb refactor(doctor): consolidate maintenance commands + improve daemon startup
Consolidate clean, repair-deps, validate into bd doctor:
- Add validation checks to doctor (merge artifacts, orphaned deps, duplicates, test pollution, git conflicts)
- Add auto-fix for merge artifacts and orphaned dependencies
- Delete obsolete command files: clean.go, repair_deps.go, validate.go
- Delete orphaned test files: clean_security_test.go, validate_test.go

Improve daemon startup performance:
- Add fast-fail detection when daemon crashed (check lock before retrying)
- Reduce graceful shutdown timeout from 5s to 1s
- Skip daemon connection for root command (just shows help)
- Extract shutdown timeout as constants (daemonShutdownTimeout, daemonShutdownPollInterval)

Other changes:
- Move rename-prefix command to Maintenance group in help
- Fix Makefile to inject git commit hash via ldflags

New files:
- cmd/bd/doctor/validation.go (5 check functions)
- cmd/bd/doctor/fix/validation.go (2 fix functions)
2025-12-22 20:21:30 -08:00
Ryan Snodgrass
fb1dff4f56 feat(ux): reorganize command groups and add Tufte-inspired help styling
- Add semantic coloring to help output (section headers, flags, types)
- Reorganize commands into clearer categories:
  - "Views & Reports" for readonly queries (ready, stats, blocked, etc.)
  - "Maintenance" for health/repair tasks (doctor, validate, migrate, etc.)
  - Merge "Issue Metadata" back into "Working With Issues"
- Highlight "doctor" as primary maintenance entry point with "(start here)"
- Create docs/UI_PHILOSOPHY.md documenting Tufte-inspired design principles
- Add guidance for PR to not include .beads/issues.jsonl
2025-12-20 12:57:16 -08:00
Steve Yegge
f6392efd07 feat(molecules): Add molecules.jsonl as separate catalog file for templates
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>
2025-12-20 09:27:41 -08:00
Steve Yegge
f7c746adb9 feat: auto-protect forks from committing upstream issue database
When bd detects it's running in a fork (origin != steveyegge/beads),
automatically add .beads/issues.jsonl to .git/info/exclude.

This prevents contributors from accidentally including issue database
changes in their PRs. The exclusion is:
- Per-clone (doesn't modify tracked files
- One-time setup (checks if already excluded)
- Silent (only logs in debug mode)

Maintainers (origin = steveyegge/beads) are not affected.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
EOF
)
2025-12-18 18:56:59 -08:00
Steve Yegge
46bfb43b8d feat: add graph links and hooks system (bd-kwro.2-5, bd-kwro.8)
- bd mail reply: reply to messages with thread linking via replies_to
- bd show --thread: display full conversation threads
- bd relate/unrelate: bidirectional relates_to links for knowledge graph
- bd duplicate --of: mark issues as duplicates with auto-close
- bd supersede --with: mark issues as superseded with auto-close
- Hooks system: on_create, on_update, on_close, on_message in .beads/hooks/
- RPC protocol: added Sender, Ephemeral, RepliesTo fields to CreateArgs/UpdateArgs

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 18:34:48 -08:00
Charles P. Cross
a69e94a958 Auto-disable daemon in git worktrees for safety (#567)
* feat: auto-disable daemon in git worktrees for safety

Implement worktree daemon compatibility as proposed in the analysis.
The daemon is now automatically disabled when running in a git worktree
unless sync-branch is configured.

Git worktrees share the same .beads directory, and the daemon commits
to whatever branch its working directory has checked out. This causes
commits to go to the wrong branch when using daemon in worktrees.

- Add shouldDisableDaemonForWorktree() helper that checks:
  1. If current directory is a git worktree (via git rev-parse)
  2. If sync-branch is configured (env var or config.yaml)
- Modify shouldAutoStartDaemon() to call the helper
- Modify daemon connection logic in main.go to skip connection
- Add FallbackWorktreeSafety constant for daemon status reporting
- Update warnWorktreeDaemon() to skip warning when sync-branch configured

- In worktree WITHOUT sync-branch: daemon auto-disabled, direct mode used
- In worktree WITH sync-branch: daemon enabled (commits go to dedicated branch)
- In regular repo: no change (daemon works as before)

- Added comprehensive unit tests for shouldDisableDaemonForWorktree()
- Added integration tests for shouldAutoStartDaemon() in worktree contexts
- Manual E2E testing verified correct behavior

- Updated WORKTREES.md with new automatic safety behavior
- Updated DAEMON.md with Git Worktrees section

* feat: check database config for sync-branch in worktree safety logic

Previously, the worktree daemon safety check only looked at:
- BEADS_SYNC_BRANCH environment variable
- sync-branch in config.yaml

This meant users who configured sync-branch via `bd config set sync-branch`
(which stores in the database) would still have daemon disabled in worktrees.

Now the check also reads sync.branch from the database config table,
making daemon work in worktrees when sync-branch is configured via any method.

Changes:
- Add IsConfiguredWithDB() function that checks env, config.yaml, AND database
- Add findBeadsDB() to locate database (worktree-aware via git-common-dir)
- Add getMainRepoRoot() helper using git rev-parse
- Add getConfigFromDB() for lightweight database reads
- Update shouldDisableDaemonForWorktree() to use IsConfiguredWithDB()
- Update warnWorktreeDaemon() to use IsConfiguredWithDB()
- Add test case for database config path

* refactor: use existing beads.FindDatabasePath() instead of duplicating code

Remove duplicate getMainRepoRoot() and findBeadsDB() functions from
syncbranch.go and use the existing beads.FindDatabasePath() which is
already worktree-aware.

Changes:
- Replace custom findBeadsDB() with beads.FindDatabasePath()
- Remove duplicate getMainRepoRoot() (git.GetMainRepoRoot() exists)
- Remove unused imports (exec, strings, filepath)
- Clean up debug logging in tests

---------

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-16 00:06:19 -08:00
Steve Yegge
6c84d36592 fix: bd onboard hangs on Windows (GH #531)
Added onboard and hooks commands to the noDbCommands list so they
skip database and daemon initialization. These commands don't need
database access - they just output documentation or manage git hooks.

On Windows, if no .beads directory exists, the PersistentPreRun
would attempt database discovery (including git worktree detection)
which could hang due to git command issues.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 18:09:34 -08:00
Steve Yegge
fc23dca7fb feat(cli): add --lock-timeout flag for SQLite busy_timeout control (#536)
Implements single-shot mode improvements for Windows and Docker scenarios:

- Add --lock-timeout global flag (default 30s, 0 = fail immediately)
- Add config file support: lock-timeout: 100ms
- Parameterize SQLite busy_timeout via NewWithTimeout() function
- In --sandbox mode: default lock-timeout to 100ms
- In --sandbox mode: skip FlushManager creation (no background goroutines)

This addresses bd.exe hanging on Windows and locking conflicts when
using beads across host + Docker containers.

Closes: bd-59er, bd-r4od, bd-dh8a

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 18:07:49 -08:00
Steve Yegge
5d71ca6356 fix: improve JSONL-only mode detection and error messages (GH #534)
- Add JSONL-only mode detection in ensureStoreActive() with context-aware
  error messages that suggest correct actions based on project state
- Improve error messages in main.go to detect JSONL presence and suggest
  appropriate solutions (bd init, --no-db flag, or config.yaml setting)
- Update documentation to use issues.jsonl as canonical filename:
  - AGENT_INSTRUCTIONS.md, README.md, resolve-beads-conflict.md
  - docs/GIT_INTEGRATION.md
- Update hook template comments to clarify issues.jsonl is canonical
  while maintaining backward compatibility for beads.jsonl

Fixes #534

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-13 12:50:33 -08: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
28a661a320 feat: add --readonly flag for worker sandboxes (gt-ymo)
Add a --readonly flag that blocks all write operations, allowing workers
to read beads state without modifying it. Workers can use:
- bd show, bd list, bd ready (read operations)

Workers cannot use:
- bd create, bd update, bd close, bd sync, etc. (write operations)

The flag can be set via:
- --readonly flag on command line
- BD_READONLY=true environment variable
- readonly: true in config file

This enables swarm workers to see their assigned work from a static
snapshot of the beads database without accidentally modifying it.

Commands protected by readonly mode:
- create, update, close, delete, edit
- sync, import, reopen
- comment add, dep add/remove, label add/remove
- repair-deps, compact, migrate, migrate-hash-ids, migrate-issues
- rename-prefix, validate --fix-all, duplicates --auto-merge
- epic close-eligible, jira sync

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 23:44:22 -08:00
Steve Yegge
8ef3d81108 fix(sync): prevent final flush after sync.branch restore
When sync.branch is configured, the sync command:
1. Exports changes to JSONL
2. Commits to sync branch via worktree
3. Pulls from sync branch
4. Restores .beads/ from HEAD to keep working directory clean

But PersistentPostRun's flushManager.Shutdown() was re-exporting to JSONL,
undoing the restore and leaving modified files.

Fix: Set skipFinalFlush flag when sync.branch mode completes successfully.
This prevents the final export in PersistentPostRun.

Also: Skip push to main branch when sync.branch is configured - all
pushes should go through the sync branch worktree.
2025-12-01 20:51:54 -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
ef50e80c2d Resolve merge conflicts in issues.jsonl and main.go
- issues.jsonl: Keep closed status for bd-5kj (already resolved)
- main.go: Clean up JSONL-only mode detection, include BD_ACTOR env check

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 13:32:51 -08:00
Steve Yegge
a4e0f9dbc8 fix(no-db): auto-detect JSONL-only mode when config has no-db:true (bd-5kj)
When .beads exists with issues.jsonl but no SQLite database, and config.yaml
has no-db: true, automatically enable JSONL-only mode instead of failing
with 'no beads database found'. Also improved error message to mention
--no-db option.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 23:36:11 -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
8b8a662acb Fix fresh clone UX with friendly error messages (bd-dmb)
When opening a database that exists but is missing issue_prefix config
(typical in fresh clone scenarios), show a helpful error message instead
of cryptic migration invariant errors.

The new message:
- Explains the database needs initialization
- Detects if a JSONL file exists and shows the issue count
- Suggests the exact command to run: bd import -i <path>
- Falls back to suggesting bd init --prefix if no JSONL exists

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 22:40:57 -08:00
Steve Yegge
650dcd42f6 fix(tests): resolve short test performance regression (bd-0v4)
Short tests were timing out after 13+ minutes due to:

1. TestZFCSkipsExportAfterImport spawning subprocess that tried to
   auto-start daemon - now skipped in short mode

2. TestVersionFlag taking 5+ seconds because --version flag did not
   skip PersistentPreRun daemon startup - added early return

3. TestGetVersionsSince* had hardcoded version expectations that
   became stale - made tests dynamic using versionChanges array

Short tests now complete in ~8 seconds instead of timing out.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 01:36:57 -08:00
Steve Yegge
273a4d1cfc feat: Complete command set standardization (bd-au0)
Epic bd-au0: Command Set Standardization & Flag Consistency

Completed all 10 child issues:

P0 tasks:
- Standardize --dry-run flag across all commands (bd-au0.1)
- Add label operations to bd update (bd-au0.2)
- Fix --title vs --title-contains redundancy (bd-au0.3)
- Standardize priority flag parsing (bd-au0.4)

P1 tasks:
- Add date/priority filters to bd search (bd-au0.5)
- Add comprehensive filters to bd export (bd-au0.6)
- Audit and standardize JSON output (bd-au0.7)

P2 tasks:
- Improve clean vs cleanup documentation (bd-au0.8)
- Document rarely-used commands (bd-au0.9)

P3 tasks:
- Add global verbosity flags --verbose/-v and --quiet/-q (bd-au0.10)

Key changes:
- export.go: Added filters (assignee, type, labels, priority, dates)
- main.go: Added --verbose/-v and --quiet/-q global flags
- debug.go: Added SetVerbose/SetQuiet and PrintNormal helpers
- clean.go/cleanup.go: Improved documentation with cross-references
- detect_pollution.go: Added use cases and warnings
- migrate_hash_ids.go: Marked as legacy command
- rename_prefix.go: Added use cases documentation

All success criteria met: flags standardized, feature parity achieved,
naming clarified, JSON output consistent.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 20:33:31 -08:00
Steve Yegge
4a9d6e6dd7 fix: Code review fixes for auto-migration (bd-jgxi)
Critical fixes from code review:

1. **Moved auto-migration to correct location**
   - Now runs AFTER daemon check but BEFORE opening database
   - Prevents: database opened twice, conflicts with daemon
   - Was: Running too early, before knowing if daemon exists

2. **Fixed context cancellation issue**
   - Check if rootCtx is canceled before using it
   - Fall back to Background() if canceled
   - Fixes: "context canceled" errors in test suite

3. **Updated function signature**
   - Takes dbPath as parameter (no longer searches for it)
   - Simpler, more explicit, easier to test
   - Caller already has dbPath, no need to re-discover

4. **Enhanced test reliability**
   - Save/restore all global state
   - Add debug logging for troubleshooting
   - Verify preconditions before migration

Changes:
- cmd/bd/main.go: Move autoMigrateOnVersionBump call to correct location
- cmd/bd/version_tracking.go: Fix context handling, update signature
- cmd/bd/version_tracking_test.go: Improve test reliability

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 18:28:01 -08:00