From gitlab-to-linear
Imports open issues from a GitLab project into Linear, preserving title, description, comments, priority, assignee, and a backlink to the original GitLab issue. Use this skill whenever the user wants to import, sync, replicate, copy, or migrate issues from GitLab to Linear. Also trigger when the user is in a git repo with a GitLab remote and asks to bring issues into Linear.
How this skill is triggered — by the user, by Claude, or both
Slash command
/gitlab-to-linear:gitlab-to-linearThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Fetches all open issues from a GitLab project via the `glab` CLI and creates corresponding issues in Linear via the `linear` CLI. Preserves title, body, non-system comments, priority, assignee, and adds a backlink to the original GitLab issue.
Fetches all open issues from a GitLab project via the glab CLI and creates corresponding issues in Linear via the linear CLI. Preserves title, body, non-system comments, priority, assignee, and adds a backlink to the original GitLab issue.
glab CLI installed and authenticated for the GitLab hostlinear CLI installed and authenticated (linear auth)When working with the linear CLI, also load the linear-cli skill — it documents every subcommand and flag, so the agent doesn't have to call --help or guess parameters.
glab auth status 2>&1
If output contains Token is expired or 401, stop and tell the user to re-authenticate:
! glab auth login --hostname <hostname>
Get <hostname> from git remote -v.
Do not continue until authentication is confirmed working.
Run git remote -v and extract the project path from the SSH or HTTPS remote URL:
[email protected]:org/repo.git → path: org/repohttps://gitlab.example.com/team/project.git → path: team/projectFor API calls, URL-encode the path (replace / with %2F):
org/repo → org%2FrepoCheck conversation context — if the Linear team and project are already known, use them. Otherwise ask:
"Which Linear team and project should I import these issues into?"
Wait for the answer before proceeding.
glab issue list --per-page 100 2>&1
If the output says there are more pages, repeat with --page 2, --page 3, etc. until all issues are collected.
For every issue ID, run these in parallel:
Full issue details:
glab issue view <id>
Comments via API (only for issues where glab issue view shows comments: N with N > 0):
glab api "projects/<url-encoded-path>/issues/<id>/notes"
From the notes response, keep only entries where "system": false. System notes are activity events ("assigned to @user", "closed by merge request", etc.) — not real comments.
Search issue labels and comment bodies (case-insensitive) for priority signals:
| Signal found | Linear priority |
|---|---|
priority: urgent, P1, urgent | 1 (Urgent) |
priority: high, P2 | 2 (High) |
priority: medium, P3 | 3 (Medium) |
priority: low, P4, low | 4 (Low) |
| Nothing found | 3 (Medium) |
Check labels first, then comment bodies. Use the highest-priority signal found.
Title: GitLab issue title, trimmed.
Description (Markdown): write to a temp file and pass via --description-file (avoids shell quoting headaches with multi-line markdown).
<GitLab issue body, if non-empty>
<For each non-system comment:>
**Comment by <author name>:**
<comment body>
**Source:** GitLab #<id> (<author_username>)
Skip the "Comment by" sections if there are no non-system comments.
Backlink: after creation, attach the original GitLab URL with linear issue link <newIssueId> <gitlab-url>.
https://<hostname>/<project-path>/-/issues/<id>Assignee: If all GitLab issues are assigned to the same person who is the current user, pass --assignee self. Otherwise omit --assignee.
For each issue, run linear issue create (one call per issue). Send all calls in a single message so they run in parallel:
linear issue create \
--team <TEAM-KEY> \
--project "<project-name>" \
--title "<title>" \
--description-file /tmp/issue-<id>.md \
--priority <1-4> \
[--assignee self] \
--no-interactive
Capture the new issue ID from each response, then run linear issue link <newId> <gitlab-url> to attach the backlink.
Print a summary table once all issues are created:
| GitLab | Linear | Title | Priority |
|---|---|---|---|
| #10 | TEAM-111 | ... | Medium |
End with: "X issues imported successfully." If any failed, list them separately.
To localize the output (other language) or hardcode site-specific defaults (a particular GitLab hostname, a fixed Linear team/project), create a wrapper skill that triggers on your context and tells the agent which overrides to apply on top of this one. The wrapper should delegate the actual procedure to this skill.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub pawelwlazlo/linear-skills --plugin gitlab-to-linear