feat: add label commands (task 0015) #15
Reference in New Issue
Block a user
Delete Branch "task-0015-label-commands"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements
.claude/tasks/0015-label-commands.md.Summary
Adds the
labelcommand group —label list,label create,label edit,label delete— to the CLI, following the siblingissue/prcommand patterns.label list(--limit, default 500): count line +labels:block of names, with the explicit empty state.label create --name --color(optional--description): prepends#to the color, idempotent via a case-insensitive existence check (create: already_existsinstead of failing).label edit <name>/label delete <name>: resolve the positional name via the standard case-insensitive lookup,VALIDATION_ERRORwhen not found; delete is deliberately not idempotent (ADR 0010).Shared reuse: extracted
findLabel/resolveLabel/labelNotFoundintosrc/lookup.ts(reused by the existingresolveLabelIds), a flat-outputrenderObjectintosrc/render.ts, and aparseSinglePositionalhelper intosrc/flags.ts.Deviations (see the task file's Implementation Notes for the full list):
label editrequires at least one change (empty PATCH refused), mirroringissue edit.create: already_existsvscreated: okkey split and the flat top-level output shape are both spec-mandated (spec lines 342–343), not free choices.label listuses a single-page--limitfetch (readingX-Total-Count) rather than exhaustive pagination; the spec asks only for--limit.All 330 unit tests pass (8 new in
test/label.test.ts, written test-first).Review
Risk
Overall: Low
label.tsplus additive helpers; the only existing-code touch is extractinglabelNotFound, wired via one line incli.ts.Unaddressed findings
Standards:
createvscreatedoutput-key split inlabel create— kept: spec-mandated (spec lines 342–343 fix both keys), not thealready: trueshape the dependency no-ops use.renderObject(flat top-level fields) vs the siblingrenderDetail(nests under anoun:block) — kept: the label outputs are flat sibling fields per the spec, a shaperenderDetailcannot produce.Spec: none.
(The other two Standards findings — the
parsePositionalNameduplication and theLABEL_LIST_FIELDStyping style — were fixed in this diff.)