agentsclimarketplace

Linear manager

Skill snvtac/skills/skills/linear-manager

A curated collection of agent skills — reusable, self-contained modules that extend AI coding assistants with specialized capabilities and domain knowledge.

Install
npx -y skills add snvtac/skills --skill linear-manager

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Manage Linear tickets/comments via direct HTTP GraphQL with `python3 scripts/linear_manager.py` and token env vars only (no Linear MCP). Supports create/read/update/delete tickets and sub-tickets, issue templates, discovery commands (whoami, teams, projects), creating/moving tickets under a project, workflow status changes, team reassignment, cycle/label updates, and comment read/create/thread reply.

SKILL.md

13.4 KB, as published. Nobody here has run it

Linear Manager

Overview

Use this skill for Linear operations through https://api.linear.app/graphql only. Execution entrypoint is python3 scripts/linear_manager.py.

Capability Scope

  • Read: list, get, templates, states, children, comments
  • Discovery (for an unfamiliar/multi workspace): workspaces (all token env vars → workspace names), whoami (current user + workspace), teams (id/key/name), projects (id/name + teams)
  • Write: create, update, delete, comment
  • Sub-ticket: create --parent <ISSUE_REF>
  • Template: templates, create [--template-id|--template-name|--use-default-template]
  • Project: projects [--team-key <KEY>|--team-id <UUID>] [--name <SUBSTR>] create --project-id <UUID> or create --project-name <NAME> update --project-id <UUID> or update --project-name <NAME>
  • Team management: update --team-key <KEY> or update --team-id <UUID>
  • Status management: update --state <name> or update --state-id <uuid>
  • Cycle/label management: update --cycle-id|--cycle-name|--cycle-number update --set-labels|--add-labels|--remove-labels update --set-label-ids|--add-label-ids|--remove-label-ids

Hard Constraints

  • Always operate via HTTP script: python3 scripts/linear_manager.py.
  • Never use Linear MCP tools (mcp__linear__*) in this skill.
  • If token is missing or HTTP fails, return an error with short suggestions only.
  • Do not fallback to Linear MCP under any failure mode.

Token Policy

Default env var is LINEAR_API_TOKEN. Select a non-default token with --token-env <ENV_NAME>.

Never print or echo a token value (do not run echo "$LINEAR_API_TOKEN"). To verify a token, resolve its workspace with whoami/workspaces instead — those never expose the token string.

If the chosen token env var is missing, stop and provide suggestions only:

export LINEAR_API_TOKEN='lin_api_xxx'

Multi-Workspace Policy (Pick One, Then Lock It)

The environment may define MORE THAN ONE Linear token, because the user works across multiple workspaces (e.g. two lin_api_* tokens in .bashrc). Treat the active workspace as explicit per-session state:

  1. Discover. Run workspaces to list every Linear token env var and the workspace it maps to. Token values are never printed — only env var names, the viewer, and organization.name/urlKey.
    python3 scripts/linear_manager.py --pretty workspaces
    
  2. Ask the user to choose — by workspace name. If more than one workspace is available and the user has not already named one this session, STOP before any operation and present the choice as selectable options whose labels are the organization.name values from workspaces (e.g. "Final Round AI", "Dark Legion"). Never guess or default silently.
  3. Lock for the session, with a hard guard. Once the user picks (or only one token exists), record the corresponding --token-env AND the chosen workspace name. On EVERY subsequent command this session, pass both --token-env <ENV> and --expect-workspace <NAME>. The guard runs whoami before the command and refuses to run (exit code 3) if the token does not resolve to that workspace — so a forgotten or wrong --token-env can never silently hit another workspace. Do not switch workspaces unless the user explicitly asks.
    python3 scripts/linear_manager.py \
      --token-env PERSON_LINEAR_API_TOKEN \
      --expect-workspace "Dark Legion" \
      --show-workspace --pretty list --team-key ENG --limit 5
    
  4. Report the workspace on every operation. State which workspace each result ran against. Output is labeled with _tokenEnv, and --show-workspace adds the resolved _workspace (org name) so reports are never ambiguous.

If the user later names a different workspace explicitly, switch to its token env var (and matching --expect-workspace) and re-confirm by reporting the new workspace name.

