Parent
#21 — Agent UX: state-by-name, command aliases, prep/pr-ready, list guardrail
What to build
Introduce a reusable workflow-state resolver in linear-core that maps a state reference (a UUID or a human name) to a stateId for a given team, and wire it into issues update so an issue's state can be set by name.
End-to-end behavior:
linear issues update ANN-1 --state "In Progress" sets the issue's state.
linear issues update ANN-1 --input '{"stateName":"In Progress"}' and --input '{"state":"In Progress"}' resolve the same way.
linear issues update ANN-1 --input '{"stateId":"<uuid>"}' is unchanged.
Resolution is scoped to the target issue's team (fetch the issue to read its teamId). Source precedence: explicit stateId in --input > --state flag (already a global option) > state/stateName key in --input. The state/stateName keys are stripped before the payload reaches GraphQL. On an unknown or ambiguous name, the command fails with an error listing the team's valid states as name (type).
Resolver contract: if the reference is a UUID, return it unchanged; otherwise exact case-insensitive name match; support an optional preferred type fallback (consumed by later slices). The resolver depends only on an injected "list workflow states for a team" capability so it is testable in isolation.
Acceptance criteria
Blocked by
- None - can start immediately
Parent
#21 — Agent UX: state-by-name, command aliases, prep/pr-ready, list guardrail
What to build
Introduce a reusable workflow-state resolver in
linear-corethat maps a state reference (a UUID or a human name) to astateIdfor a given team, and wire it intoissues updateso an issue's state can be set by name.End-to-end behavior:
linear issues update ANN-1 --state "In Progress"sets the issue's state.linear issues update ANN-1 --input '{"stateName":"In Progress"}'and--input '{"state":"In Progress"}'resolve the same way.linear issues update ANN-1 --input '{"stateId":"<uuid>"}'is unchanged.Resolution is scoped to the target issue's team (fetch the issue to read its
teamId). Source precedence: explicitstateIdin--input>--stateflag (already a global option) >state/stateNamekey in--input. Thestate/stateNamekeys are stripped before the payload reaches GraphQL. On an unknown or ambiguous name, the command fails with an error listing the team's valid states asname (type).Resolver contract: if the reference is a UUID, return it unchanged; otherwise exact case-insensitive
namematch; support an optional preferredtypefallback (consumed by later slices). The resolver depends only on an injected "list workflow states for a team" capability so it is testable in isolation.Acceptance criteria
issues update <id> --state "<name>"sets the issue to the matching state--input '{"stateName":"<name>"}'and--input '{"state":"<name>"}'resolve to astateId--input '{"stateId":"<uuid>"}'continues to work unchangedstate/stateNamekeys never reach GraphQLissues updatenormalization is tested (flag + JSON-key paths, stateId untouched)Blocked by