Commit Graph

1143 Commits

Author SHA1 Message Date
Steve Yegge
ee04b1ea96 feat: add dynamic molecule bonding with --ref flag (bd-xo1o.1)
Implements the Christmas Ornament pattern for patrol molecules:
- Add CloneOptions struct with ParentID and ChildRef for dynamic bonding
- Add generateBondedID() to create custom IDs like "patrol-x7k.arm-ace"
- Add --ref flag to `bd mol bond` for custom child references
- Variable substitution in childRef (e.g., "arm-{{polecat_name}}")

This enables:
  bd mol bond mol-polecat-arm bd-patrol --ref arm-{{name}} --var name=ace
  # Creates: bd-patrol.arm-ace, bd-patrol.arm-ace.capture, etc.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 03:38:38 -08:00
Steve Yegge
be520d90fe feat: add bd activity command for real-time state feed (bd-xo1o.3)
Implements activity feed for watching molecule/issue state changes:
- bd activity: show last 100 events
- bd activity --follow: real-time streaming
- bd activity --mol <id>: filter by molecule prefix
- bd activity --since 5m: time-based filtering
- bd activity --type update: filter by event type

Adds new mutation event types for richer activity display:
- MutationBonded: molecule bonded to parent
- MutationSquashed: wisp squashed to digest
- MutationBurned: wisp discarded
- MutationStatus: status transitions with old/new state

