Commit Graph

18 Commits

Author SHA1 Message Date
Steve Yegge
b9919fe031 Fix: --parent flag now creates parent-child dependency
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>
2025-11-15 13:20:02 -08:00
David Laing
57b6ea606b fix: add external_ref support to daemon mode RPC (fixes #303) (#304)
Add external_ref field to CreateArgs and UpdateArgs RPC protocol
structs to enable linking issues to external systems (GitHub, Jira,
Shortcut, etc.) when using daemon mode.

Changes:
- Add ExternalRef field to rpc.CreateArgs and rpc.UpdateArgs
- Update bd create/update commands to pass external_ref via RPC
- Update daemon handlers to process external_ref field
- Add integration tests for create and update operations

The --external-ref flag now works correctly in both daemon and direct modes.

Fixes https://github.com/steveyegge/beads/issues/303

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
2025-11-13 12:01:27 -08:00
vector-sigma
6408ef65f4 Fix #249: Add nil storage checks to prevent RPC daemon crashes (#250)
The daemon RPC server was crashing with a nil pointer dereference when the
global daemon received list, ready, stats, or other storage-dependent RPC
requests. The global daemon is created with nil storage, causing these
operations to panic when they attempted to access storage methods.

This fix adds defensive nil checks at the beginning of all RPC handlers
that require storage access. When storage is unavailable, they now return
a proper JSON error response instead of crashing the daemon.

The error message also informs users that the global daemon is deprecated
and they should use local daemons instead.

Handlers fixed:
- handleCreate, handleUpdate, handleClose
- handleList, handleShow, handleReady, handleStale
- handleResolveID, handleStats, handleEpicStatus
- handleCompact, handleCompactStats
- handleDepAdd (and via handleSimpleStoreOp for all label/dep/comment ops)

Co-authored-by: Test User <test@example.com>
2025-11-07 14:21:14 -08:00
Steve Yegge
9520e7a2e2 Extract normalizeLabels to internal/util/strings.go
- Created internal/util/strings.go with NormalizeLabels function
- Added comprehensive tests in internal/util/strings_test.go
- Updated internal/rpc/server_issues_epics.go to use util.NormalizeLabels
- Updated cmd/bd/list.go and cmd/bd/ready.go to use util.NormalizeLabels
- Updated cmd/bd/list_test.go to use util.NormalizeLabels
- Removed duplicate implementations
- All tests pass

Fixes bd-fb95094c.6

Amp-Thread-ID: https://ampcode.com/threads/T-edb3c286-cd60-4231-94cd-edaf75d84a3d
Co-authored-by: Amp <amp@ampcode.com>
2025-11-06 20:00:08 -08:00
Steve Yegge
fc89f15ca0 Add --parent flag support in daemon mode (bd-2e94)
- Added Parent field to CreateArgs RPC protocol
- Updated CLI to pass parent ID to daemon instead of erroring
- Added parent ID handling in RPC server to call GetNextChildID
- Added validation to prevent both --id and --parent flags
- Added comprehensive tests for hierarchical child creation
- Resolves error: '--parent flag not yet supported in daemon mode'

Amp-Thread-ID: https://ampcode.com/threads/T-3e0f76df-4ba6-4b16-bf75-bb7ea6b19541
Co-authored-by: Amp <amp@ampcode.com>
2025-11-05 13:56:25 -08:00
Steve Yegge
fbe790aa40 feat: Add ancestor_id field and implement epic/child filtering
Amp-Thread-ID: https://ampcode.com/threads/T-22f7d7c5-6f7b-4783-beda-8494360d887a
Co-authored-by: Amp <amp@ampcode.com>
2025-11-05 00:44:41 -08:00
Steve Yegge
cac9ae6647 Add routing integration tests and documentation
- Created routing_integration_test.go with comprehensive routing tests
- Tests cover maintainer/contributor detection, explicit overrides, end-to-end multi-repo
- Added docs/ROUTING.md documenting auto-routing feature
- Closed bd-6u6g, bd-zmi5, bd-nzt4, bd-btsm (routing tests)
- Updated bd-4ms and bd-8hf with progress notes

All routing tests pass. Multi-repo auto-routing is complete.

Amp-Thread-ID: https://ampcode.com/threads/T-2ea8b2ed-ceb7-432e-91f1-1f527b0e7b4d
Co-authored-by: Amp <amp@ampcode.com>
2025-11-04 23:12:42 -08:00
Ben Lovell
b92e79f98e Fix pointer dereferencing in Update RPC handler (#223)
- Dereference Design, AcceptanceCriteria, Notes, and Assignee pointers in updatesFromArgs
- Fixes EOF errors when using --notes, --design, --assignee, or --acceptance-criteria flags
- Enhance TestUpdateIssue to verify all pointer-dereferenced fields are correctly stored
2025-11-04 22:10:56 -08:00
Steve Yegge
eb434dd08c Add template support for issue creation (bd-164b)
- Built-in templates: epic, bug, feature (embedded in binary)
- Custom templates in .beads/templates/ (override built-ins)
- Commands: bd template list/show/create
- Flag: bd create --from-template <name> "Title"
- Template fields: description, type, priority, labels, design, acceptance
- Security: sanitize template names to prevent path traversal
- Flag precedence: explicit flags override template defaults
- Tests: template loading, security, flag precedence
- Docs: commands/template.md and README.md updated

Closes bd-164b

Amp-Thread-ID: https://ampcode.com/threads/T-118fe54f-b112-4f99-a3d9-b7df53fb7284
Co-authored-by: Amp <amp@ampcode.com>
2025-11-03 20:31:11 -08:00
Steve Yegge
3343351d3b Fix epic hierarchy display in bd show command
Amp-Thread-ID: https://ampcode.com/threads/T-43f6c7bf-9d4f-4475-8266-69e0a35a5909
Co-authored-by: Amp <amp@ampcode.com>
2025-11-03 14:24:45 -08:00
Steve Yegge
481649a605 Fix widespread double JSON encoding bug in daemon RPC calls (bd-1048, bd-4ec8)
Multiple CLI commands had a systematic bug where ResolveID responses were
incorrectly converted using string(resp.Data) instead of json.Unmarshal.
Since resp.Data is json.RawMessage (already JSON-encoded), this preserved
the JSON quotes, causing IDs to become "bd-1048" instead of bd-1048.
When re-marshaled for subsequent RPC calls, these became double-quoted
("\"bd-1048\""), causing database lookups to fail.

Bugs fixed:
1. Nil pointer dereference in handleShow - added nil check after GetIssue
2. Double JSON encoding in 12 locations across 4 commands:
   - bd show (3 instances in show.go)
   - bd dep add/remove/tree (5 instances in dep.go)
   - bd label add/remove/list (3 instances in label.go)
   - bd reopen (1 instance in reopen.go)

All instances replaced string(resp.Data) with proper json.Unmarshal.
Removed debug logging added during investigation.

Tested: All affected commands now work correctly with daemon mode.
2025-11-02 22:34:24 -08:00
Nikolai Prokoschenko
c65cfa1ebd Add dependency and dependent counts to bd list JSON output (#198)
When using `bd list --json`, each issue now includes:
- `dependency_count`: Number of issues this issue depends on
- `dependent_count`: Number of issues that depend on this issue

This provides quick access to dependency relationship counts without
needing to fetch full dependency lists or run multiple bd show commands.

Performance:
- Uses single bulk query (GetDependencyCounts) instead of N individual queries
- Overhead: ~26% for 500 issues (24ms vs 19ms baseline)
- Avoids N+1 query problem that would have caused 2.2x slowdown

Implementation:
- Added GetDependencyCounts() to Storage interface for bulk counting
- Efficient SQLite query using UNION ALL + GROUP BY
- Memory storage implementation for testing
- Moved IssueWithCounts to types package to avoid duplication
- Both RPC and direct modes use optimized bulk query

Tests:
- Added comprehensive tests for GetDependencyCounts
- Tests cover: normal operation, empty list, nonexistent IDs
- All existing tests continue to pass

Backwards compatible: JSON structure is additive, all original fields preserved.

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-01 19:59:15 -07:00
Steve Yegge
cc7918daf4 Implement bd stale command (bd-c01f, closes #184)
- Add bd stale command to find abandoned/forgotten issues
- Support --days (default 30), --status, --limit, --json flags
- Implement GetStaleIssues in SQLite and Memory storage
- Add full RPC/daemon support
- Comprehensive test suite (6 tests, all passing)
- Update AGENTS.md documentation

Resolves GitHub issue #184

Amp-Thread-ID: https://ampcode.com/threads/T-f021ddb8-54e3-41bf-ba7a-071749663c1d
Co-authored-by: Amp <amp@ampcode.com>
2025-10-31 23:03:56 -07:00
Steve Yegge
e2bb4311f1 Improve mutation channel robustness
- Add event type constants (MutationCreate, MutationUpdate, MutationDelete, MutationComment)
- Make buffer size configurable via BEADS_MUTATION_BUFFER (default 512, up from 100)
- Add defensive closed-channel handling in event loop consumer
- Add 1s dropped-events ticker (down from 60s) for faster recovery
- Verify mutationChan is never closed (prevents panic)

Oracle review findings addressed:
- Eliminates panic risk from send-on-closed-channel
- Reduces worst-case recovery latency from 60s to 1s
- Increases buffer capacity for better burst handling
- Type-safe event constants prevent string typos

Related: bd-36320a04, bd-1f4086c5
2025-10-31 19:12:02 -07:00
Steve Yegge
11c26d5af8 Add substring ID matching for all bd commands
- Enhanced ResolvePartialID to handle:
  - Bare hashes: 07b8c8 → bd-07b8c8
  - Prefix without hyphen: bd07b8c8 → bd-07b8c8
  - Full IDs: bd-07b8c8 (unchanged)
  - Substring matching: 07b → finds bd-07b8c8

- Added RPC support:
  - New OpResolveID operation
  - handleResolveID server handler
  - ResolveID client method

- Updated all commands to resolve IDs:
  - show, update, close, reopen
  - dep (add, remove, tree)
  - label (add, remove, list)

- Works in both daemon and direct modes

Fixes bd-0591c3
2025-10-30 19:20:50 -07:00
Steve Yegge
781e300d33 Add event-driven daemon architecture (Phase 1 foundation)
- Add fsnotify dependency for file watching
- Create daemon_debouncer.go: batch rapid events (500ms window)
- Create daemon_watcher.go: monitor JSONL and git refs changes
- Create daemon_event_loop.go: event-driven sync loop
- Add mutation channel to RPC server (create/update/close events)
- Add BEADS_DAEMON_MODE env var (poll/events, default: poll)

Phase 1 implementation: opt-in via BEADS_DAEMON_MODE=events
Target: <500ms latency (vs 5000ms), ~60% CPU reduction

Related: bd-49 (epic), bd-50, bd-51, bd-53, bd-54, bd-55, bd-56
Amp-Thread-ID: https://ampcode.com/threads/T-35a3d0d7-4e19-421d-8392-63755035036e
Co-authored-by: Amp <amp@ampcode.com>
2025-10-28 13:12:37 -07:00
Steve Yegge
bbb1725c32 Replace getStorageForRequest with s.storage (bd-32)
- Replaced all getStorageForRequest(req) calls with direct s.storage access
- Updated 5 handler files: server_issues_epics.go (~8 calls), server_labels_deps_comments.go (~4 calls), server_compact.go (~2 calls), server_export_import_auto.go (~2 calls), server_routing_validation_diagnostics.go (~1 call)
- Only remaining references are in server_cache_storage.go (to be deleted in bd-33) and server_eviction_test.go (to be deleted in bd-34)
- Part of bd-29 epic to remove daemon storage cache

Amp-Thread-ID: https://ampcode.com/threads/T-239a5531-68a5-4c98-b85d-0e3512b2553c
Co-authored-by: Amp <amp@ampcode.com>
2025-10-27 23:14:38 -07:00
Steve Yegge
0c737025b5 Split internal/rpc/server.go into 8 focused modules (bd-215)
Refactored monolithic 2238-line server.go into 8 files with clear responsibilities:
- server_core.go: Server type, NewServer (115 lines)
- server_lifecycle_conn.go: Start/Stop/connection handling (248 lines)
- server_cache_storage.go: Storage caching and eviction (286 lines)
- server_routing_validation_diagnostics.go: Request routing/validation (384 lines)
- server_issues_epics.go: Issue CRUD operations (506 lines)
- server_labels_deps_comments.go: Labels/deps/comments (199 lines)
- server_compact.go: Compaction operations (287 lines)
- server_export_import_auto.go: Export/import operations (293 lines)

Improvements:
- Replaced RWMutex.TryLock with atomic.Bool for portable single-flight guard
- Added default storage close in Stop() to prevent FD leaks
- All methods remain on *Server receiver (no behavior changes)
- Each file <510 LOC for better maintainability
- All tests pass, daemon verified working

Amp-Thread-ID: https://ampcode.com/threads/T-92d481ad-1bda-4ecd-bcf5-874a1889db30
Co-authored-by: Amp <amp@ampcode.com>
2025-10-27 21:14:34 -07:00