c5057c7b3735ac3688a7703f97ead937b3c7c0a6
braney
Thu Apr 23 14:24:06 2026 -0700
redmineCli: let 'create' accept tracker and status by name
The existing resolve_tracker() / resolve_status() helpers already accepted
either a name ("To Do", "QA Ready") or a numeric ID, and the list / update
subcommands wired them up. The create subcommand declared --tracker and
--status as type=int, which rejected the name forms that the redmine skill
documents as working.
Drop the type=int, route args.tracker / args.status through the resolvers
in cmd_create, and update the help text. Numeric IDs continue to work
because the resolvers pass digit strings through.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
diff --git src/utils/redmineCli src/utils/redmineCli
index 961ac747fa9..82cec7b9e51 100755
--- src/utils/redmineCli
+++ src/utils/redmineCli
@@ -572,33 +572,33 @@
def cmd_create(args):
"""Create a new Redmine ticket."""
description = read_text_input(args.description, args.description_file)
if not description:
sys.exit("Error: --description or --description-file is required")
description = strip_emoji(prepend_attribution(description))
subject = strip_emoji(args.subject)
issue_data = {
"issue": {
"project_id": args.project,
"subject": subject,
"description": description,
- "tracker_id": args.tracker,
+ "tracker_id": resolve_tracker(args.tracker),
"priority_id": args.priority,
- "status_id": args.status,
+ "status_id": resolve_status(args.status),
}
}
custom_fields = []
if args.category:
custom_fields.append({"id": CF_CATEGORY, "value": args.category})
if args.email:
custom_fields.append({"id": CF_EMAIL, "value": args.email})
if args.mlm:
custom_fields.append({"id": CF_MLM, "value": args.mlm})
if custom_fields:
issue_data["issue"]["custom_fields"] = custom_fields
if args.assigned_to:
issue_data["issue"]["assigned_to_id"] = resolve_user(args.assigned_to)
@@ -941,36 +941,36 @@
p_list.add_argument("--limit", type=int, default=25,
help="Max results (default: %(default)s)")
p_list.add_argument("--offset", type=int, default=0,
help="Pagination offset (default: %(default)s)")
p_list.add_argument("--sort", default="updated_on:desc",
help="Sort field:direction (default: %(default)s)")
# create
p_create = sub.add_parser("create", help="Create a new ticket")
p_create.add_argument("--subject", required=True, help="Ticket subject")
p_create.add_argument("--description", help="Ticket description")
p_create.add_argument("--description-file", dest="description_file",
help="Read description from file (- for stdin)")
p_create.add_argument("--project", default=DEFAULT_PROJECT,
help="Project (default: %(default)s)")
- p_create.add_argument("--tracker", type=int, default=TRACKER_MLQ,
- help="Tracker ID (default: %(default)s)")
+ p_create.add_argument("--tracker", default=TRACKER_MLQ,
+ help="Tracker name or ID (e.g. 'To Do' or 10; default: %(default)s)")
p_create.add_argument("--priority", type=int, default=PRIORITY_UNPRIORITIZED,
help="Priority ID (default: %(default)s)")
- p_create.add_argument("--status", type=int, default=STATUS_NEW,
- help="Status ID (default: %(default)s)")
+ p_create.add_argument("--status", default=STATUS_NEW,
+ help="Status name or ID (e.g. 'New' or 1; default: %(default)s)")
p_create.add_argument("--assigned-to", dest="assigned_to",
help="Assignee name or user ID")
p_create.add_argument("--category", help="MLQ Category (custom field)")
p_create.add_argument("--email", help="Sender email (custom field)")
p_create.add_argument("--mlm", help="MLM name (custom field)")
# comment
p_comment = sub.add_parser("comment", help="Add a comment to a ticket")
p_comment.add_argument("ticket_id", help="Ticket ID number")
p_comment.add_argument("--message", help="Comment text")
p_comment.add_argument("--message-file", dest="message_file",
help="Read comment from file (- for stdin)")
# update
p_update = sub.add_parser("update", help="Update ticket fields")