Skip to content

feat: add emoji reactions on issues and comments #83

@iamfj

Description

@iamfj

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions