Summary
Follow-up to #15. Add emoji reactions on issues and comments as subcommands within their respective domains.
API Feasibility
The Linear GraphQL API fully supports this:
reactionCreate(input) — takes emoji (string) plus one of issueId or commentId
reactionDelete(id) — removes a reaction by UUID
- Both
Issue and Comment types expose reactions: Array<Reaction> with per-reaction user field
No blockers on the API side.
Design
Reactions live inside the issues and comments domains — no standalone reactions domain.
New commands
issues react <issue> --emoji <emoji> | --shortcode <name>
issues unreact <issue> --emoji <emoji> | --shortcode <name>
comments react <comment> --emoji <emoji> | --shortcode <name>
comments unreact <comment> --emoji <emoji> | --shortcode <name>
--emoji and --shortcode are mutually exclusive — exactly one must be provided
--emoji 👍 — Unicode emoji directly
--shortcode thumbsup — shortcode name (resolved to emoji before API call)
react calls reactionCreate with the target entity ID and emoji
unreact resolves the current user's reaction UUID (via viewer + reactions list) and calls reactionDelete
Reading reactions (opt-in)
Existing read/list commands gain a --with-reactions flag:
issues read <issue> --with-reactions
comments list <issue> --with-reactions
When set, reactions are included grouped by emoji with user details:
"reactions": {
"👍": [
{ "id": "user-1", "displayName": "Alice" },
{ "id": "user-2", "displayName": "Bob" }
],
"🎉": [
{ "id": "user-3", "displayName": "Charlie" }
]
}
This is a service-layer transformation — the API returns a flat reactions array with emoji and user fields, grouped by emoji in the output. Count is implicit (array length).
Default output stays lean (no reactions) for minimal token usage.
Error handling
All reaction commands use handleCommand() and report errors through the standard JSON error output:
| Scenario |
Error message |
react but user already reacted with that emoji |
"Already reacted with emoji 👍" |
unreact but no matching reaction found |
"No reaction with emoji 👍 found for current user" |
| Invalid shortcode |
Error before API call |
Both --emoji and --shortcode provided |
Validation error |
Neither --emoji nor --shortcode provided |
Validation error |
| API failure |
Error with details |
For both react and unreact, the service pre-checks the current user's existing reactions on the target entity (via viewer + reactions list) before calling the mutation. This avoids relying on opaque API errors and provides clear, consistent error messages.
Summary
Follow-up to #15. Add emoji reactions on issues and comments as subcommands within their respective domains.
API Feasibility
The Linear GraphQL API fully supports this:
reactionCreate(input)— takesemoji(string) plus one ofissueIdorcommentIdreactionDelete(id)— removes a reaction by UUIDIssueandCommenttypes exposereactions: Array<Reaction>with per-reactionuserfieldNo blockers on the API side.
Design
Reactions live inside the
issuesandcommentsdomains — no standalonereactionsdomain.New commands
--emojiand--shortcodeare mutually exclusive — exactly one must be provided--emoji 👍— Unicode emoji directly--shortcode thumbsup— shortcode name (resolved to emoji before API call)reactcallsreactionCreatewith the target entity ID and emojiunreactresolves the current user's reaction UUID (via viewer + reactions list) and callsreactionDeleteReading reactions (opt-in)
Existing read/list commands gain a
--with-reactionsflag:When set, reactions are included grouped by emoji with user details:
This is a service-layer transformation — the API returns a flat
reactionsarray withemojianduserfields, grouped by emoji in the output. Count is implicit (array length).Default output stays lean (no reactions) for minimal token usage.
Error handling
All reaction commands use
handleCommand()and report errors through the standard JSON error output:reactbut user already reacted with that emoji"Already reacted with emoji 👍"unreactbut no matching reaction found"No reaction with emoji 👍 found for current user"--emojiand--shortcodeprovided--emojinor--shortcodeprovidedFor both
reactandunreact, the service pre-checks the current user's existing reactions on the target entity (via viewer + reactions list) before calling the mutation. This avoids relying on opaque API errors and provides clear, consistent error messages.