Commit Graph

5485 Commits

Author SHA1 Message Date
aleiby
1472d115f1 fix(mol): find molecules attached to hooked issues (bd-o0mp) (#1302)
When no steps are in_progress, bd mol current now checks for molecules
bonded to hooked issues via blocks dependencies. This fixes the case
where a molecule is attached to an agent's hook but no steps have been
claimed yet.

The fix adds findHookedMolecules() as a fallback after findInProgressMolecules()
returns empty. It queries for hooked issues assigned to the agent and checks
for blocks dependencies pointing to molecules (epics or template-labeled issues).

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 17:11:44 -08:00
aleiby
702f686fc0 feat(update): add --append-notes flag (#1304)
* feat(update): add --append-notes flag (bd-b5qu)

Add --append-notes flag that appends to existing notes with a newline
separator instead of overwriting. This prevents data loss in workflows
where multiple steps need to add info to notes (e.g., tackle workflows).

- Errors if both --notes and --append-notes specified
- Handles both daemon and direct mode paths
- Combines existing notes + newline + new content

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

* test(update): add tests for --append-notes flag

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 17:11:25 -08:00
Rui Chen
66d1e63158 feat: update to use core tap for beads installation (#1261)
* feat: update to use core tap for beads installation

Signed-off-by: Rui Chen <rui@chenrui.dev>

* remove custom tap related code and refs

Signed-off-by: Rui Chen <rui@chenrui.dev>

---------

Signed-off-by: Rui Chen <rui@chenrui.dev>
2026-01-24 17:11:21 -08:00
aleiby
44485bcf35 fix(rpc): populate dependencies in handleList response (#1300)
The daemon server's handleList was returning dependency counts but not
the actual dependency records. This complements PR #1296 which fixed
the direct CLI path.

Code paths now fixed:
- Direct (--no-daemon): cmd/bd/list.go (PR #1296)
- Daemon (default): internal/rpc/server_issues_epics.go (this PR)

Fixes bd-d240

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 17:11:00 -08:00
Ian Bull
8619d08db9 doc: create an ARTICLES.md for Articles & Tutorials about Beads (#1306)
Creates an ARTICLES.md with both official and community articles and
tutorials about Beads. This will help others get find resources and
get started.
2026-01-24 17:10:54 -08:00
Salman Chishti
0cf19d438a Upgrade GitHub Actions for Node 24 compatibility (#1307)
Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>
2026-01-24 17:10:36 -08:00
Salman Chishti
369c5a3bc0 Upgrade GitHub Actions to latest versions (#1308)
Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>
2026-01-24 17:10:31 -08:00
Eduardo Koloma Jr
8fab565f35 fix(gate): ensure add-waiter command functions (#1265)
* fix(gate): use GateWait RPC for add-waiter command

bd gate add-waiter was calling Update RPC which rejects waiters
field (not in allowedUpdateFields). Changed to use existing GateWait
RPC that handles waiters correctly.

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

* fix(storage): allow waiters field in UpdateIssue

Add waiters to allowedUpdateFields whitelist and handle JSON
serialization for the array field. This enables bd gate add-waiter
to work in direct mode (--no-daemon).

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

* fix(storage/dolt): allow waiters field in UpdateIssue

Mirror the SQLite fix: add waiters to allowed fields and handle JSON
serialization for the array field.

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

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 17:10:12 -08:00
Peter Chanthamynavong
dbd505656d fix(daemon): add sync-branch guard to daemon code paths (#1271)
* fix(daemon): skip export when sync-branch matches current

Prevent redundant export operations by checking if the daemon's sync
branch matches the current active branch.

Previously, the daemon would attempt to perform an export even when
already on the target branch. This logic now skips the export step in
such cases to avoid unnecessary overhead and potential conflicts.
Includes a new integration test to verify the guard logic.

* fix(daemon): prevent sync on guarded branches

Add checks to verify if a branch is guarded before performing automated
sync cycles, auto-imports, or branch-specific commit and pull operations.
This prevents the daemon from modifying protected branches or running
synchronization tasks where they are restricted.

Includes comprehensive integration tests to verify the guard logic
during sync-branch operations.

* fix(daemon): warn on sync branch misconfiguration at startup

The daemon now checks for sync branch name conflicts during its startup
loop. This provides early feedback if the sync branch is configured
in a way that might conflict with existing branches or other settings.

The warnIfSyncBranchMisconfigured function performs the validation
and logs a warning to the console. Integration tests verify that
the daemon correctly identifies and reports these misconfigurations
at initialization.
2026-01-24 17:10:08 -08:00
Peter Chanthamynavong
b7d650bd8e fix(init): respect BEADS_DIR environment variable (#1273)
* fix(sync): read sync.mode from yaml first, then database

bd config set sync.mode writes to config.yaml (because sync.* is a
yaml-only prefix), but GetSyncMode() only read from the database.

This caused dolt-native mode to be ignored - JSONL export still
happened because the database had no sync.mode value.

Now GetSyncMode() checks config.yaml first (via config.GetSyncMode()),
falling back to database for backward compatibility.

Fixes: oss-5ca279

* fix(init): respect BEADS_DIR environment variable

Problem:
- `bd init` ignored BEADS_DIR when checking for existing data
- `bd init` created database at CWD/.beads instead of BEADS_DIR
- Contributor wizard used ~/.beads-planning as default, ignoring BEADS_DIR

Solution:
- Add BEADS_DIR check in checkExistingBeadsData() (matches FindBeadsDir pattern)
- Compute beadsDirForInit early, before initDBPath determination
- Use BEADS_DIR as default in contributor wizard when set
- Preserve precedence: --db > BEADS_DB > BEADS_DIR > default

Impact:
- Users with BEADS_DIR set now get consistent behavior across all bd commands
- ACF-style fork tracking (external .beads directory) now works correctly

Fixes: steveyegge/beads#???

* fix(doctor): respect BEADS_DIR environment variable

Also updates documentation to reflect BEADS_DIR support in init and doctor.

Changes:
- doctor.go: Check BEADS_DIR before falling back to CWD
- doctor_test.go: Add tests for BEADS_DIR path resolution
- WORKTREES.md: Document simplified BEADS_DIR+init workflow
- CONTRIBUTOR_NAMESPACE_ISOLATION.md: Note init/doctor BEADS_DIR support

* test(init): add BEADS_DB > BEADS_DIR precedence test

Verifies that BEADS_DB env var takes precedence over BEADS_DIR
when both are set, ensuring the documented precedence order:
--db > BEADS_DB > BEADS_DIR > default

* chore: fill in GH#1277 placeholder in sync_mode comment
2026-01-24 17:10:05 -08:00
Scott Nixon
810192157c fix(export): populate export_hashes after successful export (GH#1278) (#1286)
Child issues created with --parent were missing from export_hashes table,
which affects integrity tracking and future incremental export features.

This fix ensures SetExportHash() is called for all exported issues:
- Updated ExportResult to include IssueContentHashes map
- Updated finalizeExport() to call SetExportHash() for each exported issue
- Updated exportToJSONLDeferred() to collect content hashes during export
- Updated performIncrementalExport() to collect content hashes for dirty issues
- Updated exportToJSONLWithStore() to call SetExportHash() after export
- Updated daemon's handleExport() to call SetExportHash() after export

Added test TestExportPopulatesExportHashes to verify the fix works for
both regular and hierarchical (child) issue IDs.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 17:10:02 -08:00
aleiby
fde40a79cf fix(importer): use transaction for handleRename in upsertIssuesTx (#1287)
The handleRename function was being called with the raw storage.Storage
interface inside upsertIssuesTx, which runs within a transaction. When
handleRename called store.DeleteIssue() or store.CreateIssue(), these
methods attempted to start new transactions via withTx/BEGIN IMMEDIATE,
causing a deadlock since SQLite cannot nest BEGIN IMMEDIATE transactions.

This fix:
- Adds handleRenameTx that accepts storage.Transaction and uses tx methods
- Updates the call site in upsertIssuesTx to use handleRenameTx(ctx, tx, ...)

The non-transactional upsertIssues continues to use handleRename for
backends that don't support transactions.

Fixes nested transaction deadlock during bd sync when issue renames occur.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 17:09:54 -08:00
Ryan
c952e25499 fix(prime): make beads default, avoid TodoWrite/TaskCreate (#1289)
- Make beads the DEFAULT for ALL task tracking
- Advise avoiding TodoWrite, TaskCreate, and markdown files for task tracking
- Add workflow guidance: create beads issue BEFORE writing code, mark in_progress when starting
2026-01-24 17:09:51 -08:00
aleiby
e051a31f5c fix(bd): separate parent-child deps from blocking deps in bd show (#1293)
Previously, `bd show` displayed all dependencies under "DEPENDS ON"
regardless of their type. This was confusing because parent-child
relationships (used for molecule/step hierarchy) appeared as if they
were blocking dependencies.

This fix:
- Groups dependencies by type in both daemon and non-daemon modes
- Shows parent-child deps under "PARENT" heading
- Shows blocking deps under "DEPENDS ON" heading
- Shows related deps under "RELATED" heading
- Shows discovered-from deps under "DISCOVERED FROM" heading

The fix applies the same filtering pattern already used for Dependents
(which correctly grouped CHILDREN, BLOCKS, RELATED, DISCOVERED) to the
Dependencies section.

Fixes: bd-69d7

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 17:09:48 -08:00
aleiby
dedde444cc fix(list): populate dependencies field in JSON output (bd-tjxh) (#1296)
Previously, `bd list --json` only included dependency_count and
dependent_count but not the actual dependency records. This broke
callers like `gt hook --json` that need to know what each issue
depends on to determine ready steps.

Now populates issue.Dependencies using GetAllDependencyRecords,
matching the behavior of `bd show --json`.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 17:09:45 -08:00
beads/crew/emma
e82f5136c1 fix(dolt): proper server mode support for routing and storage
- FindDatabasePath now handles Dolt server mode (no local dir required)
- main.go uses NewFromConfigWithOptions for Dolt to read server settings
- Routing uses factory via callback to respect backend configuration
- Handle Dolt "database exists" error (error 1007) gracefully

Previously, Dolt server mode failed because:
1. FindDatabasePath required a local directory to exist
2. main.go bypassed server mode config when creating Dolt storage
3. Routing always opened SQLite regardless of backend config

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 00:26:58 -08:00
mayor
13c362e67e feat(dolt): add server mode support for multi-client access
- Add dolt_mode, dolt_server_host, dolt_server_port fields to configfile.Config
- Add IsDoltServerMode(), GetDoltServerHost(), GetDoltServerPort() helpers
- Update factory to read server mode config and set Options accordingly
- Skip bootstrap in server mode (database lives on server)
- Pass Database name to dolt.Config for USE statement after connecting
- Disable dolt stats collection to avoid lock issues in embedded mode

This enables bd to connect to a running dolt sql-server (started via
'gt dolt start') instead of using embedded mode, allowing multi-client
access without file locking conflicts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 22:35:34 -08:00
beads/crew/emma
db0c6fbd3f fix(dolt): enable server mode for Gas Town integration (bd-nnjik)
- Skip Bootstrap when ServerMode is true (bootstrap is for embedded cold-start)
- Fix doltExists() to follow symlinks using os.Stat
- Pass database name from metadata.json to DoltStore config

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 22:24:55 -08:00
beads/crew/emma
a9c8c952f6 feat(show): add --id flag for IDs that look like flags
When an issue ID starts with dashes (e.g., gt--kzx), it can be
misinterpreted by Cobra's argument parser. The new --id flag allows
these IDs to be passed safely:

  bd show --id=gt--xyz

Multiple --id flags can be used, and they can be combined with
positional arguments.

Closes: bd-ix0ak

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 21:14:59 -08:00
beads/crew/emma
03400fbdbc style(doctor): use ui library for consistent --server output styling
Use ui.RenderPassIcon, ui.RenderWarnIcon, ui.RenderFailIcon, etc. for
consistent styling with the rest of the doctor command output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:38:20 -08:00
beads/crew/emma
3bcbca41fe fix(doctor): address code review issues in --server health checks
- Use parameterized query for INFORMATION_SCHEMA lookup (SQL injection)
- Add isValidIdentifier() to validate database names before USE statement
- Add password support via BEADS_DOLT_PASSWORD env var
- Remove unused variable declaration
- Add unit tests for identifier validation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:35:57 -08:00
beads/crew/emma
66d994264b feat(doctor): add --server flag for Dolt server mode health checks (bd-dolt.2.3)
Adds bd doctor --server to diagnose Dolt server mode connections:
- Server reachability (TCP connect to host:port)
- Dolt version check (verifies it is Dolt, not vanilla MySQL)
- Database exists and is accessible
- Schema compatible (can query beads tables)
- Connection pool health metrics

Supports --json for machine-readable output.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:29:12 -08:00
emma
433115725b fix(dolt): server mode should support multi-process access
Code review fix: In server mode, Dolt connects to an external sql-server
and should NOT be single-process-only. The whole point of server mode is
to enable multi-writer access.

Changes:
- Add Config.GetCapabilities() method that considers server mode
- Update daemon_guard, daemon_autostart, daemons, main to use GetCapabilities()
- Add TestGetCapabilities test
- Update init command help text to document server mode flags

The existing CapabilitiesForBackend(string) is kept for backward compatibility
but now includes a note to use Config.GetCapabilities() when the full config
is available.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:20:59 -08:00
emma
484cd9d5fd feat(dolt): add server mode config to metadata.json schema (bd-dolt.2.2)
Add Dolt server mode configuration to metadata.json for multi-writer access:

- Add DoltMode, DoltServerHost, DoltServerPort, DoltServerUser fields to Config
- Add helper methods with sensible defaults (127.0.0.1:3306, root user)
- Update factory to read server mode config and pass to dolt.Config
- Add --server, --server-host, --server-port, --server-user flags to bd init
- Validate that --server requires --backend dolt
- Add comprehensive tests for server mode configuration

Example metadata.json for server mode:
{
  "backend": "dolt",
  "database": "dolt",
  "dolt_mode": "server",
  "dolt_server_host": "192.168.1.100",
  "dolt_server_port": 3306,
  "dolt_server_user": "beads"
}

Password should be set via BEADS_DOLT_PASSWORD env var for security.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:01:46 -08:00
Steve Yegge
cec1356995 Merge pull request #1274 from aleiby/fix/1272-sqlite-retry-logic
fix(sqlite): add retry logic to transaction entry points
2026-01-22 21:05:37 -08:00
Steve Yegge
ab61b0956b feat(dolt): auto-commit write commands and set explicit commit authors (#1270)
Adds Dolt auto-commit functionality for write commands and sets explicit commit authors.

Includes fix for race condition in commandDidWrite (converted to atomic.Bool).

Original PR: #1267 by @coffeegoddd
Co-authored-by: Dustin Brown <dustin@dolthub.com>
2026-01-22 20:52:20 -08:00
ruby
35bd93b443 fix(sqlite): use BEGIN IMMEDIATE without retry loop (GH#1272)
The original PR added retry logic on top of BEGIN IMMEDIATE, but this caused
multi-minute hangs because:

1. Connection has busy_timeout=30s set via pragma
2. Each BEGIN IMMEDIATE waits up to 30s before returning SQLITE_BUSY
3. With 5 retries, worst case was 5 × 30s = 150+ seconds

The fix removes the retry loop since SQLite's busy_timeout already handles
retries internally. BEGIN IMMEDIATE still acquires the write lock early,
preventing deadlocks - we just let busy_timeout handle contention.

Root cause analysis in bd-9ldm.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 20:27:54 -08:00
ruby
718fc49776 fix(sqlite): add retry logic to transaction entry points (GH#1272)
Update withTx to use BEGIN IMMEDIATE with exponential backoff retry
on SQLITE_BUSY errors. This prevents "database is locked" failures
during concurrent operations (daemon + CLI, multi-agent workflows).

Changes:
- withTx now uses beginImmediateWithRetry (same pattern as RunInTransaction)
- Add dbExecutor interface for helper functions that work with both
  *sql.Tx and *sql.Conn
- Update all withTx callers to use *sql.Conn
- Refactor DeleteIssue to use withTx (fixes the specific error in auto-import)
- Update markIssuesDirtyTx to accept dbExecutor interface

Affected paths:
- MarkIssuesDirty, ClearDirtyIssuesByID (dirty.go)
- AddDependency, RemoveDependency (dependencies.go)
- executeLabelOperation (labels.go)
- AddComment (events.go)
- ApplyCompaction (compact.go)
- DeleteIssue (queries.go)

Note: Some direct BeginTx calls in queries.go (CloseIssue, UpdateIssue,
ReopenIssue, DeleteIssues) still use the old pattern and could be
refactored in a follow-up.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 18:30:48 -08:00
Steve Yegge
1f94b4b363 Newsletter generator: automated narrative summaries of releases
Introduces a newsletter generator script that creates narrative-style summaries.

Original PR: #1198 by @maphew
Closes #1197
2026-01-22 16:09:29 -08:00
aleiby
16749e6731 feat(bd): add --ephemeral and --persistent flags to bd update (#1263)
Adds --ephemeral and --persistent flags to bd update command.

Author: aleiby
2026-01-22 15:54:04 -08:00
groblegark
d037158624 fix(dolt): add lock retry and stale lock cleanup for operational reliability (#1260)
Adds operational improvements to the Dolt storage backend for increased
reliability in production environments with concurrent clients:

1. Lock retry with exponential backoff:
   - Add LockRetries and LockRetryDelay config options
   - Automatic retry on lock contention (default: 30 retries, ~6s window)
   - Exponential backoff starting at 100ms
   - Handles transient format version errors during manifest updates

2. Stale lock file cleanup:
   - Detect and clean orphaned .dolt/noms/LOCK files on startup
   - Prevents "database is read only" errors after crashes
   - Only removes empty locks older than 5 seconds

3. Transient error detection:
   - isTransientDoltError() detects retryable conditions
   - isLockError() identifies lock contention scenarios
   - cleanupStaleDoltLock() safely removes orphaned locks

These improvements address common issues in multi-process environments
where the Dolt embedded driver creates exclusive locks that persist
after unexpected termination.

Co-authored-by: upstream_syncer <matthew.baker@pihealth.ai>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 13:04:56 -08:00
justSteve
244b32b624 Fix PrefixOverride not respected in transaction storage layer (#1257)
When creating issues with explicit IDs via PrefixOverride (for cross-rig
creation), the storage layer was still validating against the local
config prefix, causing errors like:

  issue ID 'da-DataArchive-witness' does not match configured prefix 'hq'

The queries.go layer already handled PrefixOverride correctly, but
transaction.go did not. This fix adds the same PrefixOverride handling
to transaction.go:

1. Check if PrefixOverride is set
2. If set, use it as the prefix and skip validation (caller knows best)
3. Otherwise, fall back to existing IDPrefix/configPrefix logic

This allows gt doctor --fix to create agent beads for non-local rigs.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 13:04:52 -08:00
Aviv Kaplan
a597e013e0 Add beads-kanban-ui and beads-orchestration to Community Tools (#1255)
Web UIs:
- beads-kanban-ui: Visual Kanban board with git branch status tracking,
  epic/subtask management, design doc viewer, and activity timeline.

Claude Code Orchestration (new section):
- beads-orchestration: Multi-agent orchestration skill for Claude Code.
  Orchestrator investigates issues, manages tasks automatically, and
  delegates to tech-specific supervisors on isolated branches.
2026-01-22 13:04:48 -08:00
Cecil Ureña
040839a432 Add abacus to community tools (#1262) 2026-01-22 13:04:32 -08:00
emma
b5178e1895 fix(build): disable CGO for darwin builds in goreleaser
CGO cross-compilation for darwin from Linux CI runner fails without
osxcross. Since Dolt/federation features are now CGO-optional,
darwin builds can use CGO_ENABLED=0.

Users who need Dolt features on macOS can build from source with
CGO enabled.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 00:13:02 -08:00
emma
f91bbf3a03 fix(build): add CGO build constraints for Dolt-dependent files
The dolthub/gozstd dependency requires CGO. Several files were importing
the dolt package without build constraints, causing CI failures when
building with CGO_ENABLED=0 for Linux, FreeBSD, and Android.

Changes:
- Add //go:build cgo to federation.go and doctor/federation.go
- Create dolt_server_cgo.go/nocgo.go to abstract dolt.Server usage
- Create federation_nocgo.go with stub command explaining CGO requirement
- Create doctor/federation_nocgo.go with stub health checks
- Update daemon.go to use the dolt server abstraction

Federation and Dolt-specific features are unavailable in non-CGO builds.
Users are directed to pre-built binaries from GitHub releases.

Fixes v0.49.0 CI failure.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 00:01:37 -08:00
beads/crew/emma
9381190462 chore: Bump version to 0.49.0
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 23:42:07 -08:00
Roland Tritsch
5264d7aa60 fix(daemon): prevent zombie state after database file replacement (#1213)
fix(daemon): prevent zombie state after database file replacement

Adds checkFreshness() to health check paths (GetMetadata, GetConfig, GetAllConfig) and refactors reconnect() to validate new connection before closing old.

PR-URL: https://github.com/steveyegge/beads/pull/1213
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-21 22:46:59 -08:00
emma
78e1d6f229 chore: revert accidental .beads/ changes from #1231
The autoimport fix PR accidentally included local beads data changes.
This reverts the data files while keeping the code fixes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 21:51:07 -08:00
matt wilkie
1f8a6bf84e fix(autoimport): auto-correct deleted status to tombstone for JSONL compatibility (#1231)
* fix(autoimport): auto-correct deleted status to tombstone for JSONL compatibility (GH#1223)

This fix addresses the 'Stuck in sync diversion loop' issue where v0.48.0
encountered validation errors during JSONL import. The issue occurs when
JSONL files from older versions have issues with status='deleted' but the
current code expects status='tombstone' for deleted issues.

Changes:
- Add migration logic in parseJSONL to auto-correct 'deleted' status to 'tombstone'
- Ensure tombstones always have deleted_at timestamp set
- Add debug logging for both migration operations
- Prevents users from being stuck in sync divergence when upgrading

Fixes GH#1223: Stuck in sync diversion loop

* fix(autoimport): comprehensively fix corrupted deleted_at on non-tombstone issues (GH#1223)

The initial fix for GH#1223 only caught issues with status='deleted', but the real
data in the wild had issues with status='closed' (or other statuses) but also
had deleted_at set, which violates the validation rule.

Changes:
- Add broader migration logic: any non-tombstone issue with deleted_at should become tombstone
- Apply fix in all three JSONL parsing locations:
  - internal/autoimport/autoimport.go (parseJSONL for auto-import)
  - cmd/bd/import.go (import command)
  - cmd/bd/daemon_sync.go (daemon sync helper)
- Add comprehensive test case for corrupted closed issues with deleted_at
- Fixes the 'non-tombstone issues cannot have deleted_at timestamp' validation error
  during fresh bd init or import

Fixes GH#1223: Stuck in sync diversion loop

* Add merge driver comment to .gitattributes

* fix: properly clean up .gitattributes during bd admin reset

Fixes GH#1223 - Stuck in sync diversion loop

The removeGitattributesEntry() function was not properly cleaning up
beads-related entries from .gitattributes. It only removed lines
containing "merge=beads" but left behind:
- The comment line "# Use bd merge for beads JSONL files"
- Empty lines following removed entries

This caused .gitattributes to remain in a modified state after
bd admin reset --force, triggering sync divergence warning loop.

The fix now:
- Skips lines containing "merge=beads" (existing behavior)
- Skips beads-related comment lines
- Skips empty lines that follow removed beads entries
- Properly cleans up file so it's either empty (and gets deleted)
  or contains only non-beads content

---------

Co-authored-by: Amp <amp@example.com>
2026-01-21 21:50:38 -08:00
emma
1d3ca43620 chore: revert accidental .beads/issues.jsonl changes from #1243
The Codex setup feature PR accidentally included local beads data changes.
This reverts just the data file while keeping the code changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 21:50:18 -08:00
matt wilkie
ce622f5688 feat(setup): add Codex CLI setup recipe (#1243)
* Add Codex setup recipe

* Sync beads issues (bd-1zo)

---------

Co-authored-by: Amp <amp@example.com>
2026-01-21 21:50:01 -08:00
Steve Yegge
be306b6c66 fix(routing): auto-enable hydration and flush JSONL after routed create (#1251)
* fix(routing): auto-enable hydration and flush JSONL after routed create

Fixes split-brain bug where issues routed to different repos (via routing.mode=auto)
weren't visible in bd list because JSONL wasn't updated and hydration wasn't configured.

**Problem**: When routing.mode=auto routes issues to a separate repo (e.g., ~/.beads-planning),
those issues don't appear in 'bd list' because:
1. Target repo's JSONL isn't flushed after create
2. Multi-repo hydration (repos.additional) not configured automatically
3. No doctor warnings about the misconfiguration

**Changes**:

1. **Auto-flush JSONL after routed create** (cmd/bd/create.go)
   - After routing issue to target repo, immediately flush to JSONL
   - Tries target daemon's export RPC first (if daemon running)
   - Falls back to direct JSONL export if no daemon
   - Ensures hydration can read the new issue immediately

2. **Enable hydration in bd init --contributor** (cmd/bd/init_contributor.go)
   - Wizard now automatically adds planning repo to repos.additional
   - Users no longer need to manually run 'bd repo add'
   - Routed issues appear in bd list immediately after setup

3. **Add doctor check for hydrated repo daemons** (cmd/bd/doctor/daemon.go)
   - New CheckHydratedRepoDaemons() warns if daemons not running
   - Without daemons, JSONL becomes stale and hydration breaks
   - Suggests: cd <repo> && bd daemon start --local

4. **Add doctor check for routing+hydration mismatch** (cmd/bd/doctor/config_values.go)
   - Validates routing targets are in repos.additional
   - Catches split-brain configuration before users encounter it
   - Suggests: bd repo add <routing-target>

**Testing**: Builds successfully. Unit/integration tests pending.

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

* test(routing): add comprehensive tests for routing fixes

Add unit tests for all 4 routing/hydration fixes:

1. **create_routing_flush_test.go** - Test JSONL flush after routing
   - TestFlushRoutedRepo_DirectExport: Verify direct JSONL export
   - TestPerformAtomicExport: Test atomic file operations
   - TestFlushRoutedRepo_PathExpansion: Test path handling
   - TestRoutingWithHydrationIntegration: E2E routing+hydration test

2. **daemon_test.go** - Test hydrated repo daemon check
   - TestCheckHydratedRepoDaemons: Test with/without daemons running
   - Covers no repos, daemons running, daemons missing scenarios

3. **config_values_test.go** - Test routing+hydration validation
   - Test routing without hydration (should warn)
   - Test routing with correct hydration (should pass)
   - Test routing target not in hydration list (should warn)
   - Test maintainer="." edge case (should pass)

All tests follow existing patterns and use t.TempDir() for isolation.

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

* fix(tests): fix test failures and refine routing validation logic

Fixes test failures and improves validation accuracy:

1. **Fix routing+hydration validation** (config_values.go)
   - Exclude "." from hasRoutingTargets check (current repo doesn't need hydration)
   - Prevents false warnings when maintainer="." or contributor="."

2. **Fix test ID generation** (create_routing_flush_test.go)
   - Use auto-generated IDs instead of hard-coded "beads-test1"
   - Respects test store prefix configuration (test-)
   - Fixed json.NewDecoder usage (file handle, not os.Open result)

3. **Fix config validation tests** (config_values_test.go)
   - Create actual directories for routing paths to pass path validation
   - Tests now verify both routing+hydration AND path existence checks

4. **Fix daemon test expectations** (daemon_test.go)
   - When database unavailable, check returns "No additional repos" not error
   - This is correct behavior (graceful degradation)

All tests now pass:
- TestFlushRoutedRepo* (3 tests)
- TestPerformAtomicExport
- TestCheckHydratedRepoDaemons (3 subtests)
- TestCheckConfigValues routing tests (5 subtests)

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

* docs: clarify when git config beads.role maintainer is needed

Clarify that maintainer role config is only needed in edge case:
- Using GitHub HTTPS URL without credentials
- But you have write access (are a maintainer)

In most cases, beads auto-detects correctly via:
- SSH URLs (git@github.com:owner/repo.git)
- HTTPS with credentials

This prevents confusion - users with SSH or credential-based HTTPS
don't need to manually configure their role.

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

* fix(lint): address linter warnings in routing flush code

- Add missing sqlite import in daemon.go
- Fix unchecked client.Close() error return
- Fix unchecked tempFile.Close() error returns
- Mark unused parameters with _ prefix
- Add nolint:gosec for safe tempPath construction

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

---------

Co-authored-by: Roland Tritsch <roland@ailtir.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-21 21:22:04 -08:00
Steve Yegge
abd3feb761 fix(lint): check error return from provider.Close() (#1250)
Two lint errors introduced in recent commits:
- cmd/bd/doctor/git.go:896 - unchecked provider.Close()
- cmd/bd/orphans.go:120 - unchecked provider.Close()

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 21:11:33 -08:00
beads/crew/lydia
2cc96197c0 fix(dolt): parse timestamps from TEXT columns instead of direct time.Time scan
The Dolt storage was scanning created_at and updated_at directly into
time.Time fields, but SQLite stores these as TEXT strings. The Go SQLite
driver cannot automatically convert TEXT to time.Time.

Added parseTimeString() helper and fixed all scan functions:
- issues.go: scanIssue()
- dependencies.go: scanIssueRow()
- history.go: GetIssueHistory(), GetIssueAsOf()
- transaction.go: scanIssueTx()

Fixes bd-4dqmy

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 20:48:47 -08:00
Roland Tritsch
b63e7b8cf0 fix: auto-route create with explicit ID to correct database
When bd create --id=pq-xxx is called with an ID prefix that does not
match the current database, automatically route to the correct database
based on routes.jsonl configuration.

Changes:
- Add auto-routing logic before explicit --rig/--prefix handling
- Extract prefix from explicit ID and look it up in routes.jsonl
- If prefix matches a different rig, call createInRig automatically
- Update createInRig to accept explicitID parameter
- Pass explicitID through to issue creation

This fixes the prefix mismatch error when creating issues with
explicit IDs across rigs in multi-repo setups like Gas Town.

Example:
  cd ~/gt  # Root with hq- prefix
  bd create --id=pq-xxx --title="Test"
  # Now automatically routes to pgqueue/.beads/beads.db

Fixes: gt doctor --fix failing to create agent beads
Closes: #1188

Cherry-picked from Team-Ailtir/beads PR #1188 with build fix.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 20:44:45 -08:00
beads/crew/jane
2a56aab92c refactor(storage): move LocalProvider to internal/storage package
Move LocalProvider from cmd/bd/doctor/git.go to internal/storage/local_provider.go
where it belongs alongside StorageProvider. Both implement IssueProvider for
orphan detection - LocalProvider for direct SQLite access (--db flag),
StorageProvider for the global Storage interface.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 20:41:53 -08:00
beads/crew/collins
8da7f274d6 docs(design): add KV store design for Dolt team review
Inspired by PR #1164 from Piyush Jha (@Hackinet). Groups commands
under 'bd kv' subcommand for cleaner namespacing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 20:39:45 -08:00
Steve Yegge
9c3c21efe3 feat(cli): add 'view' as alias for 'show' command (#1249)
Users naturally try 'bd view <id>' when they want to see an issue.
Adding 'view' as an alias improves discoverability and UX.

Fixes bd-bpx35

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 19:58:49 -08:00
Peter Chanthamynavong
c11fa799be fix(orphans): honor --db flag for cross-repo orphan detection (#1200)
* fix(orphans): honor --db flag for cross-repo orphan detection

Problem:
- `bd orphans --db /path` ignored the --db flag entirely
- FindOrphanedIssues() hardcoded local .beads/ directory

Solution:
- Introduce IssueProvider interface for abstract issue lookup
- Add StorageProvider adapter wrapping Storage instances
- Update FindOrphanedIssues to accept provider instead of path
- Wire orphans command to create provider from --db flag

Closes: steveyegge/beads#1196

* test(orphans): add cross-repo and provider tests for --db flag fix

- Add TestFindOrphanedIssues_WithMockProvider (table-driven, UT-01 through UT-09)
- Add TestFindOrphanedIssues_CrossRepo (validates --db flag honored)
- Add TestFindOrphanedIssues_LocalProvider (backward compat RT-01)
- Add TestFindOrphanedIssues_ProviderError (error handling UT-07)
- Add TestFindOrphanedIssues_IntegrationCrossRepo (IT-02 full)
- Add TestLocalProvider_* unit tests

Coverage for IssueProvider interface and cross-repo orphan detection.

* docs: add bd orphans command to CLI reference

Document the orphan detection command including the cross-repo
workflow enabled by the --db flag fix in this PR.
2026-01-21 19:52:31 -08:00