linear-weave
v1.0.1Weave Spec Kit into Linear: pull requirements, mirror tasks.md into sub-issues, sync statuses.
Linear Weave
A Spec Kit extension that weaves the Spec Kit feature workflow into Linear.
Run /speckit-specify → plan → tasks → implement as usual and your Linear issue stays in sync automatically — requirements are pulled from Linear, tasks.md is mirrored into sub-issues, and statuses reconcile as you work. No Linear steps typed in chat.
Requires a connected Linear MCP server in your coding agent (Claude Code: /mcp, or the claude.ai connector settings).
What makes it different
- Configurable sub-issue granularity — mirror
tasks.mdas one sub-issue per task, per phase, or per user story (with the story's tasks as a checklist inside the sub-issue, plus a shared bucket for Setup/Foundational/Polish).storyuses the fewest Linear issues, which matters when you have a capped issue allocation. - A guided one-chat orchestrator (
/speckit-linear-weave-flow) — drives one feature from its Linear issue throughspecify → clarify → plan → tasksin a single chat, pausing at a review gate after each phase and isolating the heavy phases in subagents to keep context small.
Install
From the Spec Kit community catalog (once published):
specify extension add linear-weave
Or directly from this repo:
specify extension add --from https://github.com/tonydwoodhouse/spec-kit-linear-weave
Then connect the Linear MCP server in your agent and select the correct workspace (see Prerequisites).
What it automates
| Spec Kit command | Hook | Extension command | Behavior |
|---|---|---|---|
/speckit-specify | before_specify | speckit.linear-weave.pull | If the feature description references a Linear issue (URL or ENG-123-style identifier), fetches the issue + comments and uses them as the requirements source. |
/speckit-specify | after_specify | speckit.linear-weave.link | Writes a **Linear Issue**: [ENG-123](url) line into spec.md; posts the spec location/summary as a comment on the issue. |
/speckit-tasks | after_tasks | speckit.linear-weave.tasks | Posts the task breakdown on the main issue and creates sub-issues at the configured granularity (per task, per phase, or per user story with a task checklist). Each sub-issue is placed on the main issue's project so it shows on the project board (Linear does not inherit the project from the parent). Deduplicates on re-runs by matching existing sub-issue titles. |
/speckit-implement | before_implement | speckit.linear-weave.sync | Moves the main issue to In Progress and instructs the agent to move each sub-issue to Done as its task is marked [X]. |
/speckit-implement | after_implement | speckit.linear-weave.sync | Final reconciliation: completed tasks → sub-issues Done; all tasks done → main issue Done; posts a progress/summary comment. |
All hooks no-op silently for features that don't reference a Linear issue, so the plain Spec Kit workflow is unaffected. specify extension list reports Commands: 5 | Hooks: 5 — five commands, five hook bindings across the four hook-bound commands (flow adds a command but no hook).
Guided flow command (/speckit-linear-weave-flow)
Besides the hooks above, the extension ships one user-invocable orchestrator command — it is not wired to a hook, you run it directly:
/speckit-linear-weave-flow ENG-123
It drives a single feature from its Linear issue through specify → clarify → plan → tasks in one chat, pausing at a manual review gate after each phase and stopping before implement. To keep the main chat's context small, it runs the heavy phases (specify/plan/tasks) in subagents that return only a short summary, and runs clarify inline (it needs to ask you questions). Each phase's normal Linear hooks fire as usual. It requires a Linear issue ID (it asks for one if omitted) because every phase depends on the Linear hooks. It never runs /speckit-implement — finish that in a fresh chat.
Usage
/speckit-specify ENG-123 # requirements pulled from the Linear issue
/speckit-plan ... # unchanged
/speckit-tasks # main issue updated + sub-issues created
/speckit-implement # statuses tracked against tasks.md
That's it — no Linear instructions needed in chat. To run a manual re-sync at any time: /speckit-linear-weave-sync.
Configuration
Edit linear-config.yml (committed, applies to the whole team):
team— optional team key; inferred from the main issue when null.statuses.*— workflow status names to apply at each stage (null = leave unchanged). Matched case-insensitively against your team's statuses.subissues.granularity—task(one sub-issue per task),phase(one per phase with a task checklist), orstory(one per user story with a task checklist, plus oneSharedsub-issue for non-story Setup/Foundational/Polish tasks).storyuses the fewest Linear issues; it is the shipped default.comments.*— toggle the summary/progress comments.
Granularity trade-off
| Granularity | # issues | Per-task status tracking | Best for |
|---|---|---|---|
task | one per task | ✅ each task = one issue | Small features; heavy Linear reporting |
phase | one per phase | ❌ phase Done only when all its tasks [X] | Phase-oriented delivery |
story | one per story + 1 shared | ❌ story Done only when all its tasks [X] | Conserving Linear issue allocation (default) |
State
Linear is the source of truth — no local state files are kept. The only local trace is a single line the link hook writes into the feature's spec.md:
**Linear Issue**: [ENG-123](https://linear.app/...)
Everything else is derived live from Linear on each run: the task→sub-issue mapping comes from the parent-child relationship plus a title convention. That convention is load-bearing — don't rename sub-issues in a way that removes the identifying prefix, or the sync commands will lose track of them:
taskgranularity — theT001: <description>prefix (T###:).phasegranularity — the verbatim phase heading (e.g.Phase 2: Foundational).storygranularity — theUS1: <story title>prefix (US#:), plus the exactShared: Setup, Foundational & Polishtitle for non-story tasks.
Prerequisites
- A connected Linear MCP server (Claude Code:
/mcp, or the claude.ai connector settings). - Workspace scoping gotcha: the Linear MCP token is scoped to one workspace — the one chosen during OAuth. To target a different workspace you must reconnect and select it; the connector does not roam between workspaces.
list_teamsshows which workspace you're on. A dangerous symptom of being on the wrong one: asking forENG-22can silently returnPRD-22from the old workspace, because Linear matches the number within the connected workspace and ignores the prefix. Always verify withlist_teams/get_issueafter switching.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
LINEAR: feature not linked to a Linear issue — skipping | No **Linear Issue**: line in spec.md | Ensure /speckit-specify was run with an issue reference, or add the line manually / re-run /speckit-linear-weave-link. |
Sub-issues land in the wrong Linear workspace / ENG-22 resolves to PRD-22 | MCP token scoped to a different workspace | Reconnect the Linear connector and select the right workspace; verify with list_teams. |
| Sub-issues duplicated on re-run | Title prefix was changed so dedup couldn't match | Restore the T###: / US#: / phase-heading prefix; dedup relies on it. |
| Sub-issues nest under the parent but don't show on the project board | They were created without a project — Linear doesn't inherit it from the parent | Re-run /speckit-tasks (or /speckit-linear-weave-tasks); the tasks hook sets the project on new sub-issues and backfills existing ones. Confirm the main issue itself has a project. |
story/phase sub-issue won't move to Done | Not all of its tasks are [X] in tasks.md | Expected with phase/story granularity — complete the remaining tasks, or use task granularity for per-task status. |
| Linear sync skipped entirely | MCP server unavailable/unauthenticated | Reconnect via /mcp; hooks intentionally no-op so the core workflow isn't blocked. |
Disable / remove
specify extension disable linear-weave
specify extension remove linear-weave # add --keep-config to preserve linear-config.yml
Contributing
Issues and pull requests are welcome. Please open an issue at the tracker with:
- your Spec Kit version (
specify --version) and coding agent, - the extension command / hook involved, and
- what you expected vs. what happened (redact any private Linear workspace details).
For code changes:
- Test against a real Linear workspace with a dev install:
specify extension add --dev . - Keep the load-bearing sub-issue title conventions intact —
T###:(task),US#:(story), and verbatim phase headings (phase) — since the sync commands match on them. - Add an entry under an
## [Unreleased]heading inCHANGELOG.md.
By contributing you agree that your work is licensed under the project's MIT license.
License
MIT © Tony Woodhouse
Stats
Version
Install
Using the Specify CLI
specify extension add linear-weave --from https://github.com/tonydwoodhouse/spec-kit-linear-weave/archive/refs/tags/v1.0.1.zip