Event symbols: + created, → in_progress, ✓ completed, ⊘ deleted, ◉ squashed

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 03:19:09 -08:00
Ryan
e8d0860571 fix(doctor): use --fix instead of manual commands (#715)
UX improvement: doctor advice now recommends bd doctor --fix instead of manual commands
2025-12-23 02:30:33 -08:00
Steve Yegge
14e1f5a2e0 feat: add --parent flag to bd list command (bd-yqhh)
Filters issues by parent issue ID using parent-child dependencies.

Example: bd list --parent=bd-xyz --status=open

Changes:
- Add ParentID field to IssueFilter type
- Add --parent flag to list command
- Forward parent filter through RPC
- Implement filtering in SQLite and memory storage

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 02:10:42 -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
Steve Yegge
7fb92ff78c feat: implement conditional bond type for mol bond (bd-kzda)
Conditional bonds now work as documented: "B runs only if A fails".

Implementation:
- Add DepConditionalBlocks dependency type to types.go
- Add IsFailureClose() helper to detect failure keywords in close_reason
- Update blocked cache to handle conditional-blocks:
  - B is blocked while A is open
  - B stays blocked if A closes with success
  - B becomes unblocked if A closes with failure

Failure keywords: failed, rejected, wontfix, cancelled, abandoned,
blocked, error, timeout, aborted (case-insensitive)

Updated bondProtoProto, bondProtoMol, bondMolMol to use
DepConditionalBlocks for conditional bond type.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 01:32:31 -08:00
Steve Yegge
aa1ce63156 feat: consolidate maintenance commands into bd doctor --fix (bd-bqcc)
Add new Maintenance category to bd doctor with checks for:
- Stale closed issues (older than 30 days)
- Expired tombstones (older than TTL)
- Compaction candidates (info only)

Add fix handlers for cleanup and tombstone pruning via bd doctor --fix.
Add deprecation hints to cleanup, compact, and detect-pollution commands
suggesting users try bd doctor instead.

This consolidation reduces cognitive load - users just need to remember
'bd doctor' for health checks and 'bd doctor --fix' for maintenance.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 01:31:18 -08:00
Steve Yegge
59b57f8d06 test: add mol current tests (bd-nurq)
Add tests for molecule progress tracking:
- TestGetMoleculeProgress: tests loading molecule and computing progress
- TestFindParentMolecule: tests walking up parent-child chain
- TestAdvanceToNextStep: tests auto-advancing to next step
- TestAdvanceToNextStepMoleculeComplete: tests molecule completion detection
- TestAdvanceToNextStepOrphanIssue: tests non-molecule issue handling

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 01:24:36 -08:00
Steve Yegge
e79558a972 fix: make database_removal_scenario test more realistic
The test was creating an empty .beads/ directory after simulating rm -rf,
but FindBeadsDir() requires some project files (config.yaml, metadata.json,
or *.db/*.jsonl) to recognize a directory as a valid beads directory.

Updated the test to create a minimal config.yaml like bd init actually does
before auto-import runs. This makes the test more realistic and fixes the
flakiness.
2025-12-23 00:04:55 -08:00
Steve Yegge
bd6fa5cbbb fix: bd create -f now works with daemon mode (GH#719)
When using bd create -f with a running daemon, the command would fail
with 'database not initialized' because it bypassed the daemon RPC path.

The fix adds createIssuesFromMarkdownViaDaemon which:
- Parses the markdown file (no store access needed)
- Converts issue templates to CreateArgs
- Uses daemon Batch RPC to create all issues efficiently
- Preserves all features: labels, dependencies, hooks, JSON output

Tested with daemon and non-daemon modes, verifying priority 0 is
preserved correctly.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 23:30:08 -08:00
Steve Yegge
ad02b80330 feat: display external deps in bd dep tree (bd-vks2, bd-mv6h, bd-d9mu)
External dependencies (external:project:capability) are now visible in
the dependency tree output. Previously they were invisible because the
recursive CTE only JOINed against the issues table.

Changes:
- GetDependencyTree now fetches external deps and adds them as synthetic
  leaf nodes with resolution status (satisfied/blocked)
- formatTreeNode displays external deps with special formatting
- Added helper parseExternalRefParts for parsing external refs

Test coverage added for:
- External deps appearing in dependency tree
- Cycle detection ignoring external refs
- CheckExternalDep when target has no .beads directory
- Various invalid external ref format variations

Closes: bd-vks2, bd-mv6h, bd-d9mu
2025-12-22 22:34:18 -08:00
Steve Yegge
25061ea9a7 chore: code health review - test fix and error comments (bd-9g1z, bd-ork0)
- Remove TestFindJSONLPathDefault from .test-skip (now passes)
- Add explanatory comments to 24 ignored error locations in cmd/bd:
  - Cobra flag methods (MarkHidden, MarkRequired, MarkDeprecated)
  - Best-effort cleanup/close operations
  - Process signaling operations

Part of code health review epic bd-tggf.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 21:30:57 -08:00
Steve Yegge
fc0b98730a refactor: consolidate duplicate path-finding utilities (bd-74w1, bd-4nqq)
- Add git.GetRepoRoot() with Windows path normalization
- Update beads.findGitRoot() to delegate to git.GetRepoRoot()
- Replace findBeadsDir() with beads.FindBeadsDir() across 8 files
- Remove duplicate findBeadsDir() and findGitRoot() function definitions
- Remove dead test code (TestInfoCommand, TestInfoWithNoDaemon)
- Update tests to work with consolidated APIs

Part of Code Health Review Dec 2025 epic (bd-tggf).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 21:15:41 -08:00
Steve Yegge
e2ab727a2c fix(doctor): use context.Background() instead of nil in CheckDuplicateIssues
The nil context caused a panic during store.Close() in tests.
Passing context.Background() fixes the test timeout issue.
2025-12-22 20:21:30 -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
Steve Yegge
e60dfaf1f1 Merge pull request #713 from cpdata/fix/daemon-duplicate-log-messages
Reviewed by dave (beads crew worker)
2025-12-22 20:18:02 -08:00
Steve Yegge
c4fc27de57 Merge pull request #711 from cpdata/fix/worktree-health-check-redundancy
Reviewed by dave (beads crew worker)
2025-12-22 20:17:59 -08:00
Steve Yegge
7c24cf63bd Merge pull request #707 from cpdata/feat/auto-pull-config
Reviewed by dave (beads crew worker)
2025-12-22 20:17:54 -08:00
Steve Yegge
90ce008047 Merge pull request #705 from crcatala/fix/add-interactions-jsonl-to-gitignore-allowlist
Reviewed by dave (beads crew worker)
2025-12-22 20:17:51 -08:00
Steve Yegge
808c33b7a0 feat: add molecule navigation commands (bd-sal9, bd-ieyy)
Add bd mol current: Shows current position in molecule workflow
- Displays all steps with status indicators (done/current/ready/blocked/pending)
- Infers molecule from in_progress issues when no ID given
- Supports --for flag to check another agent's molecules

Add bd close --continue: Auto-advances to next molecule step
- After closing, finds parent molecule and next ready step
- Auto-claims next step by default (--no-auto to skip)
- Shows molecule completion message when all steps closed

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 17:37:23 -08:00
Charles P. Cross
195091711e fix(daemon): deduplicate file and git ref change log messages
The daemon.log was showing duplicate log messages:
- 'File change detected' appeared 4x for a single file change
- 'Git ref change detected' appeared 2x for a single ref update

Root cause:
- fsnotify generates multiple events (Write, Create, Chmod) for single file ops
- Both parent directory and file watchers can trigger for the same change
- Multiple git ref files may be updated simultaneously

Fix:
- Add log deduplication with 500ms window (matching debouncer window)
- Track last log time for file changes and git ref changes separately
- Only log if enough time has passed since last log of same type
- Still trigger debouncer for every event (functionality unchanged)

This reduces log noise while maintaining full functionality.
2025-12-22 19:02:42 -05:00
Charles P. Cross
665e5b3a87 fix(worktree): integrate health check into CreateBeadsWorktree to prevent redundant checks
The error message 'path exists but is not a valid git worktree' was appearing
in daemon.log when the daemon attempted to use an existing worktree that was
in the git worktree list but had other issues (broken sparse checkout, etc.).

Root cause:
- CreateBeadsWorktree only checked isValidWorktree (is it in git worktree list)
- CheckWorktreeHealth was called separately and checked additional things
- If the worktree passed isValidWorktree but failed health check, an error
  was logged and repair was attempted

Fix:
- CreateBeadsWorktree now performs a full health check when it finds an
  existing worktree that's in the git worktree list
- If the health check fails, it automatically removes and recreates the
  worktree
- Removed redundant CheckWorktreeHealth calls in daemon_sync_branch.go and
  syncbranch/worktree.go since CreateBeadsWorktree now handles this internally

This eliminates the confusing error message and ensures worktrees are always
in a healthy state after CreateBeadsWorktree returns successfully.
2025-12-22 18:57:43 -05:00
Steve Yegge
4c38075520 refactor(cmd): replace map[string]interface{} with typed JSON response structs (bd-u2sc.1)
Added typed response structs for JSON output in CLI commands:

compact.go:
- CompactDryRunResponse, CompactSuccessResponse
- CompactNoCandidatesResponse, CompactBatchSuccessResponse
- CompactStatsResponse, CompactTierStats
- CompactApplyResponse, TombstonePrunedInfo

cleanup.go:
- CleanupEmptyResponse

daemons.go:
- DaemonStopResponse, DaemonRestartResponse
- DaemonLogsResponse, DaemonKillallEmptyResponse
- DaemonHealthResponse, DaemonHealthReport

daemon_lifecycle.go:
- DaemonStatusResponse

Benefits:
- Compile-time type checking for JSON output
- IDE autocompletion for response fields
- Self-documenting API structure
- Easier refactoring

Note: RPC args and storage update maps remain as-is (require
interface changes for internal APIs).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 15:48:36 -08:00
Charles P. Cross
03f5afb605 feat(daemon): add auto_pull config parameter for periodic remote sync
Add --auto-pull flag to control whether the daemon periodically pulls from
remote to check for updates from other clones.

Configuration precedence:
1. --auto-pull CLI flag (highest)
2. BEADS_AUTO_PULL environment variable
3. daemon.auto_pull in database config
4. Default: true when sync.branch is configured

When auto_pull is enabled, the daemon creates a remoteSyncTicker that
periodically calls doAutoImport() to pull remote changes. When disabled,
users must manually run 'git pull' to sync remote changes.

Changes:
- cmd/bd/daemon.go: Add --auto-pull flag and config reading logic
- cmd/bd/daemon_event_loop.go: Gate remoteSyncTicker on autoPull parameter
- cmd/bd/daemon_lifecycle.go: Add auto-pull to status output and spawn args
- internal/rpc/protocol.go: Add AutoPull field to StatusResponse
- internal/rpc/server_core.go: Add autoPull to Server struct and SetConfig
- internal/rpc/server_routing_validation_diagnostics.go: Include in status
- Tests updated to pass autoPull parameter

Closes #TBD
2025-12-22 18:47:18 -05:00
Steve Yegge
e67712dcd4 refactor(cmd): migrate sort.Slice to slices.SortFunc (bd-u2sc.2)
Modernize sorting code to use Go 1.21+ slices package:
- Replace sort.Slice with slices.SortFunc across 16 files
- Use cmp.Compare for orderable types (strings, ints)
- Use time.Time.Compare for time comparisons
- Use cmp.Or for multi-field sorting
- Use slices.SortStableFunc where stability matters

Benefits: cleaner 3-way comparison, slightly better performance,
modern idiomatic Go.

Part of GH#692 refactoring epic.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 15:39:55 -08:00
Charles P. Cross
82cbd98e50 fix(daemon): include tombstones in exportToJSONLWithStore for sync propagation (#696)
* fix(daemon): include tombstones in exportToJSONLWithStore for sync propagation

The daemon's exportToJSONLWithStore() function was using an empty
IssueFilter which defaults to IncludeTombstones: false. This caused
deleted issues (tombstones) to be excluded from JSONL exports during
daemon sync cycles.

Bug scenario:
1. User runs `bd delete <issue>` with daemon active
2. Database correctly marks issue as tombstone
3. Main .beads/issues.jsonl correctly shows status:"tombstone"
4. But sync branch worktree JSONL still showed status:"open"
5. Other clones would not see the deletion

The fix adds IncludeTombstones: true to match the behavior of
exportToJSONL() in sync.go, ensuring tombstones propagate to other
clones and prevent resurrection of deleted issues.

Adds regression test TestExportToJSONLWithStore_IncludesTombstones
that verifies tombstones are included in daemon JSONL exports.

* fix: resolve all golangci-lint errors (cherry-pick from fix/linting-errors)

Cherry-picked linting fixes to ensure CI passes.

---------

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-22 14:18:10 -08:00
Charles P. Cross
ee016bbb25 fix(daemon): handle diverged sync branch with fetch-rebase-retry on push (#697)
* fix(daemon): handle diverged sync branch with fetch-rebase-retry on push

When pushing to the sync branch, if the remote has newer commits that
the local worktree doesn't have, the push would fail with "fetch first"
error and the daemon would log the failure without recovery.

Bug scenario:
1. Clone A pushes commit X to sync branch
2. Clone B has local commit Y (not based on X)
3. Clone B's push fails with "fetch first" error
4. Without this fix: daemon logs failure and stops
5. With this fix: daemon fetches, rebases Y on X, and retries push

This fix adds fetch-rebase-retry logic to gitPushFromWorktree():
1. Detect push rejection due to remote having newer commits
2. Fetch the latest remote sync branch
3. Rebase local commits on top of remote
4. Retry the push

If rebase fails (e.g., due to conflicts), the rebase is aborted and
an error is returned with helpful context.

This allows multiple clones to push to the same sync branch without
manual intervention, as long as the changes don't conflict.

Adds integration test TestGitPushFromWorktree_FetchRebaseRetry that
verifies the fetch-rebase-retry behavior with diverged branches.

* fix: resolve all golangci-lint errors (cherry-pick from fix/linting-errors)

Cherry-picked linting fixes to ensure CI passes.

---------

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-22 14:17:26 -08:00
Charles P. Cross
737e65afbd fix(daemon): add periodic remote sync to event-driven mode (#698)
* fix(daemon): add periodic remote sync to event-driven mode

The event-driven daemon mode only triggered imports when the local JSONL
file changed (via file watcher) or when the fallback ticker fired (only
if watcher failed). This meant the daemon wouldn't see updates pushed
by other clones until something triggered a local file change.

Bug scenario:
1. Clone A creates an issue and daemon pushes to sync branch
2. Clone B's daemon only watched local file changes
3. Clone B would not see the new issue until something triggered local change
4. With this fix: Clone B's daemon periodically calls doAutoImport

This fix adds a 30-second periodic remote sync ticker that calls
doAutoImport(), which includes syncBranchPull() to fetch and import
updates from the remote sync branch.

This is essential for multi-clone workflows where:
- Clone A creates an issue and daemon pushes to sync branch
- Clone B's daemon needs to periodically pull to see the new issue
- Without periodic sync, Clone B would only see updates if its local
  JSONL file happened to change

The 30-second interval balances responsiveness with network overhead.

Adds integration test TestEventDrivenLoop_PeriodicRemoteSync that
verifies the event-driven loop starts with periodic sync support.

* feat(daemon): add configurable interval for periodic remote sync

- Add BEADS_REMOTE_SYNC_INTERVAL environment variable to configure
  the interval for periodic remote sync (default: 30s)
- Add getRemoteSyncInterval() function to parse the env var
- Minimum interval is 5s to prevent excessive load
- Setting to 0 disables periodic sync (not recommended)
- Add comprehensive integration tests for the configuration

Valid duration formats:
- "30s" (30 seconds)
- "1m" (1 minute)
- "5m" (5 minutes)

Tests added:
- TestEventDrivenLoop_HasRemoteSyncTicker
- TestGetRemoteSyncInterval_Default
- TestGetRemoteSyncInterval_CustomValue
- TestGetRemoteSyncInterval_MinimumEnforced
- TestGetRemoteSyncInterval_InvalidValue
- TestGetRemoteSyncInterval_Zero
- TestSyncBranchPull_FetchesRemoteUpdates

* fix: resolve all golangci-lint errors (cherry-pick from fix/linting-errors)

Cherry-picked linting fixes to ensure CI passes.

* feat(daemon): add config.yaml support for remote-sync-interval

- Add remote-sync-interval to .beads/config.yaml as alternative to
  BEADS_REMOTE_SYNC_INTERVAL environment variable
- Environment variable takes precedence over config.yaml (follows
  existing pattern for flush-debounce)
- Add config binding in internal/config/config.go
- Update getRemoteSyncInterval() to use config.GetDuration()
- Add doctor validation for remote-sync-interval in config.yaml

Configuration sources (in order of precedence):
1. BEADS_REMOTE_SYNC_INTERVAL environment variable
2. remote-sync-interval in .beads/config.yaml
3. DefaultRemoteSyncInterval (30s)

Example config.yaml:
  remote-sync-interval: "1m"

---------

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-22 14:15:33 -08:00
Charles P. Cross
e360a74b61 fix: resolve all golangci-lint errors (#699)
Fix 12 linting issues that were causing CI failures:

errcheck (8 fixes):
- cmd/bd/mol_burn.go: wrap wispStore.Close() in defer func
- cmd/bd/mol_burn.go: handle fmt.Scanln() return value
- cmd/bd/mol_squash.go: wrap wispStore.Close() in defer func (2 locations)
- cmd/bd/wisp.go: wrap wispStore.Close() in defer func (3 locations)
- internal/beads/beads.go: wrap mainStore.Close() and wispStore.Close()

gosec G104 (2 fixes):
- internal/storage/sqlite/multirepo.go: handle rows.Close() errors

misspell (1 fix):
- cmd/bd/mol_burn.go: change "Cancelled" to "Canceled"

unparam (1 fix):
- cmd/bd/mol_squash.go: use blank identifier for unused cmd parameter

All fixes follow existing patterns in the codebase:
- defer func() { _ = store.Close() }() for deferred closes
- _ = rows.Close() for explicit closes with ignored errors
- _, _ = fmt.Scanln() for ignored return values

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-22 14:06:45 -08:00
cc-vps
7ad9fb537b fix: add interactions.jsonl to .gitignore allowlist
The interactions.jsonl file is an append-only audit log that should be
tracked in git (synced with bd sync), but it was missing from the
negation patterns in .beads/.gitignore.

This adds !interactions.jsonl alongside !issues.jsonl and !metadata.json
for consistency and clarity that this file should be committed.

Co-authored-by: Christian Catalan <crcatala@gmail.com>
2025-12-22 13:48:06 -08:00
Steve Yegge
199def9fed release: v0.34.0
## Added
- Wisp commands - bd wisp create/list/gc for ephemeral molecule management
- Chemistry UX - bd pour, bd mol bond --wisp/--pour for phase control
- Cross-project deps - external:<repo>:<id> syntax, bd ship command
- Orphan detection in bd doctor

## Changed
- Multi-repo config uses YAML - bd repo add/remove writes to .beads/config.yaml

## Fixed
- Wisp storage auto-copies issue_prefix from main database
- Prefix validation in multi-repo mode
- Remove orphaned repo_test.go
- Update version tests for 0.34.0 thresholds

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 03:18:55 -08:00
Steve Yegge
cadf798b23 feat: implement molecular chemistry UX commands
Add chemistry-inspired commands for the molecular work metaphor:

New commands:
- bd pour <proto>: Instantiate proto as persistent mol (liquid phase)
- bd wisp create <proto>: Instantiate proto as ephemeral wisp (vapor)
- bd hook: Inspect what's pinned to an agent's hook

Enhanced commands:
- bd mol spawn: Add --pour flag, deprecate --persistent
- bd mol bond: Add --pour flag (force liquid on wisp target)
- bd pin: Add --for <agent> and --start flags

Phase transitions:
  Proto (solid) --pour--> Mol (liquid) --squash--> Digest
  Proto (solid) --wisp--> Wisp (vapor) --burn--> (nothing)

Design docs: gastown/mayor/rig/docs/molecular-chemistry.md

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 02:21:40 -08:00
Steve Yegge
8f8e9516df fix: bd repo commands write to YAML and cleanup on remove (#683)
- bd repo add/remove now writes to .beads/config.yaml instead of database
- bd repo remove deletes hydrated issues from the removed repo
- Added internal/config/repos.go for YAML config manipulation
- Added DeleteIssuesBySourceRepo for cleanup on remove

Fixes config disconnect where bd repo add wrote to DB but hydration read from YAML.

Breaking change: bd repo add no longer accepts optional alias argument.

Co-authored-by: Dylan Conlin <dylan.conlin@gmail.com>

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 01:26:45 -08:00
Ryan
a11b20960a fix(doctor): UX improvements for diagnostics and daemon (#687)
* fix(doctor): UX improvements for diagnostics and daemon

- Add Repo Fingerprint check to detect when database belongs to a
  different repository (copied .beads dir or git remote URL change)
- Add interactive fix for repo fingerprint with options: update repo ID,
  reinitialize database, or skip
- Add visible warning when daemon takes >5s to start, recommending
  'bd doctor' for diagnosis
- Detect install method (Homebrew vs script) and show only relevant
  upgrade command
- Improve WARNINGS section:
  - Add icons (⚠ or ✖) next to each item
  - Color numbers by severity (yellow for warnings, red for errors)
  - Render entire error lines in red
  - Sort by severity (errors first)
  - Fix alignment with checkmarks above
- Use heavier fail icon (✖) for better visibility
- Add integration and validation tests for doctor fixes

* fix(lint): address errcheck and gosec warnings

- mol_bond.go: explicitly ignore ephStore.Close() error
- beads.go: add nosec for .gitignore file permissions (0644 is standard)
2025-12-22 01:25:23 -08:00
Steve Yegge
f27b1f3102 feat: add wisp commands (bd-kwjh)
Implements wisp management commands for ephemeral molecules:
- bd wisp list: List wisps with stale detection
- bd wisp gc: Garbage collect orphaned wisps
- bd mol burn: Delete wisp without creating digest

Wisps are ephemeral molecules stored in .beads-wisp/ for patrol cycles
and operational loops that shouldn't accumulate in permanent storage.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 01:13:50 -08:00
Steve Yegge
69911070f0 feat: add cross-store wisp→digest squash (bd-kwjh.4)
- Add wisp detection in mol squash: checks wisp storage if not in main
- squashWispToPermanent: creates digest in permanent, deletes from wisp
- Fix directory naming: .beads-wisps → .beads-wisp (singular, matches doc)
- Add comprehensive tests for wisp squash scenarios

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 00:54:35 -08:00
Steve Yegge
a49b924794 refactor: rename ephemeral → wisp throughout (bd-ldb0)
Standardize terminology for ephemeral molecule storage:
- .beads-ephemeral/ → .beads-wisps/
- --ephemeral flag → --wisp flag
- All Ephemeral* functions → Wisp*

Wisps are the "steam" in Gas Town's engine metaphor - ephemeral
molecules that evaporate after squash.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 00:32:18 -08:00
Steve Yegge
22eee81f42 feat: add --ephemeral flag to bd mol bond (bd-kwjh.3)
When --ephemeral is set:
- Spawned molecules go to .beads-ephemeral/ instead of .beads/
- Ephemeral directory is automatically gitignored
- No auto-flush (ephemeral does not sync)
- Proto+proto bonding ignores flag (templates stay in permanent storage)

Updated help text to document wisp workflow (bond then squash/burn).

Generated with Claude Code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 00:19:18 -08:00
Steve Yegge
9afefe73a7 feat: add bd ship command for cross-project capabilities (bd-eijl)
- bd ship <capability> finds issue with export:<capability> label
- Validates issue is closed (or --force to override)
- Adds provides:<capability> label to mark capability as shipped
- Protects provides:* namespace in bd label add
- Supports --dry-run for preview

External projects depend on capabilities via:
  bd dep add <issue> external:<project>:<capability>

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 23:11:48 -08:00
Steve Yegge
e7f09660c0 feat: add cross-project dependency support - config and external: prefix (bd-66w1, bd-om4a)
Config (bd-66w1):
- Add external_projects config for mapping project names to paths
- Add GetExternalProjects() and ResolveExternalProjectPath() functions
- Add config documentation and tests

External deps (bd-om4a):
- bd dep add accepts external:project:capability syntax
- External refs stored as-is in dependencies table
- GetBlockedIssues includes external deps in blocked_by list
- blocked_issues_cache includes external dependencies
- Add validation and parsing helpers for external refs

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 23:08:00 -08:00
Steve Yegge
fe6fec437a fix: remove slice bounds panic in mol run output (bd-987a)
The code assumed rootID was at least 8 chars, but issue IDs
like 'gt-i4lo' are only 7 chars (prefix-hash format).

Simply use the full ID instead of truncating - IDs are already
short enough for display.
2025-12-21 22:58:05 -08:00
Steve Yegge
240a4e2dbc feat: add bd doctor check for orphaned issues (bd-5hrq)
- Add CheckOrphanedIssues to detect issues referenced in commits but still open
- Pattern matches (prefix-xxx) in git log against open issues in database
- Reports warning with issue IDs and commit hashes
- Add 8 comprehensive tests for the new check

Also:
- Add tests for mol spawn --attach functionality (bd-f7p1)
- Document commit message convention in AGENT_INSTRUCTIONS.md
- Fix CheckpointWAL to use wrapDBError for consistency

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 22:05:14 -08:00
Steve Yegge
6a949d91b8 fix: rename customID to customTitle in mol bond for consistency (bd-e7ou)
The --as flag description correctly says "Custom title" but the variable
was named customID and dry-run output said "Custom ID". Fixed for consistency:

- Renamed variable customID -> customTitle
- Changed dry-run output from "Custom ID" to "Custom title"

Closes bd-e7ou
2025-12-21 21:18:43 -08:00
Steve Yegge
d39e868199 fix: handle empty config values in getRepoConfig() (GH#680)
GetConfig() returns ("", nil) for missing/empty config keys.
getRepoConfig() then tried json.Unmarshal([]byte(""), ...) which
fails with "unexpected end of JSON input".

Add empty value check before JSON parsing - return empty map when
config value is empty string.

Closes GH#680

Co-Authored-By: dylan-conlin <dylan-conlin@users.noreply.github.com>
2025-12-21 21:08:57 -08:00
Steve Yegge
1e096a30b0 feat: add 'fart' as easter egg alias for bd mol bond
Molecules can produce gas (wisps) when bonded. 💨

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 16:43:21 -08:00
Steve Yegge
95b735c070 fix: add third change to satisfy versionChanges test 2025-12-21 16:14:41 -08:00
Steve Yegge
c184d10554 chore: bump version to 0.33.2
Fixes:
- P0 priority preserved - omitempty removed from Priority field (GH#671)
- nil pointer check in markdown parsing (GH#674)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 16:12:37 -08:00
Steve Yegge
0c10eab873 chore: remove dead deprecated wrapper functions
Remove cleanupSnapshots() and validateSnapshotConsistency() from
deletion_tracking.go - both were marked deprecated and never called.

The other two deprecated functions (getSnapshotStats, initializeSnapshotsIfNeeded)
are still used by tests and production code respectively.

Filed bd-xsl9 to track removal of legacy autoflush dual-path code.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 15:50:10 -08:00
Steve Yegge
8b87c556c7 fix: priority:0 omitempty and markdown nil pointer (GH#671, GH#674)
- Remove omitempty from Priority field so P0 issues preserve priority:0
- Add nil check for store in createIssuesFromMarkdown

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 15:41:22 -08:00
Steve Yegge
4e8924c52f chore: bump version to 0.33.1
Breaking changes:
- Ephemeral → Wisp rename (JSON field, CLI flag)

Fixes:
- Lint error in mail.go (nosec for mail delegate)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 15:31:38 -08:00