Skip to main content
ClaudeWave
Skill82 repo starsupdated today

work-items-to-linear

# work-items-to-linear This Claude Code skill converts a structured work-items.md file into Linear issues within a single target team. It validates the markdown format, resolves dependencies between work slices, confirms team membership and workflow states against the live Linear workspace, creates one issue per slice with required reference artifacts attached, and establishes native "blocked by" relations for documented dependencies. Use this after breaking down work with /plan-work-items to publish slices directly into Linear for team execution.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/testdouble/han /tmp/work-items-to-linear && cp -r /tmp/work-items-to-linear/han-linear/skills/work-items-to-linear ~/.claude/skills/work-items-to-linear
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Work Items to Linear Issues

Take an already-broken-down `work-items.md` file (produced by `/plan-work-items`) and publish each slice as a Linear issue in a single target team.

The breakdown work — drafting slices, assigning symbolic IDs, specifying dependencies, inventorying references — has already been done upstream. This skill validates the format, confirms the target against the live team, creates one issue per slice through the Linear MCP server, links the within-file dependencies as native "blocked by" relations, and reports.

## Rules

- **Every slice posts into one Linear team.** This skill does not split work across teams or repos. A `work-items.md` that names multiple code repos still produces issues in the single team you name; the repo prose is informational only.
- **Dependencies are within-file only.** Every SYM named in a `Depends on` line must resolve to another slice in the same file. A `Depends on` that names an unknown SYM, names the slice itself, or forms a cycle is a format error to surface for repair, never published.
- **Symbolic-ID prefixes:** accept whatever the input uses. Any uppercase prefix shape is valid (`W-N`, `V2-N`, `EV-N`, ...); the prefix has no effect on team placement.
- **Resolve against the live team before writing.** Read the team's real workflow states, labels, Projects, and members, and resolve every named option against them before creating any issue. Nothing is assigned, categorized, grouped, or moved unless asked.
- **No issue types.** Linear has no issue-type concept. The skill never asks for or sets one. Categorization is via the team's real labels, chosen by the operator.
- **Every slice issue MUST carry the reference artifacts an implementer needs** — API/event contracts, design references, schema docs, runbooks, ADRs, coding standards. Full include/exclude list in [references/reference-artifact-inventory.md](references/reference-artifact-inventory.md).
- **NEVER include process artifacts in issue descriptions.** Excluded: iteration histories, decision logs, review findings, team findings, facilitation summaries, gap analyses, and anything under an `artifacts/` subfolder of the plan that is not a contract or design reference.
- **No image upload or embedding.** Design references are carried as links, not uploaded into Linear. See [references/linear-issue-template.md](references/linear-issue-template.md).

## Process

### 0. Linear MCP preflight (hard requirement)

This skill cannot run without a configured and connected Linear MCP server. Confirm it is reachable by calling `mcp__plugin_linear_linear__list_teams`. If the tool is unavailable, the call errors, or no workspace is accessible, **stop immediately** and tell the operator the skill requires the Linear MCP server to be installed, configured, and authenticated. Do not fall back to any other publishing target.

If the integration exposes more than one Linear workspace, note which are available and confirm which one to use before resolving the team.

### 1. Locate the work-items file

If the path is not provided, ask for it. The input is a single `work-items.md` produced by `/plan-work-items`. Read it. Its format is described in [references/work-items-file-format.md](references/work-items-file-format.md).

### 2. Gather the run options

Read these from the arguments and conversation; do not guess defaults the operator did not ask for:

- **Target team** — `--team <name or key>`. **Required.** If absent, ask for it in Step 3.
- **Project** — `--project <name or ID>`. Optional. Groups every created issue under a Linear Project.
- **Parent** — `--parent <issue id>`. Optional. Nests every created issue as a sub-issue under the named parent.
- **State** — `--state <name>`. Optional; defaults to the team's initial/default workflow state.
- **Labels** — `--label <name>`, repeatable. Optional; resolved against the team's real labels.
- **Assignee** — `--assignee <name/email/me>`. Optional; defaults to unassigned.

### 3. Resolve the target against the live team

Resolve everything concretely now so failures surface before any issue is created. This is a strict, fail-before-write sequence:

- **Team (required).** Confirm the named team with `mcp__plugin_linear_linear__list_teams`. If none is named, ask. If the name matches more than one team, present the matches and ask which one. Do not proceed without exactly one team.
- **Read the team's configuration** with `mcp__plugin_linear_linear__list_issue_statuses`, `mcp__plugin_linear_linear__list_issue_labels`, and `mcp__plugin_linear_linear__list_users`. These reads are independent and may run together.
- **State.** If `--state` was given, match it against the team's real states. The default is the team's initial/default state. If a named state does not exist, present the team's real states and ask.
- **Labels.** If `--label`s were given, match each against the team's labels. When categorization was not specified, present the team's real labels and let the operator choose one, several, or none. If the team defines no labels, say so and proceed without categorization.
- **Assignee.** If named, resolve it with `mcp__plugin_linear_linear__get_user`: the literal token `me` resolves to the authenticated Linear identity, and a name or email resolves to that member. If unset, leave issues unassigned. The creator is recorded automatically by Linear as the authenticated user; never set it.
- **Project (optional).** Resolve a named Project at **workspace scope** with `mcp__plugin_linear_linear__list_projects` (Projects are not strictly team-scoped), and confirm the target team participates in it.
- **Parent (optional).** Resolve a named parent issue with `mcp__plugin_linear_linear__get_issue` and confirm it belongs to the target team.

For any option that cannot be resolved, do not silently drop or invent it. Distinguish "no such option exists in the team" (present the team's real options for that field) from "it exists but belongs to a different team