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
This commit is contained in:
Steve Yegge
2025-10-30 19:20:50 -07:00
parent 185c734d75
commit 11c26d5af8
10 changed files with 343 additions and 124 deletions

View File

@@ -255,6 +255,11 @@ func (c *Client) Show(args *ShowArgs) (*Response, error) {
return c.Execute(OpShow, args)
}
// ResolveID resolves a partial issue ID to a full ID via the daemon
func (c *Client) ResolveID(args *ResolveIDArgs) (*Response, error) {
return c.Execute(OpResolveID, args)
}
// Ready gets ready work via the daemon
func (c *Client) Ready(args *ReadyArgs) (*Response, error) {
return c.Execute(OpReady, args)

View File

@@ -25,6 +25,7 @@ const (
OpCommentList = "comment_list"
OpCommentAdd = "comment_add"
OpBatch = "batch"
OpResolveID = "resolve_id"
OpCompact = "compact"
OpCompactStats = "compact_stats"
@@ -104,6 +105,11 @@ type ShowArgs struct {
ID string `json:"id"`
}
// ResolveIDArgs represents arguments for the resolve_id operation
type ResolveIDArgs struct {
ID string `json:"id"`
}
// ReadyArgs represents arguments for the ready operation
type ReadyArgs struct {
Assignee string `json:"assignee,omitempty"`

View File

@@ -6,6 +6,7 @@ import (
"strings"
"github.com/steveyegge/beads/internal/types"
"github.com/steveyegge/beads/internal/utils"
)
// normalizeLabels trims whitespace, removes empty strings, and deduplicates labels
@@ -319,6 +320,31 @@ func (s *Server) handleList(req *Request) Response {
}
}
func (s *Server) handleResolveID(req *Request) Response {
var args ResolveIDArgs
if err := json.Unmarshal(req.Args, &args); err != nil {
return Response{
Success: false,
Error: fmt.Sprintf("invalid resolve_id args: %v", err),
}
}
ctx := s.reqCtx(req)
resolvedID, err := utils.ResolvePartialID(ctx, s.storage, args.ID)
if err != nil {
return Response{
Success: false,
Error: fmt.Sprintf("failed to resolve ID: %v", err),
}
}
data, _ := json.Marshal(resolvedID)
return Response{
Success: true,
Data: data,
}
}
func (s *Server) handleShow(req *Request) Response {
var showArgs ShowArgs
if err := json.Unmarshal(req.Args, &showArgs); err != nil {

View File

@@ -168,6 +168,8 @@ func (s *Server) handleRequest(req *Request) Response {
resp = s.handleList(req)
case OpShow:
resp = s.handleShow(req)
case OpResolveID:
resp = s.handleResolveID(req)
case OpReady:
resp = s.handleReady(req)
case OpStats: