ClaudeMods
☰
ZH-TW
● 0 人在線上 · 瀏覽 0 次
贊助提交作品
GitHub 儲存庫 · 發布者 Sarimarcus

linear-workflow

為 Claude Code 提供 Linear 工作流程:issue-next、issue-start、issue-review、issue-ship 和 issue-plan-cycle 技能由確定性的 CLI、linear-manager agent,以及在提示列上方顯示目前 issue、其他工作階段和衝突警告的外掛支援。

Sarimarcus@Sarimarcus

Sarimarcus/claude-code-plugins/tree/main/plugins/linear-workflow

已翻譯

關於這個 mod

Linear 工作流程

在 Claude Code 中處理 Linear issue,從挑選 cycle 中的下一個 issue,一直到 PR 合併。 處理過程中 Linear 會保持最新狀態,目前的 issue 一律顯示在提示列上方。

概覽

這個外掛由四個部分組成:

  • **技能(斜線指令)**把 issue 從 cycle 推進到已合併的 PR: issue-next → issue-start → (work) → issue-review → issue-ship,另外還有用來填入 cycle 的 `issue-plan-cycle。
  • CLI(`bin/linear-workflow.mjs)執行不需要判斷的 Linear 和 GitHub 步驟:取得並排序 issue、變更狀態、變更 cycle、檢查 PR。它比 LLM 更快,而且每次都給出相同答案。Claude 負責需要判斷的部分:閱讀 issue、撰寫程式碼、commit message、PR 摘要和留言。
  • agent `linear-manager 建立和編輯 issue;當 CLI 無法連到 Linear 時,它會代替 CLI 工作。
  • 外掛:即時顯示提示列上方的目前 issue,列出你的其他 Claude Code 工作階段,並在兩個工作階段發生衝突時發出警告。它與 CLI 共用程式碼(`lib/)。

Claude Code 會為外掛技能和 agent 加上命名空間,因此完整名稱是 /linear-workflow:issue-start 和 linear-workflow:linear-manager。輸入 `/issue,再從選單中選取。

快速開始

/plugin marketplace add Sarimarcus/claude-code-plugins
/plugin install linear-workflow@sarimarcus
  1. 建立 Linear personal API key(Settings → Security & access;參見 Linear's API docs),然後設定它:在 shell 設定檔加入 export LINEAR_API_KEY=lin_api_…, 或在儲存庫被 git 忽略的 .env 中加入 `LINEAR_API_KEY=。CLI 和外掛都會使用它。
  2. 選用:為 linear-manager agent 連接 [Linear's MCP server](https://linear.app/docs/mcp)(claude.ai 上的 Linear connector,或 claude mcp add --transport http linear https://mcp.linear.app/mcp)。
  3. 執行 `/linear-workflow:issue-next。

技能

`/linear-workflow:issue-next

選擇接下來要處理的內容。唯讀。在 Haiku 上執行,只會顯示 CLI 排序後的清單。

/linear-workflow:issue-next

Claude 會:

  • 取得 active cycle 中分配給你、狀態為 Todo 或 In Progress 且沒有阻塞的 issue
  • 用下一個沒有阻塞的 sub-issue 取代進行中的 epic
  • 先按優先順序,再按 milestone 日期,最後按建立時間排序,顯示前 5 個 issue 及各自的理由
  • 提供啟動第一項(Y)、另一項(ABC-140)或不啟動的選項

`/linear-workflow:issue-start <ABC-123>

開始處理 issue。

/linear-workflow:issue-start ENG-123

Claude 會:

  • 將 issue 移到 In Progress
  • 顯示 Context、Implementation 和 Scope,但不顯示 Acceptance Criteria,因為那是 reviewer 要看的內容
  • 原樣重現可執行的留言,並將它們視為 scope(較新的留言優先於描述)
  • 如果 issue 有未解決的阻塞,繼續前先詢問
  • 建立 Linear 的 issue 分支,然後立即開始工作,不等待

`/linear-workflow:issue-review [ABC-123]

送出工作供 review。絕不合併或部署。

/linear-workflow:issue-review

Claude 會:

  • 如果你在 base 分支,或在名稱指向其他 issue 的分支上,便拒絕執行
  • 對照變更檢查每條 acceptance criterion;如果有一條未達成,繼續前先詢問
  • 執行檢查(來自 .claude/linear.json,或明顯需要的檢查,例如 npm test)
  • 只提交這個 issue 的檔案(有無關檔案時先詢問),commit message 中包含 ` (ENG-123)
  • 推送分支並開啟 PR,內文寫入 `Closes ENG-123
  • 將 issue 移到 In Review,並發布完成留言

`/linear-workflow:issue-ship [ABC-123]

合併已完成 review 的 PR 並關閉 issue。

/linear-workflow:issue-ship

Claude 會:

  • 沒有 open PR、PR 是 draft、有衝突、有人要求修改、檢查失敗,或分支上的工作還沒進入 PR 時拒絕執行
  • 合併它(gh pr merge,或在本機執行 git merge --no-ff,讓 `pre-push hooks 執行)
  • 在碰觸 Linear 前,先到 GitHub 確認 PR 確實已合併
  • 將 issue 移到 Done;所有 sub-issue 完成後,再彙整 parent issue

