Skip to content
Agentmart
Submit a tool

pm-tasks-linear

Linear adapter for the @llodev/pm-tasks-* family.

Skill by llodev

IndexedMIT★ 2
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/llodev-pm-tasks-linear

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Linear adapter for the @llodev/pm-tasks-* family. Use when the user mentions Linear, asks to "create Linear issue", "publish to Linear", "log to Linear", "set cycle/sprint", "check sub-issue", or uses --publish-linear; OR for CRUD on existing issues (check sub-issue, close, due-date, assign, comment, estimate, parent, sprint); OR when invoked autonomously with [autonomous] / --auto sentinel. Linear model: issue upsert via save_issue; sub-issues as hierarchy AND checklist mechanism (parentId); states by type (unstarted/ started/completed/canceled); cycles = sprints (team-gated); single assignee (set-not-add); labels are replace-set (est: idempotency read-modify-write). MCP: Linear MCP (Streamable-HTTP, OAuth, mcp__linear__ prefix). Modes: paste-ready, MCP publish, autonomous (write-through with allowlist), plan-execution. Implements 10 verbs (task.create, task.move, checklist.check, task.close, task.due-date.set, task.assignee.add, task.comment.add, task.parent.set, task.estimate.set, task.sprint.set). FIRST family adapter to implement task.sprint.set (via cycles). Requires @llodev/pm-tasks-core.

Use cases: security, writing, productivity, agent-building

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found
Runs as
Node.js package

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/pm-tasks-linear

What's inside

Skill name
pm-tasks-linear
Description
Linear adapter for the @llodev/pm-tasks-* family. Use when the user mentions Linear, asks to "create Linear issue", "publish to Linear", "log to Linear", "set cycle/sprint", "check sub-issue", or uses --publish-linear; OR for CRUD on existing issues (check sub-issue, close, due-date, assign, comment, estimate, parent, sprint); OR when invoked autonomously with [autonomous] / --auto sentinel. Linear model: issue upsert via save_issue; sub-issues as hierarchy AND checklist mechanism (parentId); states by type (unstarted/ started/completed/canceled); cycles = sprints (team-gated); single assignee (set-not-add); labels are replace-set (est: idempotency read-modify-write). MCP: Linear MCP (Streamable-HTTP, OAuth, mcp__linear__ prefix). Modes: paste-ready, MCP publish, autonomous (write-through with allowlist), plan-execution. Implements 10 verbs (task.create, task.move, checklist.check, task.close, task.due-date.set, task.assignee.add, task.comment.add, task.parent.set, task.estimate.set, task.sprint.set). FIRST family adapter to implement task.sprint.set (via cycles). Requires @llodev/pm-tasks-core.
License
MIT
Metadata
role: adapter · tool: linear · family: pm-tasks · version: 1.2.0
Instructions
264 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts
  • Instructions read files in your home folder (~/.ssh, ~/.aws…)

Agent Skills spec issues

  • description: longer than 1024 characters
  • compatibility: must be text of at most 500 characters

Files (28)

  • CHANGELOG.md
  • README.md
  • SKILL.md
  • linear.md · anti-patterns/
  • README.es-ES.md · docs/i18n/
  • README.pt-BR.md · docs/i18n/
  • en-US.json · i18n/
  • es-ES.json · i18n/
  • pt-BR.json · i18n/
  • manifest.json
  • package.json
  • autonomous.md · references/
  • estimation.md · references/
  • operations.md · references/
  • config.json · schemas/
  • adapter.ts · src/
  • init.ts · src/bin/
  • doctor-cli.ts · src/
  • index.ts · src/
  • init-flow.ts · src/
  • transport-linear.ts · src/
  • adapter.test.ts · tests/
  • doctor-cli.test.ts · tests/
  • init.smoke.test.ts · tests/
  • init.test.ts · tests/
  • transport-linear.test.ts · tests/
  • tsconfig.json
  • vitest.config.ts

SKILL.md (first lines)

# pm-tasks-linear

Linear adapter for the `@llodev/pm-tasks-*` family. Publishes generic cards as Linear issues and dispatches CRUD verbs through the Linear MCP (`mcp__linear__*` tool prefix).

## Routing

| Trigger        | Signal                                              | Path                                     |
| -------------- | --------------------------------------------------- | ---------------------------------------- |
| Paste-only     | No MCP, no `.linear.json`                           | Phase 4 only — Markdown issue body       |
| MCP publish    | Linear MCP connected + `.linear.json` present       | Phase 4 → 5 (create parent + sub-issues) |
| Autonomous     | `[autonomous]` sentinel or `--auto` flag            | Phase 5b (write-through, no preview)     |
| CRUD ops       | Verb on existing issue (`LEO-12`, UUID, or URL)     | Phase 6 — jump directly                  |
| Plan-execution | Plan file path or `--plan-exec` with `.linear.json` | Phase 7 (discover + dispatch)            |

## Linear model

Linear issues have:

