Work Items To Linear logo

Work Items To Linear

Organization
testdouble
work-items-to-linear

Turn a work-items.md file (produced by /plan-work-items) into Linear issues, one per slice, in a single target Linear team. Use when you want to publish work items as Linear issues, create implementation tickets to track in Linear, or push a broken-down plan into a Linear team. Requires a configured Linear MCP server and a target team. Reads the team's real workflow states, labels, Projects, and members and resolves every option against them before creating anything; defaults each issue to the team's initial state, unassigned, uncategorized, with no parent or Project unless you ask. Links within-file `Depends on` relationships as native Linear "blocked by" relations and annotates the source file so re-runs resume cleanly. Does not produce the work-items file itself — use plan-work-items first. Does not post to Jira — use work-items-to-jira. Does not post to GitHub — use work-items-to-issues.

Overview

Publishertestdouble
Repositoryhan
Skill namework-items-to-linear
Stars
320
Forks
26
Bundled files
3
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 3 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by testdouble on GitHub. Read the source before you install it.

Installation

Install the Work Items To Linear AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/testdouble/han/tree/main/han-linear/skills/work-items-to-linear
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/testdouble/han.git /tmp/han
mkdir -p .claude/skills
cp -r /tmp/han/han-linear/skills/work-items-to-linear .claude/skills/work-items-to-linear
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Work Items To Linear in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Work Items To Linear on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Work Items To Linear is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Project Context

  • personal config directory: !bash "${CLAUDE_PLUGIN_ROOT}/scripts/han-config-dir.sh" 2>/dev/null || echo "$HOME/.claude"
  • project .han/config.md: !cat .han/config.md 2>/dev/null || echo ""

As your first action, use the Read tool on .han/config.md inside the personal config directory path above. A read that returns no file is no personal configuration: continue silently. When that file or the project .han/config.md probe supplies content, apply it per config-rule.md, which governs precedence between the two files, relative-path resolution, and what to do with a file that reads but cannot be used.

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 user.
  • 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.
  • 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.

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 user 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.

2. Gather the run options

Read these from the arguments and conversation; do not guess defaults the user 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 --labels were given, match each against the team's labels. When categorization was not specified, present the team's real labels and let the user 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" (name that team). Ask the user to pick or correct before continuing.

4. Validate the format with evidence-based repair

Check the work-items file against the invariants in references/work-items-file-format.md and references/linear-issue-template.md:

  • Heading shape. Every slice heading matches ## <SYM-N> — <title> with an em-dash separator (already-published headings annotated as ## <SYM-N> (<LINEAR-ID>) — <title> are valid too).
  • Depends on line. Literal bold marker **Depends on.**, trailing period, None. or comma-separated SYMs.
  • Within-file blockers. Every SYM named in a Depends on line resolves to another slice in this file. A SYM that names the slice itself (self-block) or that forms a dependency cycle with other slices is a format error.
  • References block. Present whenever the slice consumes an HTTP endpoint, event payload, design frame, ADR, coding standard, or other named artifact.
  • No process artifacts. No links to iteration histories, decision logs, review findings, team findings, facilitation summaries, gap analyses, or anything under an artifacts/ subfolder that is not a contract or design reference.

When a check fails, attempt evidence-based repair. Pull evidence from the source work-items.md, the parent plan referenced in its intro, the feature spec in the same folder, sibling files in the plan folder, and the relevant repo's ADRs / coding standards / docs:

  • Malformed heading — propose the corrected shape based on surrounding text. Cite the line number.
  • Missing Depends on line — propose None. if no blockers are evident. Cite the absence.
  • Unknown-SYM, self-block, or cycle — propose the correct in-file SYM (if a typo is evident), or None., or breaking the cycle. Cite the SYM list this file defines.
  • Missing References bullet for an HTTP-consuming or UI slice — propose the contract section or design frame from the parent plan or feature spec. Cite the anchor.
  • Process-artifact link found — propose removing the link and, if the slice still needs the context, restating the decision in plain language with a Plan decisions References bullet naming the ID plus a one-sentence description. Cite the include/exclude list.

After validation, report findings in plain language. For each: (1) what is wrong — slice SYM, line reference, failing invariant; (2) the proposed fill — corrected line, new bullet, removed link; (3) the evidence — file path with line number, document section, or named source.

