* fix: address critical resource leaks and error handling issues
Fixes 5 critical and high-priority issues identified in codebase analysis:
1. bd-vavh: Fix row iterator resource leak in recursive dependency queries
- Move defer rows.Close() to execute on all code paths
- Previously leaked connections on scan errors
- Location: internal/storage/sqlite/sqlite.go:1121-1145
2. bd-qhws: Configure database connection pool limits for daemon mode
- Set MaxOpenConns to runtime.NumCPU() + 1 for file-based databases
- Prevents connection exhaustion under concurrent RPC load
- Only affects daemon mode (long-running server)
- Location: internal/storage/sqlite/sqlite.go:108-125
3. bd-jo38: Add WaitGroup tracking to FileWatcher goroutines
- Track goroutines with sync.WaitGroup for graceful shutdown
- Wait for goroutines to finish before cleanup in Close()
- Prevents race condition on debouncer access during shutdown
- Location: cmd/bd/daemon_watcher.go (Start, startPolling, Close)
4. bd-2d5r: Fix silent error handling in RPC response writing
- writeResponse now returns errors instead of ignoring them
- Prevents sending partial JSON and client hangs
- Closes connection on marshal/write errors
- Location: internal/rpc/server_lifecycle_conn.go:227-246
5. bd-zqmb: Fix goroutine leak in daemon restart
- Add 10-second timeout to daemon Wait() goroutine
- Kill process if it doesn't fork within timeout
- Prevents goroutine accumulation on restart failures
- Location: cmd/bd/daemons.go:250-268
All changes follow Go best practices and maintain backward compatibility.
* Add feature request for .beads/README.md generation during init
Created bd-m7ge to automatically generate a promotional/documentation
README in the .beads directory when running 'bd init'. This will help
advertise Beads in open source repositories and provide quick reference
documentation for developers using AI coding agents.
The README will include:
- Brief explanation of Beads (AI-native issue tracking)
- Link to steveyegge/beads repository
- Quick reference of essential commands
- Compelling messaging to encourage adoption
monitor-webui fails to connect to the bd daemon because it calculates the socket path incorrectly. It expects beads.db.sock in a nested .beads directory, whereas the daemon listens on bd.sock in the .beads directory.
Updated `getSocketPath` function to:
- Check if dbPath directory is already .beads.
- Use bd.sock as the socket name instead of [dbName].sock.
- Handle both nested and non-nested cases correctly.
- Add fast path for exact ID matches in ResolvePartialID
- Properly unmarshal ResolveID RPC responses used by `bd show`
Summary:
--------
Fixes regression introduced after v0.23.1 where `bd show <issue_id>`,
`bd update <issue_id>`, and `bd close <issue_id>` commands failed with
"operation failed: issue not found" errors even when the issue existed
in the database.
Root Cause:
-----------
The daemon's ResolveID RPC handler (handleResolveID in
internal/rpc/server_issues_epics.go) returns a JSON-encoded string
containing the resolved issue ID. For example, when resolving "ao-izl",
the RPC response contains the JSON string: "ao-izl" (with quotes).
After v0.23.1, the show/update/close commands in cmd/bd/show.go were
changed to use string(resp.Data) to extract the resolved ID, which
treats the raw bytes as a string without decoding the JSON. This caused
the resolved ID to literally be "ao-izl" (including the quotes),
which then failed to match the actual issue ID ao-izl (without quotes)
when passed to subsequent Show/Update/Close RPC calls.
In v0.23.1 (commit 77dcf55), the code correctly unmarshaled the JSON:
var resolvedID string
if err := json.Unmarshal(resp.Data, &resolvedID); err != nil {
// handle error
}
This unmarshal step was removed in later commits, causing the regression.
Fix:
----
Restored the JSON unmarshaling step in three places in cmd/bd/show.go:
1. showCmd - line 37-42
2. updateCmd - line 400-405
3. closeCmd - line 723-728
Each now properly decodes the JSON string response before using the
resolved ID in subsequent RPC calls.
Testing:
--------
- Verified `bd show <issue-id-with-prefix>` works correctly in both daemon and direct modes
- Tested with newly created issues to ensure the fix works for all IDs
- All Go tests pass (go test ./... -short)
- Confirmed behavior matches v0.23.1 working binary
The fix ensures that issue ID resolution works correctly regardless of
whether the ID prefix matches the configured issue_prefix.
After daemon auto-export, JSONL mtime could be newer than database mtime
due to SQLite WAL mode not updating beads.db until checkpoint. This caused
validatePreExport to incorrectly block subsequent exports with "JSONL is
newer than database" error, leading to daemon shutdown.
Solution: Call TouchDatabaseFile after all export operations to ensure
database mtime >= JSONL mtime. This prevents false positives in validation
- Enhanced checkIDFormat to sample multiple issues instead of just one
- Added detectHashBasedIDs function with robust multi-heuristic detection:
* Checks for child_counters table (hash ID schema indicator)
* Detects letters in IDs (base36 encoding)
* Identifies leading zeros (common in hash IDs, rare in sequential)
* Analyzes variable length patterns (adaptive hash IDs)
* Checks for non-sequential numeric ordering
- Added comprehensive test coverage (16 new test cases)
- Fixes false positives for numeric-only hash IDs like 'pf-0088'
Closes#322
The ID disambiguation logic treated 'offlinebrew-3d0' as ambiguous when
child IDs like 'offlinebrew-3d0.1' existed. Now the system:
1. Checks for exact full ID matches first (issue.ID == input)
2. Checks for exact hash matches (handling cross-prefix scenarios)
3. Only falls back to substring matching if no exact match is found
Added test cases verifying:
- 'offlinebrew-3d0' matches exactly, not ambiguously with children
- '3d0' without prefix still resolves to exact match
Amp-Thread-ID: https://ampcode.com/threads/T-5358ea57-e9ea-49e9-aedf-7044ebf8b52a
Co-authored-by: Amp <amp@ampcode.com>
When using 'bd create --parent <id>', the system now automatically
creates a parent-child dependency linking the child to the parent.
This fixes epic status reporting which was showing zero children.
Fixes#318 (bd-jijf)
Changes:
- cmd/bd/create.go: Add parent-child dependency after issue creation
- internal/rpc/server_issues_epics.go: Add same fix for daemon mode
Tested:
- Created epic with children, verified epic status shows correct count
- Verified closing all children makes epic eligible for closure
- All tests pass
Amp-Thread-ID: https://ampcode.com/threads/T-f1a1aee1-03bd-4e62-a63c-c1d339f8300b
Co-authored-by: Amp <amp@ampcode.com>