`/linear-workflow:issue-plan-cycle

從 backlog 填入 active cycle。和 `issue-next 一樣在 Haiku 上執行。其他技能使用目前工作階段的模型,因為它們會撰寫程式碼、判斷 acceptance criteria 或執行合併。

Claude 會:

  • 按優先順序列出 active cycle 中尚未排程、沒有阻塞的 Backlog 和 Todo issue;parent 已在 cycle 中的 sub-issue 會暫時保留
  • 詢問要加入哪些 issue(all、none 或 id 清單),然後只為這些 issue 設定 cycle,不做其他變更

不帶 id 時,issue-review 和 issue-ship 依序使用目前工作階段的 issue、分支名稱,以及你在 Linear 中開始的 issue。如果 id 是猜出來的,它們會先顯示 id;`issue-ship 在合併前會要求你確認。

`linear-manager agent

CLI 不負責的工作交給它:建立 issue、把計畫拆成 sub-issue、設定 label、relation、milestone,以及搜尋(「使用 linear-manager 建立一個關於……的 bug」)。當 CLI 無法連到 Linear 時,技能也會回退到它。它遵循與 CLI 相同的規則:

  • 傳遞名稱而不是 ID(state: "In Review"、labels: ["Bug"]、`assignee: "me")
  • 讓狀態變更具備冪等性:issue 已經處於該狀態時不做任何事
  • 藉由詢問是否存在未完成的 sub-issue 來檢查 parent,而不是列出全部 sub-issue
  • 清單中絕不回傳 issue 描述,避免很長的 backlog 淹沒對話
  • 絕不編輯檔案或執行 git

CLI

技能會透過 node "\${CLAUDE_PLUGIN_ROOT}/bin/linear-workflow.mjs" <command> 呼叫 CLI。你也可以在任何儲存庫中自行執行。它在 stdout 輸出精簡 JSON,在 stderr 輸出一行摘要,說明檢查了什麼。結束碼:0 表示成功,1 表示錯誤或輸入無效,2 表示拒絕執行(需要人工處理)。

**為小型脈絡而打造。**每個技能步驟只進行一次呼叫,每次呼叫只回傳該步驟讀取的欄位。每次工具呼叫都是會重新讀取對話的模型回合,因此減少呼叫次數、縮小回傳內容是主要節省來源。start 視圖完全不包含 acceptance criteria,因此不必依賴 Claude 遵守指令來避免實作者看到它們。

| 每個技能步驟一次呼叫 | 回傳內容 | | --- | --- | | start <ABC-123> | 要處理的 issue(不含 acceptance criteria 的描述、阻塞、分支名稱、每條原樣留言)以及儲存庫狀態(分支、base、分支設定、未提交檔案) | | review [ABC-123] | 哪個 issue(參數、分支名稱或唯一一個已開始的 issue),它的 acceptance criteria,以及儲存庫狀態:base 分支、分支指向的 issue、此分支的 open PR、檢查、未提交檔案 | | ship [ABC-123] [--pr N] | 哪個 issue、合併設定,以及 PR 判定結果(格式為 pr-check) |

| 個別步驟 | 做什麼 | | --- | --- | | config | 儲存庫根目錄、目前分支及其指向的 issue(branchIssue)、解析出的 base 分支(否則使用 origin 的預設分支)、是否位於該分支、此分支的 open PR、team key、是否找到 key、.claude/linear.json | | resolve [ABC-123|123] | 要操作的 issue:先看參數,再看分支名稱,最後看你唯一一個已開始的 issue。無法判斷時以帶有 candidates 的結束程式碼 2 結束 | | issue <ABC-123> [--view start\|review] | 完整 issue(描述、解析後的 acceptanceCriteria、阻塞、sub-issue、連結、分支名稱、每條留言),或某個技能使用的檢視 | | queue [--limit N] | active cycle 中狀態為 Todo 或 In Progress 的 issue(不含 In Review、沒有阻塞),epic 會取代為下一個 sub-issue;每項都帶有 rank 和可直接顯示的 urgency(overdue 3d、ends in 5d……) | | plan-cycle [--limit N] | active cycle 中尚未排程、沒有阻塞的 backlog issue,按順序排列 | | transition <ABC-123> <state> [--comment TEXT \| --comment-file F] | 具備冪等性的狀態變更、留言、parent 彙整(使用 parent 自己的 team 狀態) | | set-cycle <n> <ABC-123>… | 將 issue 放入 cycle,不做其他變更 | | pr-check <ABC-123> [--pr N] | PR 能否合併:ready、wait(檢查執行中)或 stop,並提供理由。只有分支或標題包含 issue,或內文關閉 issue 的 PR 才會被計入;--pr 可從多個 PR 中選取一個 | | pr-merged <ABC-123> --pr N | 該 PR 是否確實落地:只有當 GitHub 表示已合併並提供 merge commit 時,結束碼才是 `0 |

全域旗標:--team KEY 覆寫 team key;--pretty 縮排 JSON;`--out FILE 將完整 JSON 寫入檔案,只輸出檔案路徑。未提交檔案清單最多顯示前 20 個,並附上總數。

排序規則是優先順序(Urgent 在前,沒有優先順序的在最後),接著是 milestone 目標日期,最後是建立時間。只有在沒有未完成 sibling 時,parent 才會彙整;任何不是 done 或 canceled 的內容都算未完成(目標是 Done 時,In Review 也算)。

外掛

── Linear ─────────────────────────────────────────────────────────
◆ ENG-2919  In Progress · High
  Core affiliate link builders
  root branch · scope: web · parent ENG-2900            Details  Hide
  sessions  ENG-2748 In Review (eng-2748)  ·  ⚠  ENG-2912 In Progress (main)
  • 提示列上方的狀態帶:目前 issue 的 id、state、priority、title、scope 和 parent。
  • Details pane(`/linear):description、sub-issue、連結、最新留言,以及 Open in Linear。
  • 只有你自己的 issue:工作階段會顯示它接手的 issue:你釘選的 issue(/linear ENG-123、輸入 /linear-workflow:issue-start ENG-123,或 Claude 根據你的話開始處理的 issue),或分支名稱中的 issue (alex/eng-2919-link-builders → ENG-2919),前提是這個工作階段自己切換到該分支。如果同一個 checkout 中的另一個即時工作階段已認領這個分支 issue,就交給那個工作階段處理;你的介面會顯示 No Linear issue found 和 sessions 列。單獨在 feature branch 上開啟的工作階段仍會接手它的 issue。
  • 其他工作階段(sessions 列):機器上每個執行這個外掛的 Claude Code 工作階段,並顯示其 issue 和 checkout(main 或 worktree 名稱)。
  • 衝突警告:當同一個 checkout 中的另一個工作階段處理不同 issue(你們共用一個分支和工作樹),或兩個工作階段處理同一個 issue 時,會顯示 toast 和紅色 ⚠。
  • 你的 issue 不會移動。 如果另一個工作階段把共用 checkout 切換到其他分支,你的工作階段會一直保留自己的 issue(`held),直到該 issue 變成 Done 或 Canceled,或是你自己的工作階段切換分支。
  • Scope drift(選用):如果有 sub-project registry,在 issue 標記的 sub-project 之外進行編輯會跳出 toast。
  • 保持最新:任何寫入 Linear 的回合結束時(技能的 transition、linear-manager agent、Linear MCP 寫入),都會重新取得 issue;其他時候則每個 pollMinutes 重新取得。狀態變更時會顯示 toast。

| /linear | 做什麼 | | --- | --- | | /linear | 開啟 Details pane | | /linear ENG-123 | 將 issue 釘選到目前工作階段。釘選會持續到這個工作階段自己切換到其他 issue 的分支 | | /linear clear | 取消釘選,重新跟隨分支 | | /linear refresh | 立即從 Linear 重新取得 | | /linear hide / `show | 隱藏或顯示狀態帶 |

需求

  • Claude Code 2.1.289 或更新版本。Mods 是較新的功能,而這是外掛建置和測試所用的版本。
  • CLI 需要 Node.js 22.18 或更新版本(它直接執行 TypeScript,不需要 build 步驟)。
  • 用於 CLI 和外掛的 Linear personal API key。
  • 選用:Linear MCP 連線,供 `linear-manager agent 使用。
  • 選用:Linear's GitHub integration,它會把 PR 連結到 issue,並在合併時推進狀態。由於狀態變更具備冪等性,這些技能有沒有它都能執行。
  • GitHub CLI `gh,lo

安裝

請先查看作者 README,確認 marketplace 與外掛名稱;指令可能隨儲存庫結構而變動。

claude plugin marketplace add Sarimarcus/claude-code-plugins
claude plugin install linear-workflow
原文 / README

Linear Workflow

Work Linear issues from Claude Code, from picking the next issue in the cycle to the merged PR. Linear stays up to date along the way, and the current issue is always shown above the prompt.

Overview

The plugin has four parts:

  • Skills (slash commands) take an issue from the cycle to a merged PR: issue-next → issue-start → (work) → issue-review → issue-ship, plus issue-plan-cycle to fill the cycle.
  • A CLI (bin/linear-workflow.mjs) runs the Linear and GitHub steps that need no judgment: fetching and ranking issues, status changes, cycle changes, PR checks. It's faster than an LLM and gives the same answer every time. Claude keeps the parts that need judgment: reading the issue, writing the code, the commit message, PR summary and comments.
  • An agent, linear-manager, creates and edits issues, and stands in for the CLI when it can't reach Linear.
  • A mod: live code that shows the current issue above the prompt, lists your other Claude Code sessions, and warns when two of them collide. It shares its code with the CLI (lib/).

Claude Code namespaces plugin skills and agents, so the full names are /linear-workflow:issue-start and linear-workflow:linear-manager. Type /issue and pick from the menu.

Quick start

/plugin marketplace add Sarimarcus/claude-code-plugins
/plugin install linear-workflow@sarimarcus
  1. Create a Linear personal API key (Settings → Security & access; see Linear's API docs) and set it: export LINEAR_API_KEY=lin_api_… in your shell profile, or a LINEAR_API_KEY= line in your repo's git-ignored .env. The CLI and the mod both use it.
  2. Optional: connect Linear's MCP server for the linear-manager agent (the Linear connector on claude.ai, or claude mcp add --transport http linear https://mcp.linear.app/mcp).
  3. Run /linear-workflow:issue-next.

Skills

/linear-workflow:issue-next

Picks what to work on next. Read-only. Runs on Haiku: it only presents the CLI's ranked list.

/linear-workflow:issue-next

Claude will:

  • Fetch the active cycle's Todo and In Progress issues that are assigned to you and unblocked
  • Replace an in-progress epic with its next unblocked sub-issue
  • Rank them by priority, then milestone date, then age, and show the top 5 with a reason for each
  • Offer to start the top one (Y), another (ABC-140), or none

/linear-workflow:issue-start <ABC-123>

Starts work on an issue.

/linear-workflow:issue-start ENG-123

Claude will:

  • Move the issue to In Progress
  • Show its Context, Implementation and Scope, but not the Acceptance Criteria, which are for the reviewer
  • Reproduce actionable comments verbatim and treat them as scope (a newer comment beats the description)
  • Ask before continuing if the issue has open blockers
  • Create Linear's branch for the issue, then start working without waiting

/linear-workflow:issue-review [ABC-123]

Puts the work up for review. Never merges or deploys.

/linear-workflow:issue-review

Claude will:

  • Refuse if you're on the base branch, or on a branch that names another issue
  • Check each acceptance criterion against the change, and ask before going on if one isn't met
  • Run your checks (from .claude/linear.json, or the obvious ones such as npm test)
  • Commit only the files for this issue (asking about unrelated ones) with (ENG-123) in the message
  • Push the branch and open a PR whose body says Closes ENG-123
  • Move the issue to In Review and post a completion comment

/linear-workflow:issue-ship [ABC-123]

Merges the reviewed PR and closes the issue.

/linear-workflow:issue-ship

Claude will:

  • Refuse when there's no open PR, it's a draft, it has conflicts, changes were requested, checks failed, or work on the branch isn't in the PR yet
  • Merge it (gh pr merge, or git merge --no-ff locally so your pre-push hooks run)
  • Check on GitHub that the PR really merged before touching Linear
  • Move the issue to Done, and roll up the parent issue once all its sub-issues are finished

/linear-workflow:issue-plan-cycle

Fills the active cycle from the backlog. Runs on Haiku, like issue-next. The other skills use your session's model, because they write code, judge acceptance criteria or merge.

Claude will:

  • List unscheduled, unblocked Backlog and Todo issues by priority, holding back sub-issues whose parent is already in the cycle
  • Ask which to add (all, none, or a list of ids), then set the cycle on those issues and change nothing else

Without an id, issue-review and issue-ship use the session's issue, then the branch name, then your issues in Linear. If the id was guessed, they show it first, and issue-ship asks you to confirm it before merging.

The linear-manager agent

Use it for what the CLI doesn't do: filing issues, splitting a plan into sub-issues, labels, relations, milestones, searches ("use linear-manager to file a bug for…"). The skills also fall back to it when the CLI can't reach Linear. It follows the same rules as the CLI:

  • passes names, not IDs (state: "In Review", labels: ["Bug"], assignee: "me")
  • makes status changes idempotent: a no-op when the issue is already in that state
  • checks a parent's sub-issues by asking whether an unfinished one exists, instead of listing them all
  • never returns issue descriptions in lists, so long backlogs don't flood your conversation
  • never edits files or runs git

The CLI

The skills call it as node "${CLAUDE_PLUGIN_ROOT}/bin/linear-workflow.mjs" <command>. You can run it yourself from any repo. It prints compact JSON on stdout and one summary line on stderr, stating what it examined. Exit codes: 0 ok, 1 error or bad input, 2 refused (needs a human).

Built for a small context. Each skill step makes one call, and each call returns only the fields that step reads. Every tool call is a model turn that re-reads the conversation, so fewer, smaller calls are the main saving. The start view doesn't contain the acceptance criteria at all, so keeping them out of the implementer's view doesn't depend on Claude following an instruction.

| One call per skill step | Returns | | --- | --- | | start <ABC-123> | The issue to work from (description without acceptance criteria, blockers, branch name, every comment verbatim) and the repo state (branch, base, branching setting, uncommitted files) | | review [ABC-123] | Which issue (argument, branch name, or your only started issue), its acceptance criteria, and the repo state: base branch, the issue the branch names, this branch's open PR, checks, uncommitted files | | ship [ABC-123] [--pr N] | Which issue, merge settings, and the PR verdict (as pr-check) |

| Single steps | What it does | | --- | --- | | config | Repo root, current branch and the issue its name points to (branchIssue), resolved base branch (baseBranch, else origin's default) and whether you're on it, this branch's open PR, team keys, whether a key was found, .claude/linear.json | | resolve [ABC-123\|123] | Which issue to act on: the argument, then the branch name, then your only started issue. Exit 2 with candidates when it can't tell | | issue <ABC-123> [--view start\|review] | The full issue (description, parsed acceptanceCriteria, blockers, sub-issues, links, branch name, every comment), or just one skill's view of it | | queue [--limit N] | The active cycle's Todo and In Progress issues (not In Review, not blocked), epics replaced by their next sub-issue, ranked, each with its rank and display-ready urgency (overdue 3d, ends in 5d…) | | plan-cycle [--limit N] | Unscheduled, unblocked backlog issues for the active cycle, ranked | | transition <ABC-123> <state> [--comment TEXT \| --comment-file F] | Idempotent status change, comment, parent roll-up (into the parent's own team states) | | set-cycle <n> <ABC-123>… | Put issues in a cycle and change nothing else | | pr-check <ABC-123> [--pr N] | Whether the issue's PR can merge: ready, wait (checks running) or stop, with reasons. Only PRs whose branch or title names the issue, or whose body closes it, count; --pr picks one of several | | pr-merged <ABC-123> --pr N | Whether that PR really landed: exit 0 only when GitHub says merged and names the merge commit |

Global flags: --team KEY overrides the team key; --pretty indents the JSON; --out FILE writes the full JSON to a file and prints only its path. Uncommitted-file lists are capped at the first 20, with the total count.

Ranking is priority (Urgent first, no priority last), then milestone target date, then age. A parent rolls up only when no sibling is unfinished, and anything not done or canceled counts as unfinished (In Review included when the target is Done).

The mod

── Linear ─────────────────────────────────────────────────────────
◆ ENG-2919  In Progress · High
  Core affiliate link builders
  root branch · scope: web · parent ENG-2900            Details  Hide
  sessions  ENG-2748 In Review (eng-2748)  ·  ⚠  ENG-2912 In Progress (main)
  • Band above the prompt: the current issue's id, state, priority, title, scope and parent.
  • Details pane (/linear): description, sub-issues, links, latest comments, and Open in Linear.
  • Only your own issue: a session shows an issue it took on: one you pinned (/linear ENG-123, typing /linear-workflow:issue-start ENG-123, or Claude starting it from your words), or the issue in a branch name (alex/eng-2919-link-builders → ENG-2919) that this session switched to itself. A branch issue that another live session in the same checkout has claimed is left to that session, and yours shows No Linear issue found and the sessions row. A lone session opened on a feature branch still picks its issue up.
  • Other sessions (sessions row): every Claude Code session on your machine that runs the plugin, with its issue and checkout (main or the worktree name).
  • Conflict warnings: a toast and a red ⚠ when another session in the same checkout is on a different issue (you share one branch and one working tree), or two sessions are on the same issue.
  • Your issue stays put. If another session switches the shared checkout to another branch, your session keeps its issue (held) until that issue is Done or Canceled, or your own session switches branches.
  • Scope drift (optional): with a sub-project registry, an edit outside the issue's labelled sub-projects raises a toast.
  • Stays current: the issue is fetched again at the end of any turn that wrote to Linear (a skill's transition, the linear-manager agent, a Linear MCP write), and every pollMinutes otherwise. A toast says when its state changed.

| /linear | What it does | | --- | --- | | /linear | Open the details pane | | /linear ENG-123 | Pin an issue to this session. The pin lasts until this session itself switches to another issue's branch | | /linear clear | Drop the pin and follow the branch again | | /linear refresh | Re-fetch from Linear now | | /linear hide / show | Hide or show the band |

Requirements

  • Claude Code 2.1.289 or later. Mods are a recent feature, and this is the version the plugin was built and tested on.
  • Node.js 22.18 or later for the CLI (it runs TypeScript directly, no build step).
  • A Linear personal API key, for the CLI and the mod.
  • Optional: a Linear MCP connection, for the linear-manager agent.
  • Optional: Linear's GitHub integration, which links PRs to issues and moves them on merge. The skills work with or without it, because their transitions are idempotent.
  • GitHub CLI gh, logged in, for issue-review and issue-ship.
  • git 2.23 or later (git switch).

Configuration

Nothing is required beyond the API key. Everything else is inferred, and each layer below overrides the one before it:

  1. Built-in defaults: GitHub flow, a branch per issue, standard Linear state names.
  2. Plugin settings (per user): the API key, team keys, polling, the session list.
  3. Project settings (.claude/linear.json, per repo, committed): states, branching, checks, merge method, issue template.
  4. Project conventions (CLAUDE.md, CONTRIBUTING.md, the PR template): the skills follow them for commit messages, PR bodies and anything else they describe.
  5. Your own skills: see Customizing.

Plugin settings

| Option | Default | Meaning | | --- | --- | --- | | linearApiKey | — | Linear API key, stored as a secret (secret options are not shown in /config). If unset: LINEAR_API_KEY in the environment, then in <repo>/.env | | teamKeys | (auto) | Team keys to find in branch names, for repos whose .claude/linear.json sets no teamKey. Else the keys of the teams you belong to. The mod passes this to the CLI too | | pinCommand | issue-start | Skill whose first argument pins an issue to the session. Empty disables it | | pollMinutes | 5 | How often the mod refreshes the issue | | showOtherSessions | true | Share this session's issue with your other sessions and list theirs | | registryFile | — | Sub-project registry for scope and drift (monorepos). Empty: off |

Project settings (.claude/linear.json)

Optional, all fields optional. A missing value is inferred, or the skill asks once. See linear.example.json.

{
  "team": "Engineering",
  "teamKey": "ENG",
  "project": "Website",
  "assignee": "me",
  "baseBranch": "main",
  "checks": ["npm run build", "npm test"],
  "mergeMethod": "squash",
  "deleteBranch": true,
  "branching": "create",
  "states": { "inProgress": "Doing", "inReview": "Ready for QA", "done": "Shipped" },
  "issueTemplate": ".github/linear-issue.md"
}

| Field | Default | Meaning | | --- | --- | --- | | team, teamKey, project, assignee | inferred | Where the skills look and file issues. teamKey also lets you type bare numbers (123) | | baseBranch | origin's default branch | Base for new branches and PRs | | checks | inferred (npm test, make test…) | Commands issue-review runs before committing | | mergeMethod | merge | merge, squash, rebase, or local (git merge --no-ff + push, so your own pre-push hooks run) | | deleteBranch | false | Delete the branch after merging | | branching | create | issue-start creates the issue's branch (create), asks (ask), or stays on the current one (none) | | states | Linear's usual names | Your team's names for In Progress, In Review and Done, used by every transition and by the queue's review filter | | issueTemplate | 4-section template | A markdown file the agent uses for new issue descriptions |

Sub-project registry (monorepos)

Set the registryFile plugin setting to a JSON file at the repo root:

{ "projects": [ { "key": "web", "path": "apps/web" }, { "key": "api", "path": "services/api" } ] }

An issue labelled web (or whose parent is) is scoped to apps/web, so editing services/api/... raises a drift toast once per issue and sub-project. An issue with no matching label is scoped to everything.

Customizing

  • Settings first. Most differences between teams (state names, branching, checks, merge method, templates) are settings above, and project conventions in CLAUDE.md take precedence over the skills' defaults.
  • Replace a skill. Copy skills/<name>/SKILL.md into your project's .claude/skills/<name>/ and edit it. Yours runs as /<name>, and the plugin's stays available as /linear-workflow:<name>. Keep calling the CLI for the deterministic steps so the checks stay the same. If you rename issue-start, set the pinCommand plugin setting to your skill's name so the band follows it.
  • Use the CLI directly. It works without the skills, in your own scripts or CI: node <plugin>/bin/linear-workflow.mjs queue.
  • Turn parts off. /linear hide hides the band; showOtherSessions: false stops the session list; leaving registryFile empty keeps scope and drift checks off.

Safety

  • issue-plan-cycle can't be started by Claude on its own. You have to type it. issue-review and issue-ship can also be invoked by Claude. When Claude does that without you asking to ship, issue-ship confirms the issue and PR with you before merging.
  • Typing issue-review or issue-ship yourself authorizes the push or merge for that issue only.
  • The skills never run git push --force, git reset --hard, git clean, git checkout -- ., git restore ., a bare git stash or git commit --amend: each can destroy work that isn't yours. Every eval checks this. The only push to the base branch is the merge itself, when issue-ship uses mergeMethod: local.
  • issue-review refuses on a branch that names another issue, so work never lands under the wrong issue.
  • issue-ship checks GitHub before writing to Linear, so a merge that failed is never reported as done.

Best practices

  • One issue per session. Several sessions work best in separate git worktrees. In a shared checkout the band warns you, but the shared tree is still shared.
  • Put the steps of the work in the issue (Context, Implementation, Scope). issue-start gives Claude those sections and leaves out the acceptance criteria.
  • Put decisions made after filing in comments, because issue-start treats them as scope.
  • Set checks in .claude/linear.json so issue-review runs exactly what your CI runs.

Privacy and data handling

  • The CLI and the mod send GraphQL queries and updates to api.linear.app with your key. They never write it to disk. When you set the key as the secret plugin option, the mod exports it as LINEAR_API_KEY to the session's shell so the CLI can use it.
  • The CLI's pr-check and the review and ship skills use the gh CLI. The agent uses your Linear MCP connection. What any of them return goes into the conversation like any tool output.
  • Session list: each session writes ~/.claude/linear-workflow/sessions/<session-id>.json (checkout path, issue id, title, state) every minute. These files stay on your machine and are deleted when the session ends, or after a day if it crashed. To turn this off, set showOtherSessions: false.

Troubleshooting

No band. It only shows when the branch names an issue or one is pinned. Check teamKeys, or pin one with /linear ENG-123. If the band says Linear API key not found, set the key (see Configuration).

The details pane doesn't open by itself. A pane the session opens on its own needs a wide terminal (about 144 columns). /linear opens it at any width.

A skill says LINEAR_API_KEY not set. Set the key (Quick start, step 1). Run node "<plugin>/bin/linear-workflow.mjs" config to see what the CLI finds.

The agent says Linear tools are missing. Connect the Linear MCP server (Quick start, step 2), then restart the session.

gh errors in issue-review or issue-ship. Run gh auth status. If the repository doesn't allow your mergeMethod, issue-ship asks which one to use.

The band shows held. Another session moved the shared branch, and yours kept its issue (until it is Done or Canceled). /linear clear follows the branch again.

Limitations

  • Single-repository workflow (one PR per issue). Multi-repo or submodule shipping isn't supported.
  • The skills follow GitHub's PR model through gh. GitLab and Bitbucket aren't supported.
  • The mod sees branch switches made through Claude Code, but not ones made in your own terminal. Use /linear clear after those.
  • The shared logic (ranking, roll-up, state matching, PR verdicts, mod helpers) has unit tests, including transitions against a fake Linear API. The skills have evals that check they follow the CLI's verdicts, run against canned CLI answers. Nothing runs end to end against a real Linear workspace or GitHub repo.

Development

claude --plugin-dir .      # from this folder: load from source, hot-reloads on save
claude plugin validate .
claude plugin test .       # unit tests (lib/ and the mod)

Dev tooling lives at the repo root, outside the plugin, so installing the plugin pulls in none of it:

npm install                # at the repo root: TypeScript and Node types
npm run typecheck          # mod + lib, then CLI + lib
npm test                   # same as claude plugin test
npm run eval               # skill evals, then writes evals/RESULTS.md

Evals (evals/) check the skills' guardrails: issue-ship stops on a missing, draft or failing PR asks when several PRs or running checks are involved, and doesn't merge on its own when Claude reaches it without being asked to ship; issue-review refuses on the base branch or another issue's branch, flags unmet acceptance criteria and never stages unrelated files; no skill ever runs a destructive git command; issue-start never stashes or discards a dirty tree, quotes actionable comments verbatim and hides acceptance criteria; issue-next keeps the CLI's order and urgency. Each case's scaffold.sh builds a git repo and canned CLI answers in .lw/; with EVAL_LINEAR_WORKFLOW_FIXTURES set, the CLI answers from there (and logs each call to calls.log) instead of calling Linear or GitHub. Granting Bash needs Claude Code's sandbox: on Linux, apt install bubblewrap socat. Each case runs 3 times, so a full run costs real tokens (about $3). The latest results are in evals/RESULTS.md: commit it with each release.

The engine generates .claude-plugin/types/ when the mod loads, and the type-check needs it. Layout: lib/ is shared code with no Node or browser APIs; hooks/ is the mod; bin/ is the CLI.

Author

Olivier Depiesse (@Sarimarcus)

Version

See CHANGELOG.md for the current version and its history. The version lives only in plugin.json (and the marketplace entry): don't write it here.

License

MIT

更多類似作品