plugins/lisa/skills/linear-sync/SKILL.md
Syncs plan progress to a linked Linear Issue. Posts plan contents, progress updates, branch links, and PR links at key milestones. Use this skill throughout the plan lifecycle to keep Linear Issues in sync. The Linear counterpart of lisa:jira-sync and lisa:github-sync.
npx skillsauth add codyswanngt/lisa linear-syncInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Post milestone updates to the linked Linear Issue at key plan-lifecycle moments. This skill is the destination of the lisa:tracker-sync shim when tracker = "linear".
Reads linear.workspace, linear.teamKey from .lisa.config.json (with .local override).
Callers (planning skills, lifecycle skills) invoke this skill at:
| Milestone | What to post |
|-----------|--------------|
| Plan created | Plan contents (sections + ordered tasks) as a comment, suggest transition Backlog → Todo (label: status:ready) |
| Implementation in progress | Branch URL + first commit, suggest transition Todo → In Progress (label: status:in-progress) |
| PR ready for review | PR URL + summary, the implementation handoff comment, suggest transition In Progress → In Review (label: status:code-review) |
| PR merged | Merge SHA + deploy environment (if known), suggest transition In Review → Done (label: status:done) |
This skill suggests transitions but does not auto-transition the native Linear state field. It DOES update the status:* label set when the caller asks (the build queue is keyed off labels). Native state transitions remain a human / triage decision.
$ARGUMENTS is <IDENTIFIER> <milestone> where:
<IDENTIFIER> is the Linear Issue identifier (e.g. ENG-123). If not provided, the skill searches the active plan file for a linked Linear Issue.<milestone> is one of plan-created, implementation-in-progress, pr-ready, pr-merged.pr_url=<url> for the live pull request and merge_sha=<sha> once merged.$ARGUMENTS includes an identifier, parse it.plans/) and extract the linked Linear Issue identifier from its frontmatter.mcp__linear-server__get_issue to confirm it exists.Per the milestone, build the comment body. Include:
**Plan created** — <plan-file>)Example for plan-created:
**Plan created** — `plans/feat-X.md`
Sections:
- Phase 1: Schema doc
- Phase 2: Linear destination skills
- ...
Tasks: 7 ordered items.
Next: implementation begins. Suggested status: **Todo** (label: `status:ready`).
Call mcp__linear-server__save_comment({issueId: <id>, body: <comment>}).
When $ARGUMENTS includes pr_url=<url> for pr-ready or pr-merged, ensure the Linear Issue has a durable ticket -> PR link:
[lisa-pr-link] and include the milestone (pr-ready or pr-merged) and merge SHA when available.[lisa-pr-link] comment for the same PR URL, and update/skip it instead of appending duplicates. If comment update is unavailable, skip when an identical managed comment already exists and otherwise add exactly one replacement comment with the stable marker.The PR branch/title/body identifier is the PR -> Linear side. This phase is the required Linear -> PR side.
If the caller passes --update-label, update the status:* label set via mcp__linear-server__save_issue:
plan-created → add status:readyimplementation-in-progress → remove status:ready, add status:in-progresspr-ready → remove status:in-progress, add status:code-reviewpr-merged → remove status:code-review, add status:doneIf the requested label doesn't exist on the team, create it via mcp__linear-server__create_issue_label.
Verify exactly one status:* label remains after the update — having two simultaneously breaks the build-queue invariant.
Without --update-label, this skill posts the comment only and does NOT touch labels.
--rollup)When the caller passes --rollup, this skill derives a parent/container's status:* label from the roll-up of its children instead of acting on a leaf. A Project (the Epic equivalent) rolls up from its Issues; an Issue rolls up from its sub-Issues. This implements the Linear child-issue-status arm of the Parent status rollup (the state machine) section of the leaf-only-lifecycle rule — cite that rule, do not restate the policy.
Resolve the child set the same way lisa:linear-read-issue does — mcp__linear-server__list_issues({project: <id>}) for a Project's Issues, or mcp__linear-server__get_issue per child for an Issue's sub-Issues (via parentId). Capture each child's status:* label. If the item has no children it is a leaf — rollup is N/A; behave as a normal milestone sync.
Evaluate the required children over the env ladder in-progress < dev < staging < production (the ordered keys of the Linear env-keyed done map, e.g. status:on-dev < status:on-stg < status:done) and take the first match (canonical roles from config-resolution; Linear label map is status:blocked, status:in-progress, status:code-review, env-keyed done):
| If among the required child leaves… | Derived parent role | Linear label |
|---|---|---|
| any child carries status:blocked | blocked | status:blocked |
| else every required child has shipped to some env (each at a done-map label, e.g. status:on-dev/status:on-stg/status:done) | done[min-env] | the least-advanced env label among them (all status:on-stg → status:on-stg; mixed dev+staging → status:on-dev; all production → status:done) |
| else any child has started (status:in-progress / status:code-review, or shipped to an env while a sibling has not) | claimed | status:in-progress |
| else (children exist, none started) | — | unchanged — parent keeps its non-ready container label |
status:blocked on the parent even while siblings progress.state to Done) fires only when the resolved env is the production status:done, never at status:on-dev/status:on-stg.Canceled) children do not hold the parent open.status:ready — ready is leaf-only. Rollup only moves the parent between non-ready container labels.Single-environment collapse (this repo). The env rungs resolve via the env-keyed done logic in config-resolution. In this repo deploy.branches declares only production: main, so done collapses to the single status:done label, the only env rung is production, and the lifecycle is status:ready → status:in-progress → status:code-review → status:done with no dev/staging promotion hops; the rollup never resolves a dev or staging done. Multi-environment projects keep the env-keyed map and roll a parent up to intermediate env labels (status:on-dev/status:on-stg).
Apply the derived label via mcp__linear-server__save_issue (Project or Issue), removing the parent's existing status:* and adding the derived one so exactly one status:* label remains. Post an idempotent rollup comment naming the derived state and the child tally. The native Linear state is not auto-transitioned — only the status:* label, mirroring the --update-label rule. Safe default: if the derived terminal cannot be resolved (ambiguous required-set or unresolvable env done), do not guess — post the derived suggestion as a comment and leave the parent's label untouched.
state — only the label, and only when the caller explicitly asks (--update-label, or --rollup for parent derivation per the leaf-only-lifecycle rule).status:* label from its children and never sets a parent to status:ready. It cites the leaf-only-lifecycle rule by slug rather than restating the state machine.save_comment fails, retry once. If it fails again, surface the error.pr_url=<url> is present: native first, managed-comment fallback, never silently dropped.development
Use Expo DOM components to run web code in a webview on native and as-is on web. Migrate web code to native incrementally.
development
Guidelines for upgrading Expo SDK versions and fixing dependency issues
development
Use when implementing or debugging ANY network request, API call, or data fetching. Covers fetch API, React Query, SWR, error handling, caching, offline support, and Expo Router data loaders (`useLoaderData`).
tools
`@expo/ui/swift-ui` package lets you use SwiftUI Views and modifiers in your app.