Cross-session note: this lock lives only in the current session. A new claude session starts with no memory of the choice and MUST re-run step 1–2. The selection is intentionally never persisted, so workspaces cannot leak across sessions.

Write Safety Policy (Default Dry-Run)

create, update, delete, comment are dry-run by default. To perform real write, caller must pass --execute.

Delete has an extra safety requirement:

  1. Run dry-run first to inspect the resolved target and expected confirmation value.
  2. Re-run with both --execute and --confirm-delete <IDENTIFIER> after the user explicitly agrees.

Recommended two-step workflow:

  1. Run dry-run first and inspect payload.
  2. Run the same command with --execute to apply.

Example:

python3 scripts/linear_manager.py --pretty update --id ENG-123 --state "In Progress"
python3 scripts/linear_manager.py --pretty update --id ENG-123 --state "In Progress" --execute

Command Reference

Run from skill folder:

python3 scripts/linear_manager.py --pretty list --limit 20
python3 scripts/linear_manager.py --pretty templates --team-key ENG
python3 scripts/linear_manager.py --pretty templates \
  --team-key ENG \
  --name "Issue Templates 2025"
python3 scripts/linear_manager.py --pretty workspaces
python3 scripts/linear_manager.py --pretty whoami
python3 scripts/linear_manager.py --pretty teams --limit 100
python3 scripts/linear_manager.py --pretty teams --name core
python3 scripts/linear_manager.py --pretty projects --limit 50
python3 scripts/linear_manager.py --pretty projects --team-key ENG --limit 50
python3 scripts/linear_manager.py --pretty projects --team-key ENG --name "platform"
python3 scripts/linear_manager.py --pretty get --id ENG-123 --include-children --comments-limit 20
python3 scripts/linear_manager.py --pretty create \
  --team-key ENG \
  --title "Issue title"
python3 scripts/linear_manager.py --pretty create \
  --team-key ENG \
  --title "Issue title" \
  --description "Issue description" \
  --execute
python3 scripts/linear_manager.py --pretty create \
  --team-key ENG \
  --title "Issue title" \
  --template-name "Issue Templates 2025"
python3 scripts/linear_manager.py --pretty create \
  --team-key ENG \
  --title "Issue title" \
  --template-id <TEMPLATE_UUID> \
  --execute
python3 scripts/linear_manager.py --pretty create \
  --team-key ENG \
  --title "Issue title" \
  --use-default-template
python3 scripts/linear_manager.py --pretty create \
  --team-key ENG \
  --title "Issue title" \
  --project-name "Platform Foundation 2026"
python3 scripts/linear_manager.py --pretty create \
  --team-key ENG \
  --title "Issue title" \
  --project-id <PROJECT_UUID> \
  --execute
# --team-key/--team-id is optional when the project resolves to a single team; the team
# is derived (output then includes derivedTeam + a warning to verify it).
python3 scripts/linear_manager.py --pretty create \
  --title "Issue title" \
  --project-name "Platform Foundation 2026"
python3 scripts/linear_manager.py --pretty create \
  --team-key ENG \
  --title "Sub-ticket title" \
  --parent ENG-123 \
  --execute
python3 scripts/linear_manager.py --pretty update \
  --id ENG-123 \
  --cycle-name "Cycle 25" \
  --add-labels "TEST,bug bash"
python3 scripts/linear_manager.py --pretty update \
  --id ENG-123 \
  --cycle-name "Cycle 25" \
  --add-labels "TEST,bug bash" \
  --execute
python3 scripts/linear_manager.py --pretty update \
  --id ENG-123 \
  --description-file /tmp/issue-desc.md \
  --execute
python3 scripts/linear_manager.py --pretty update \
  --id ENG-123 \
  --team-key DEVOPS
python3 scripts/linear_manager.py --pretty update \
  --id ENG-123 \
  --team-key DEVOPS \
  --execute
python3 scripts/linear_manager.py --pretty update \
  --id ENG-123 \
  --project-name "Platform Foundation 2026" \
  --execute
python3 scripts/linear_manager.py --pretty states --team-key ENG
python3 scripts/linear_manager.py --pretty children --id ENG-123 --limit 50
python3 scripts/linear_manager.py --pretty comments --id ENG-123 --limit 20
python3 scripts/linear_manager.py --pretty comment \
  --id ENG-123 \
  --body "Progress update"
