From 2199bdffea874e6cbe7b5ad08dbac4ff66ff91d9 Mon Sep 17 00:00:00 2001 From: rictus Date: Fri, 2 Jan 2026 13:50:43 -0800 Subject: [PATCH] fix(convoy): Auto-detect issue IDs in convoy create first arg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When first arg to `gt convoy create` looks like a beads issue ID (e.g., gt-abc, bd-xyz), treat all args as issues and auto-generate the convoy name from the first issue title. This prevents the bug where `gt convoy create gt-abc` would use "gt-abc" as the convoy name instead of recognizing it as an issue to track. (gt-7qyfh) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/cmd/convoy.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/internal/cmd/convoy.go b/internal/cmd/convoy.go index fbf90057..71fae9bf 100644 --- a/internal/cmd/convoy.go +++ b/internal/cmd/convoy.go @@ -27,6 +27,36 @@ func generateShortID() string { return strings.ToLower(base32.StdEncoding.EncodeToString(b)[:5]) } +// looksLikeIssueID checks if a string looks like a beads issue ID. +// Issue IDs have the format: prefix-id (e.g., gt-abc, bd-xyz, hq-123). +func looksLikeIssueID(s string) bool { + // Common beads prefixes + prefixes := []string{"gt-", "bd-", "hq-"} + for _, prefix := range prefixes { + if strings.HasPrefix(s, prefix) { + return true + } + } + // Also check for pattern: 2-3 lowercase letters followed by hyphen + // This catches custom prefixes defined in routes.jsonl + if len(s) >= 4 && s[2] == '-' || (len(s) >= 5 && s[3] == '-') { + hyphenIdx := strings.Index(s, "-") + if hyphenIdx >= 2 && hyphenIdx <= 3 { + prefix := s[:hyphenIdx] + // Check if prefix is all lowercase letters + allLower := true + for _, c := range prefix { + if c < 'a' || c > 'z' { + allLower = false + break + } + } + return allLower + } + } + return false +} + // Convoy command flags var ( convoyMolecule string @@ -171,6 +201,18 @@ func runConvoyCreate(cmd *cobra.Command, args []string) error { name := args[0] trackedIssues := args[1:] + // If first arg looks like an issue ID (has beads prefix), treat all args as issues + // and auto-generate a name from the first issue's title + if looksLikeIssueID(name) { + trackedIssues = args // All args are issue IDs + // Get the first issue's title to use as convoy name + if details := getIssueDetails(args[0]); details != nil && details.Title != "" { + name = details.Title + } else { + name = fmt.Sprintf("Tracking %s", args[0]) + } + } + townBeads, err := getTownBeadsDir() if err != nil { return err