feat(update): add --type flag to bd update command (GH#522)

Allow changing an issue type (bug, feature, task, epic, chore) via the
bd update command. The storage layer already supported issue_type in
allowedUpdateFields, this just exposes it through the CLI.

Changes:
- Add --type/-t flag to updateCmd in show.go
- Add IssueType field to UpdateArgs in protocol.go
- Handle issue_type in updatesFromArgs in server_issues_epics.go
- Add validation using ParseIssueType before update

Example usage:
  bd update ab-xyz --type epic

Fixes: #522
This commit is contained in:
Steve Yegge
2025-12-16 01:08:11 -08:00
parent 0dd8914619
commit 7d35ced5ae
5 changed files with 243 additions and 207 deletions

2
.beads/.gitignore vendored
View File

@@ -30,3 +30,5 @@ beads.right.meta.json
!issues.jsonl
!metadata.json
!config.json
deletions.jsonl
deletions.jsonl.migrated

File diff suppressed because one or more lines are too long

View File

@@ -526,6 +526,15 @@ var updateCmd = &cobra.Command{
setLabels, _ := cmd.Flags().GetStringSlice("set-labels")
updates["set_labels"] = setLabels
}
if cmd.Flags().Changed("type") {
issueType, _ := cmd.Flags().GetString("type")
// Validate issue type
if _, err := validation.ParseIssueType(issueType); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
updates["issue_type"] = issueType
}
if len(updates) == 0 {
fmt.Println("No updates specified")
@@ -606,6 +615,9 @@ var updateCmd = &cobra.Command{
if setLabels, ok := updates["set_labels"].([]string); ok {
updateArgs.SetLabels = setLabels
}
if issueType, ok := updates["issue_type"].(string); ok {
updateArgs.IssueType = &issueType
}
resp, err := daemonClient.Update(updateArgs)
if err != nil {
@@ -1019,6 +1031,7 @@ func init() {
updateCmd.Flags().StringP("status", "s", "", "New status")
registerPriorityFlag(updateCmd, "")
updateCmd.Flags().String("title", "", "New title")
updateCmd.Flags().StringP("type", "t", "", "New type (bug|feature|task|epic|chore)")
registerCommonIssueFlags(updateCmd)
updateCmd.Flags().String("notes", "", "Additional notes")
updateCmd.Flags().String("acceptance-criteria", "", "DEPRECATED: use --acceptance")

View File

@@ -87,6 +87,7 @@ type UpdateArgs struct {
Assignee *string `json:"assignee,omitempty"`
ExternalRef *string `json:"external_ref,omitempty"` // Link to external issue trackers
EstimatedMinutes *int `json:"estimated_minutes,omitempty"` // Time estimate in minutes
IssueType *string `json:"issue_type,omitempty"` // Issue type (bug, feature, task, epic, chore)
AddLabels []string `json:"add_labels,omitempty"`
RemoveLabels []string `json:"remove_labels,omitempty"`
SetLabels []string `json:"set_labels,omitempty"`

View File

@@ -73,6 +73,9 @@ func updatesFromArgs(a UpdateArgs) map[string]interface{} {
if a.EstimatedMinutes != nil {
u["estimated_minutes"] = *a.EstimatedMinutes
}
if a.IssueType != nil {
u["issue_type"] = *a.IssueType
}
return u
}