linearis
Drive Linear.app from the shell via the linearis CLI (JSON-only output; linear is an alias). Do not guess the command surface — the CLI documents itself, and this skill teaches the protocol, not the flags.
Preflight (reactive — branch on the CLI's own output; don't pre-run checks every turn)
- Not installed — if the shell reports command-not-found, tell the user linearis isn't installed and offer
npm install -g linearis. As a no-install fallback, prefix commands withnpx linearis@latest(adds cold-start latency and needs network per call — fallback, not default). Never silentlynpm install -g. - Auth required — any command may fail with this envelope on stderr and exit code 42:
{ "error": "AUTHENTICATION_REQUIRED", "action": "USER_ACTION_REQUIRED", "instruction": "Run 'linearis auth login' …", "exit_code": 42 }. Detect it byexit_code === 42/error === "AUTHENTICATION_REQUIRED"(not paraphrased text) and surface the CLI's owninstruction.linearis auth loginis an interactive browser flow you cannot complete — hand it to the user. - Invalid invocation — an unknown command or option, a wrong argument count, or a command group named without a subcommand fails on stderr with exit code
2:{ "error": "UNKNOWN_COMMAND", "message": "…", "suggestion": "Did you mean read?", "command": "linearis issues", "available_commands": [...], "instruction": "Run 'linearis issues usage' …", "exit_code": 2 }. Recover from the envelope, not by guessing: pick fromavailable_commands, or run theinstruction.erroris one ofUNKNOWN_COMMAND,UNKNOWN_OPTION,MISSING_ARGUMENT,MISSING_REQUIRED_OPTION,MISSING_OPTION_ARGUMENT,TOO_MANY_ARGUMENTS,MISSING_SUBCOMMAND,INVALID_USAGE. A bare group (linearis issues) is a failure, not a request for help. - Updates (advisory, never blocking) — optionally run
linearis version checkonce →{ current, latest, channel, updateAvailable }. IfupdateAvailableis true, mention it and ask the user beforenpm install -g linearis@latest, honoringchannel(don't move anextuser tolatest). npm can hang or rate-limit; on any timeout/error just proceed with the installed version. Read the plain installed version withlinearis version(JSON), not--version.
Discover, then act
- Run
linearis usageonce for the list of domains (issues, projects, cycles, …). - Run
linearis <domain> usagefor a domain's full command and flag reference before acting. - Never invent flags or subcommands —
usageis authoritative and always current.
Output
Every command prints JSON on stdout. Shape it at the source with the global --fields identifier,title,state.name and --compact — no external binary, works on Windows and fresh containers. Reach for jq only for complex reshaping, and fall back to raw JSON if jq is absent.
Invariants worth knowing (everything else lives in usage)
- IDs are forgiving: pass a UUID, team key (
ENG), issue identifier (ABC-123), or name interchangeably. Reference tickets by identifier. issues createrequires--team; some filters need a scope flag — confirm inusagerather than memorizing.- Threaded discussion lives under
issues discuss/discussions/replies/reply. The top-levelcommentsdomain is a deprecated facade (still works) — prefer theissuesdiscussion commands. Record non-trivial progress in a discussion thread and keep the description in sync on status changes. files download <url>only fetches Linear storage URLs (uploads.linear.app);files uploadreturns anassetUrlyou can embed;issues read --with-attachmentslists linked resources (PRs, docs, URLs) — references, not necessarily downloadable files.
For anything not covered here, linearis <domain> usage is the reference.