- **Title** (required; aim for ≤80 chars for board readability).
- **Description** (Markdown; MCP instructions require **literal newlines** — not `\n` escape sequences).
- **State** — resolved by **type string** (`backlog`, `unstarted`, `started`, `completed`, `canceled`, `duplicate`). States are team-scoped and stored in `.linear.json`. **NEVER match by state name** — names are locale-dependent and change with team customization.
- **Sub-issues** — `save_issue` with `parentId` = parent issue id. Arbitrary depth (unlike Jira's one-level Subtask). Sub-issues are both the **hierarchy mechanism** and the **checklist mechanism** (see Phase 4).
- **Cycles** — Linear's sprint primitive. Team-gated (`config.cycles.enabled`). Resolved by name/number/id via `list_cycles`. `task.sprint.set` returns `NOT_APPLICABLE` when cycles are disabled.
- **Single assignee** — `save_issue { assignee }`. Set-not-add — Linear supports only one assignee. Accepts id, name, email, or `"me"`.
- **Labels** — **replace-set**: any label write overwrites the full label array. The transport always reads current labels, strips `est:*`, merges, and writes the complete set (read-modify-write). Never write labels without reading first.
- **Identifiers** — `TEAMKEY-N` (e.g. `LEO-1`) or UUID are interchangeable on all MCP tools.

**MCP transport:** Linear MCP at Streamable-HTTP (`https://mcp.linear.app/mcp`). The MCP handles OAuth — the adapter never sees tokens. All tools use the prefix `mcp__linear__`.

**`save_issue` upsert:** 8 of 10 verbs collapse onto `save_issue`. When `id` is present → update. When `id` is absent → create. Omitting `id` silently creates a new issue — always pass `id` on updates.

## Phase 4 — Linear formatting

Apply the generic card from core's [`../pm-tasks-core/references/generic-card.md`](../pm-tasks-core/references/generic-card.md). Then map to Linear:

- Title → issue `title`.
- Sections of the generic card → Markdown headings in `description` (literal newlines, per MCP instructions).
- Labels → resolve by name from `config.labels[]`; pass through raw strings otherwise.
- Due date → `dueDate` (YYYY-MM-DD; sliced from ISO 8601). Native Linear field; typed in the transport (`src/transport-linear.ts` `taskCreate`) — see [`references/operations.md`](references/operations.md) § Temporal handling.
- Assignee → `save_issue { assignee }` by id/name/email/`"me"`. Single-assignee set.
- Estimate → `save_issue { estimate }` (numeric points) when `estimation.enabled` and `linearTarget === "points"`.
- **Checklists → sub-issues (M3 resolution):** The core `task.create` contract carries no `items[]`. During Phase 5 MCP publish, the SKILL orchestrates child creation: for each checklist item in the generic card, call `save_issue` with `parentId` = the created parent issue's id. This is the doc-layer resolution — Linear has no native checklist, so checklist items become **sub-issues**. `checklist.check` later moves the sub-issue to a completed-type state via `save_issue { id: subIssueId, state: <completed-type-id> }`.

## Phase 5 — MCP publish

**Prerequisites:** Linear MCP connected in your agent.

- **Claude Code**: `claude mcp add linear -s project -- npx -y @linear/mcp-server` (or follow [Linear's MCP setup guide](https://linear.app/docs/mcp)), then approve the OAuth flow.
- **Cursor / Windsurf / Cline / Roo Code**: add an MCP entry pointing at `https://mcp.linear.app/mcp`.
- **Codex**: add `[mcp_servers.linear]` in `~/.codex/config.toml`.

In Claude Code, verify with `claude mcp list` — `linear` should appear as authenticated.

Strict order: 5.1 read `.linear.json` → 5.2 resolve labels/members/states → 5.3 preview & approval → 5.4 publish → 5.5 error handling.

MCP publish sequence:

1. **Config discovery** — `requireConfig` loads `.linear.json` (see § Config for lookup order). Extract `team.id`, `states[]`, `labels[]`, `members[]`.
2. **Resolve** — match label names to ids from `config.labels[]`; resolve assignee from `config.members[]` or pass-through; resolve target state from `config.states[]` by type.
3. **Preview & approval** — show title, description excerpt, labels, assignee, estimate.
4. **Publish** — `save_issue` (no id) → parent issue. Then one `save_issue` per checklist item with `parentId` = created id.
5. **Confirm** — display issue identifier (`LEO-N`) + URL and each sub-issue identifier.
6. **Error handling** — on MCP error, surface the raw error; no partial-commit guarantees (sub-issue creates are individual calls).

### Attribution (opt-in)

Before calling `save_issue`, read `config.attribution`. If `enabled === true`, append the `descriptionFooter` returned by `getAttribution()` to the end of `description`, and prefix comments with `commentPrefix`. In autonomous mode (`[autonomous]` sentinel), the `commentPrefix` automatically becomes the `autonomousCommentPrefix`. See [references/attribution.md in pm-tasks-core](../pm-tasks-core/references/attribution.md).

## Phase 5b — Autonomous

Skip 5.3 preview & approval. Apply the autonomous-mode contract from [`../pm-tasks-core/references/autonomous-mode.md`](../pm-tasks-core/references/autonomous-mode.md). Audit log entries per [`../pm-tasks-core/references/audit-log-format.md`](../pm-tasks-core/references/audit-log-format.md).

Linear-specific autonomous scope: `autonomous.scope.teams` must list the target team id from `.linear.json`. Issue state transitions must be to types reachable from the current workflow (`config.states[]` is the allowlist). See [`references/autonomous.md`](references/autonomous.md).

### Continuous operation in multi-task loops

Mandatory when the controller executes a plan with multiple tasks autonomously. Mirror each task transition on the corresponding Linear issue in real time — NEVER batch state updates at end-of-loop. See [`../pm-tasks-core/references/autonomous-mode.md`](../pm-tasks-core/references/autonomous-mode.md) § **Continuous operation across multi-task loops**.

Linear-specific verb mapping:

| Transition        | Canonical verb + MCP call(s)                                                                                                                                                        |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Task started      | `task.move` → `save_issue { id, state }` (type `started`)                                                                                                                           |
| Task completed    | `task.close` → `save_issue { id, state }` (type `completed`)                                                                                                                        |
| Sub-issue checked | `checklist.check` → `save_issue { id: subIssueId, state }` (type `completed`) (idempotent)                                                                                          |
| Task failed       | `task.comment.add` → `save_comment { issueId, body }` with failure mode + `task.assignee.add` to reassign for human escalation. Do NOT call `task.move(_, "done")` or `task.close`. |

**Close/start preserve the plan (lifecycle fidelity):** Linear auto-stamps `startedAt` when `task.move` enters a `started` state and `completedAt` when `task.close` enters a `completed` state — both are the real timestamps. Leave `dueDate` = the original plan; never overwrite it at close. No extra calls: start/close fidelity is already native. See [`references/operations.md`](references/operations.md) § Temporal handling and [`../pm-tasks-core/references/lifecycle-fidelity.md`](../pm-tasks-core/references/lifecycle-fidelity.md).

**Linear note:** `get_issue` returns current state but not the full changelog. Verify lifecycle in the Linear UI activity feed when auditing.

## Phase 6 — CRUD operations (existing issues)

For verbs other than `task.create`, jump directly to the operation.

> **MANDATORY READ:** [`references/operations.md`](references/operations.md) — full verb → MCP tool mapping, `<task-ref>` resolution, error codes, and idempotency rules.

Verb → MCP tool mapping summary:

| Core verb           | Linear MCP tool                                         | Notes                                                                                                       |
| ------------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `task.create`       | `save_issue` (no id)                                    | `title`+`team` required; `project: config.defaultProjectId` when set; sub-issues via `parentId` per Phase 5 |
| `task.move`         | `save_issue` (id + state)                               | Resolve state by type: `open`→`unstarted`, `wip`→`started`, `done`→`completed`                              |
| `checklist.check`   | `save_issue` (sub-issue id + state)                     | `req.itemId` = sub-issue id; check = type `completed`; uncheck = type `unstarted`                           |
| `task.close`        | `save_issue` (id + state)                               | Type `completed`; cancel = type `canceled`                                                                  |
| `task.due-date.set` | `save_issue` (id + dueDate)                             | `YYYY-MM-DD` sliced from ISO 8601                                                                           |
| `task.assignee.add` | `save_issue` (id + assignee)                            | Single-assignee set-not-add; accepts id/name/email/`"me"`                                                   |
| `task.comment.add`  | `save_comment` (issueId + body)                         | Markdown, literal newlines; apply attribution prefix if enabled                                             |
| `task.parent.set`   | `save_issue` (id + parentId)                            | Arbitrary depth; `null` parentId detaches                                                                   |
| `task.estimate.set` | `get_issue` (labels) → `save_issue` (estimate + labels) | Read-modify-write label merge; see § Estimation below                                                       |
| `task.sprint.set`   | `list_cycles` → `save_issue` (id + cycle)               | Team-gated; see § Sprint below                                                                              |

`<task-ref>` resolution: Linear permalink (`https://linear.app/team/issue/LEO-12`) → bare identifier (`LEO-12`) → UUID → alias from `.linear.json` `taskAliases[]`.

### Estimation (task.estimate.set detail)

> **MANDATORY READ:** [`references/estimation.md`](references/estimation.md)

Estimation records **effort** — never a calendar deadline. The request carries `{ taskId, input: EstimateInput, config: EstimationConfig }`.

From llodev/skills, MIT.

More from llodev/skills

Signals

Stars
2
Forks
0
Open issues
0
Last commit (this folder)
Aug 1, 2026 (2 months ago)
Last release
Aug 21, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

Version
1.2.0
License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from llodev

Cite this page

pm-tasks-linear skill. Agent Mart. https://agentmart.dev/skills/llodev-pm-tasks-linear (last updated 2026-10-24)