Then give the user three actions: Continue with fills (apply the repairs to the source work-items.md and proceed), Correct the fills (user provides the right values; apply those and proceed), or Stop (exit without creating issues). If validation passes with no findings, proceed to Step 5.

5. Show the plan for confirmation

Creating Linear issues writes to a shared system, so confirm before doing it. Present a summary and wait for an explicit yes:

  • Destination: the Linear workspace, the target team, the Project (if any), the parent (if any, and that each item becomes a sub-issue under it), the workflow state, the labels (or "none"), and the assignee (or "unassigned").
  • The issues to create: a table, in file order, of every slice that does not already carry a (<LINEAR-ID>) annotation.
SYMTitleDepends on
W-1...None
W-2...W-1

State the total count of issues to create and how many slices are being skipped because they already carry an identifier. Do not create anything until the user confirms.

6. Create one issue per slice

Walk the slices in file order. Skip any slice whose heading already carries a (<LINEAR-ID>) annotation so a re-run resumes cleanly. Creation order does not affect correctness, because dependency relations are made in Step 7 once every issue exists. For each remaining slice, call mcp__plugin_linear_linear__save_issue with:

  • team = the resolved team,
  • title = the slice title (the text after — in the heading),
  • description = the rendered slice body (Summary, Description, any notes, References, Tests, Acceptance criteria) as Markdown, passed through without conversion,
  • state, labels, assignee, parentId, project = the values resolved in Step 3, applied as chosen,
  • never blockedBy here — relations are made in Step 7.

After each successful create, capture the returned Linear identifier and rewrite that slice's heading in place from ## <SYM-N> — <title> to ## <SYM-N> (<LINEAR-ID>) — <title> using Edit, so dependencies resolve and re-runs skip it. Report each creation as created: <SYM-N> -> <LINEAR-ID>.

If a create succeeds but the heading annotation fails, stop. Report the orphaned Linear identifier so the user can annotate the heading by hand or delete the issue. Do not continue creating, and do not run the link pass — the file state is inconsistent until the user resolves it.

7. Link dependencies as native relations

Once every slice has a Linear identifier, build the SYM-to-identifier map from the annotated headings. This pass runs over the whole annotated file on every run (including identifiers carried over from a prior run), not only over newly created issues, so a link step interrupted earlier completes on the next run.

Relations are made after all issues exist because a blocked by relation needs both endpoints to exist, and file order is not guaranteed to be blocker-first.

  • Stale-annotation check. For each unique identifier in the map, confirm it resolves to an accessible issue in the team with mcp__plugin_linear_linear__get_issue. Surface any that do not resolve to the user before making any relation; never link to a missing or wrong issue.
  • Make the relations. For each slice's **Depends on.** line (skip None.), call mcp__plugin_linear_linear__save_issue on the dependent issue with blockedBy set to each blocker's identifier. Relations are append-only and de-duplicated, so a re-run does not duplicate them; no per-relation pre-read is needed.

Report each as linked: <SYM-A>(<LINEAR-A>) blocked_by <SYM-B>(<LINEAR-B>).

8. Report

Summarize: the team, the Project and parent (if any), the workflow state, the labels and assignee (or "none" / "unassigned"). List every created issue as <SYM-N> — <LINEAR-ID> with its URL, the count of native "blocked by" relations created, and any slices skipped because they already carried an identifier. If any step failed, report the error and confirm the source work-items.md annotations reflect exactly which issues were created, so the user can re-run safely.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Work Items To Linear AI skill do?

Turn a work-items.md file (produced by /plan-work-items) into Linear issues, one per slice, in a single target Linear team. Use when you want to publish work items as Linear issues, create implementation tickets to track in Linear, or push a broken-down plan into a Linear team. Requires a configured Linear MCP server and a target team. Reads the team's real workflow states, labels, Projects, and members and resolves every option against them before creating anything; defaults each issue to the team's initial state, unassigned, uncategorized, with no parent or Project unless you ask. Links w...

Why use Work Items To Linear on TypingMind?

Because you install it once and use it with any model. Work Items To Linear is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Work Items To Linear in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/testdouble/han/tree/main/han-linear/skills/work-items-to-linear. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Work Items To Linear?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Work Items To Linear?

As many as you like. As long as a model supports skills, you can use Work Items To Linear with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Work Items To Linear AI skill free?

Yes. It is published on GitHub by testdouble under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