python3 scripts/linear_manager.py --pretty comment \
  --id ENG-123 \
  --body "Progress update" \
  --execute
python3 scripts/linear_manager.py --pretty comment \
  --id ENG-123 \
  --parent-comment-id <COMMENT_UUID> \
  --body "Thread reply" \
  --execute
python3 scripts/linear_manager.py --pretty delete --id ENG-123
python3 scripts/linear_manager.py --pretty delete \
  --id ENG-123 \
  --confirm-delete ENG-123 \
  --execute

Output And Exit Codes

  • Exit code 0: success
  • Exit code 1: validation/API error
  • Exit code 2: missing token env var
  • Exit code 3: --expect-workspace guard mismatch (token resolves to a different workspace)

Operational Notes

  • Prefer --pretty for readable JSON.
  • --id and --parent accept both UUID and identifier (TEAM-123).
  • templates is read-only. It lists issue templates by default and can filter by team/name.
  • Template creation is optional. If no template flag is passed to create, the command keeps the original custom-content behavior.
  • create --template-name uses a case-insensitive exact name match and must resolve to one available issue template.
  • create --title is still required, so template title values are always overridden by the CLI title.
  • CLI-provided create fields override matching template fields; fields not provided by the CLI are left for Linear to fill from the template.
  • Form-field templates are not filled by this CLI version. Dry-run warns for explicit --template-id/--template-name selections when hasFormFields=true.
  • delete --execute requires --confirm-delete to exactly match the resolved issue identifier.
  • For an unfamiliar or multi-token environment, start with workspaces (pick the workspace), then whoami (confirm user + workspace), then teams (find team keys), then projects (find project ids/names).
  • workspaces scans all candidate token env vars and does not require --token-env to be set; it never prints token values. Detection is by token VALUE prefix (lin_api_/lin_oauth_) only — never by env var name — so an unrelated secret is never sent to Linear. If a real token uses an unrecognized format, select it explicitly with --token-env.
  • Output is labeled with _tokenEnv; add --show-workspace to also include _workspace (resolved org name) at one extra API call.
  • --expect-workspace <name|urlKey> is a hard cross-workspace guard: it runs whoami first and refuses (exit 3) unless the token resolves to that workspace. It applies to all commands except workspaces, and reuses the same whoami call as --show-workspace. In a multi-token environment, pass it on every command alongside --token-env. An empty value (e.g. --expect-workspace "$UNSET") also refuses (exit 3) rather than silently skipping.
  • whoami and teams are read-only and need no arguments beyond optional teams --name/--limit.
  • projects lists workspace projects by default; --team-key|--team-id lists projects accessible to that team. It is read-only.
  • projects --name is a case-insensitive substring filter applied to the fetched page (--limit). --limit is capped at 250 (Linear's per-query complexity ceiling); to find a specific project, prefer --name, scope with --team-key/--team-id, or resolve it directly via create/update --project-name.
  • create/update accept --project-id (UUID) or --project-name. --project-name is a case-insensitive exact match scoped to the issue's team and must resolve to exactly one project.
  • --project-id is validated to be accessible to the target team; a project scoped to other teams (or with no team) is rejected before the mutation.
  • create accepts a team via --team-key/--team-id, OR derives the team from --project-id/--project-name when that project belongs to exactly one team. If the project spans multiple teams (or none), pass --team-key/--team-id explicitly. When the team is derived, the output includes derivedTeam and a warnings entry — verify it is the intended team before relying on a real create.
  • update --team-key|--team-id moves an issue to another team.
  • Do not combine a cross-team move with --state, --cycle-*, or label mutation flags; move first, then apply destination-team workflow fields in a second command.
  • For large markdown, use --description-file or --body-file.
  • Use --body-stdin for piping comment content.

Validation

Ensure no MCP call is introduced in executable script:

rg -n "mcp__linear__" skills/linear-manager/scripts/linear_manager.py

Expected result: no matches (exit code 1).

Resources

  • Script entrypoint: scripts/linear_manager.py
  • Test cases: scripts/linear_manager_test_cases.md
  • GraphQL reference: references/graphql-operations.md

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.