{"id":50307518,"url":"https://github.com/nicshik/linear-skills","last_synced_at":"2026-05-28T18:00:20.058Z","repository":{"id":355547974,"uuid":"1228516822","full_name":"nicshik/linear-skills","owner":"nicshik","description":"Codex skills for Linear API automation: issue status changes and Custom View queues.","archived":false,"fork":false,"pushed_at":"2026-05-22T15:01:16.000Z","size":120,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-22T20:11:51.691Z","etag":null,"topics":["automation","codex","codex-skills","graphql","issue-tracking","linear","linear-api","python"],"latest_commit_sha":null,"homepage":"https://github.com/nicshik/linear-skills#readme","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nicshik.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-04T05:15:00.000Z","updated_at":"2026-05-22T15:00:52.000Z","dependencies_parsed_at":"2026-05-22T17:03:07.623Z","dependency_job_id":null,"html_url":"https://github.com/nicshik/linear-skills","commit_stats":null,"previous_names":["nicshik/linear-skills"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/nicshik/linear-skills","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nicshik%2Flinear-skills","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nicshik%2Flinear-skills/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nicshik%2Flinear-skills/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nicshik%2Flinear-skills/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nicshik","download_url":"https://codeload.github.com/nicshik/linear-skills/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nicshik%2Flinear-skills/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33619972,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","codex","codex-skills","graphql","issue-tracking","linear","linear-api","python"],"created_at":"2026-05-28T18:00:19.163Z","updated_at":"2026-05-28T18:00:20.037Z","avatar_url":"https://github.com/nicshik.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Linear Skills\n\n[Русский](README.ru.md)\n\nCodex skills and small Python scripts for direct Linear GraphQL API workflows.\n\nThis repository is useful when the standard Linear connector is read-only, unavailable, or blocked by a tool guard, but you still need a narrow, auditable way to automate Linear actions with your own personal API key.\n\nThe repository is intentionally generic. Project-specific queues, delivery rules, issue prefixes, and \"Done\" policies should live in a separate wrapper skill or project repository.\n\n## Included Skills\n\n| Skill | Purpose |\n| --- | --- |\n| `linear-change-status` | Change a Linear issue workflow state and verify the result. |\n| `linear-comment-issue` | Add one comment to a Linear issue after reading and verifying the target issue. |\n| `linear-create-issue` | Create one Linear issue after resolving target team, status, project, and labels. |\n| `linear-delete-issue` | Soft-delete one Linear issue after reading it and passing explicit guard checks. |\n| `linear-custom-view` | Read a Linear Custom View and return its issues in manual order. |\n| `linear-custom-view-setup` | Ensure one team Custom View exists after resolving team, project, and labels. |\n| `linear-custom-view-update` | Update one existing Custom View after reading and resolving metadata. |\n| `linear-label-setup` | Ensure issue labels exist in a team, with dry-run and no-op behavior. |\n| `linear-list-issues` | Read filtered issue lists for migration, label cleanup, and metadata preflight. |\n| `linear-read-issue` | Read one Linear issue, with optional comments and relations, as a read-only fallback. |\n| `linear-relation-setup` | Ensure one related or blocking link exists between two Linear issues. |\n| `linear-update-issue` | Update one existing issue after a read-before-write check and verify the result. |\n\n## Repository Layout\n\n```text\nlinear-change-status/\n  SKILL.md\n  agents/openai.yaml\n  scripts/change_status.py\nlinear-comment-issue/\n  SKILL.md\n  agents/openai.yaml\n  scripts/comment_issue.py\nlinear-create-issue/\n  SKILL.md\n  agents/openai.yaml\n  scripts/create_issue.py\nlinear-delete-issue/\n  SKILL.md\n  agents/openai.yaml\n  scripts/delete_issue.py\nlinear-custom-view/\n  SKILL.md\n  agents/openai.yaml\n  scripts/custom_view.py\nlinear-custom-view-setup/\n  SKILL.md\n  agents/openai.yaml\n  scripts/custom_view_setup.py\nlinear-custom-view-update/\n  SKILL.md\n  agents/openai.yaml\n  scripts/custom_view_update.py\nlinear-label-setup/\n  SKILL.md\n  agents/openai.yaml\n  scripts/label_setup.py\nlinear-list-issues/\n  SKILL.md\n  agents/openai.yaml\n  scripts/list_issues.py\nlinear-read-issue/\n  SKILL.md\n  agents/openai.yaml\n  scripts/read_issue.py\nlinear-relation-setup/\n  SKILL.md\n  agents/openai.yaml\n  scripts/relation_setup.py\nlinear-update-issue/\n  SKILL.md\n  agents/openai.yaml\n  scripts/update_issue.py\nlinear_common/\n  graphql.py\ndocs/\n  codex-approvals.md\nexamples/\n  default.rules.snippet\nscripts/\n  validate.sh\n  secret_scan.sh\n  release_check.sh\n```\n\n## Requirements\n\n- Python 3.10 or newer.\n- A Linear personal API key with access to the target workspace.\n- Optional but recommended: `certifi` for reliable TLS certificate handling on macOS Python installs.\n\nInstall the optional Python dependency:\n\n```bash\npython3 -m pip install -r requirements.txt\n```\n\n## API Key Setup\n\nSet the key in your shell:\n\n```bash\nexport LINEAR_API_KEY=\u003clinear-api-key\u003e\n```\n\nOr pass a local env file:\n\n```bash\npython3 linear-custom-view/scripts/custom_view.py \u003cview-url\u003e --env-file /path/to/.env.local\n```\n\nThe env file should contain:\n\n```text\nLINEAR_API_KEY=\u003clinear-api-key\u003e\n```\n\nDo not commit real API keys. `.env` and `.env.*` are ignored by this repository.\n\n## Usage\n\nRead a Custom View queue in manual order:\n\n```bash\npython3 linear-custom-view/scripts/custom_view.py \\\n  \"https://linear.app/example/view/my-view-123abc\" \\\n  --env-file /path/to/.env.local \\\n  --limit 50\n```\n\nReturn the first actionable row and explain the view filter:\n\n```bash\npython3 linear-custom-view/scripts/custom_view.py \\\n  \"https://linear.app/example/view/my-view-123abc\" \\\n  --env-file /path/to/.env.local \\\n  --json --first --explain-filter\n```\n\nChange an issue status:\n\n```bash\npython3 linear-change-status/scripts/change_status.py LIN-123 Done \\\n  --env-file /path/to/.env.local\n```\n\nRead one issue without updating Linear:\n\n```bash\npython3 linear-read-issue/scripts/read_issue.py LIN-123 \\\n  --env-file /path/to/.env.local \\\n  --include-comments --include-relations\n```\n\nList open issues with no labels:\n\n```bash\npython3 linear-list-issues/scripts/list_issues.py \\\n  --team LIN \\\n  --project \"Example Project\" \\\n  --open-only \\\n  --without-labels \\\n  --env-file /path/to/.env.local \\\n  --json\n```\n\nCreate one issue after verifying metadata:\n\n```bash\npython3 linear-create-issue/scripts/create_issue.py \\\n  --team LIN \\\n  --project \"Example Project\" \\\n  --status Backlog \\\n  --label Idea \\\n  --optional-label Product \\\n  --assignee \"Example User\" \\\n  --parent LIN-100 \\\n  --title \"Example idea\" \\\n  --description-file /path/to/body.md \\\n  --env-file /path/to/.env.local\n```\n\nAdd one comment after verifying the target issue:\n\n```bash\npython3 linear-comment-issue/scripts/comment_issue.py LIN-123 \\\n  --body-file /path/to/comment.md \\\n  --env-file /path/to/.env.local\n```\n\nSoft-delete one issue after verifying guards:\n\n```bash\npython3 linear-delete-issue/scripts/delete_issue.py LIN-123 \\\n  --expect-status Done \\\n  --forbid-label Idea \\\n  --require-no-children \\\n  --require-no-relations \\\n  --require-no-comments \\\n  --env-file /path/to/.env.local \\\n  --dry-run \\\n  --json\n```\n\nFor live deletion, repeat the checked command without `--dry-run` and add `--confirm LIN-123`. This helper does not expose permanent deletion.\n\n### Issue target diagnostics\n\nUse stable issue keys such as `LIN-123` for read, comment, and delete targets whenever possible. If `linear-read-issue`, `linear-comment-issue`, or `linear-delete-issue` reaches Linear but cannot find the target Issue, JSON output includes `error_category=not_found`, `error_code=issue_not_found`, `lookup`, `input_kind`, and a safe `hint`.\n\nTreat `issue_not_found` as a wrong, inaccessible, or cross-workspace issue target. Do not report it as a missing `LINEAR_API_KEY` unless the helper actually returns `error_category=missing_api_key`.\n\nEnsure issue labels exist in a team:\n\n```bash\npython3 linear-label-setup/scripts/label_setup.py \\\n  --team LIN \\\n  --label \"Example label\" \\\n  --description \"Issues for the example stream\" \\\n  --env-file /path/to/.env.local \\\n  --dry-run\n```\n\nUpdate an existing issue after reading it:\n\n```bash\npython3 linear-update-issue/scripts/update_issue.py LIN-123 \\\n  --add-label \"Example label\" \\\n  --assignee \"Example User\" \\\n  --priority high \\\n  --append-description-file /path/to/addition.md \\\n  --env-file /path/to/.env.local \\\n  --dry-run\n```\n\nSet one issue's priority after reading it:\n\n```bash\npython3 linear-update-issue/scripts/update_issue.py LIN-123 \\\n  --priority high \\\n  --env-file /path/to/.env.local \\\n  --dry-run \\\n  --json\n```\n\nAccepted priority values are `none`, `no-priority`, `no_priority`, `urgent`, `high`, `medium`, `normal`, `low`, and numeric `0..4`.\n\nSet one issue's manual order after reading it:\n\n```bash\npython3 linear-update-issue/scripts/update_issue.py LIN-123 \\\n  --sort-order -199000 \\\n  --env-file /path/to/.env.local \\\n  --dry-run \\\n  --json\n```\n\nPreview a Custom View manual reordering by applying one `sortOrder` value per issue in the intended order, then run the same commands without `--dry-run` only after checking every payload. This changes Linear's workspace-wide manual order, so project-specific wrappers should build and verify the full identifier list before live updates.\n\nEnsure a Custom View exists:\n\n```bash\npython3 linear-custom-view-setup/scripts/custom_view_setup.py \\\n  --team LIN \\\n  --project \"Example Project\" \\\n  --name \"Example open work\" \\\n  --label \"Example label\" \\\n  --open-only \\\n  --env-file /path/to/.env.local \\\n  --dry-run\n```\n\nUpdate one Custom View after reading it:\n\n```bash\npython3 linear-custom-view-update/scripts/custom_view_update.py \\\n  \"Example open work\" \\\n  --team LIN \\\n  --label \"Example label\" \\\n  --status Backlog \\\n  --open-only \\\n  --env-file /path/to/.env.local \\\n  --dry-run\n```\n\nEnsure one issue relation exists:\n\n```bash\npython3 linear-relation-setup/scripts/relation_setup.py LIN-123 LIN-100 \\\n  --type related \\\n  --env-file /path/to/.env.local \\\n  --dry-run\n```\n\nTest a status transition without updating Linear:\n\n```bash\npython3 linear-change-status/scripts/change_status.py LIN-123 Done \\\n  --env-file /path/to/.env.local \\\n  --dry-run\n```\n\nPreview a batch of one-by-one status transitions:\n\n```bash\npython3 linear-change-status/scripts/change_status.py \\\n  --batch-file status_changes.tsv \\\n  --env-file /path/to/.env.local \\\n  --json\n```\n\nUse `--json` when another tool or agent should consume the output.\n\n## Project-Specific Wrappers\n\nThese skills are low-level Linear helpers:\n\n- `linear-custom-view` reads a Custom View queue and preserves manual order.\n- `linear-change-status` performs a narrow status transition and verifies it.\n- `linear-comment-issue` creates one issue comment after reading and verifying the target issue.\n- `linear-read-issue` reads one issue and optional comments or relations without updating Linear.\n- `linear-create-issue` creates one issue after resolving required metadata and verifying the created issue.\n- `linear-delete-issue` soft-deletes one issue after reading it, checking optional guards, and requiring exact confirmation for live deletion.\n- `linear-label-setup` creates missing labels only when explicitly asked, with no-op behavior for existing labels.\n- `linear-list-issues` reads scoped issue lists for metadata preflight without updating Linear.\n- `linear-update-issue` updates one existing issue after read-before-write, including optional priority or manual `sortOrder`, then verifies the result.\n- `linear-custom-view-setup` creates one missing Custom View after resolving metadata.\n- `linear-custom-view-update` updates one existing Custom View after read-before-write, then verifies the result.\n- `linear-relation-setup` creates one missing issue relation after reading both issues, then verifies the result.\n\nThey do not decide which project issue should be implemented, whether delivery is complete, or whether `Done` is appropriate. Keep those decisions in a project-specific wrapper skill or process document. The wrapper can call these scripts through stable environment variables such as `LINEAR_API_KEY`, `LINEAR_ENV_FILE`, or `--env-file`.\n\n## Codex Approvals\n\nThe scripts call the Linear API, so Codex may ask for network approval. To avoid repeated prompts while keeping the permission narrow, approve only these prefixes:\n\n```text\npython3 linear-change-status/scripts/change_status.py\npython3 linear-comment-issue/scripts/comment_issue.py\npython3 linear-create-issue/scripts/create_issue.py\npython3 linear-delete-issue/scripts/delete_issue.py\npython3 linear-custom-view/scripts/custom_view.py\npython3 linear-custom-view-setup/scripts/custom_view_setup.py\npython3 linear-custom-view-update/scripts/custom_view_update.py\npython3 linear-label-setup/scripts/label_setup.py\npython3 linear-list-issues/scripts/list_issues.py\npython3 linear-read-issue/scripts/read_issue.py\npython3 linear-relation-setup/scripts/relation_setup.py\npython3 linear-update-issue/scripts/update_issue.py\n```\n\nDo not approve broad prefixes such as `python3`.\n\nFor complete setup guidance, including how to pre-seed rules before the first run, see [`docs/codex-approvals.md`](docs/codex-approvals.md).\n\n## Safety Model\n\n- The API key is read from environment variables or local env files only.\n- The scripts never print the API key.\n- `linear-change-status` reads the issue, resolves the target state in the issue's team, updates only when needed, then verifies.\n- `linear-change-status --dry-run` resolves the transition without updating Linear.\n- `linear-custom-view` resolves direct Custom View IDs or slug IDs through `customView(id:)` before falling back to workspace view listing.\n- `linear-custom-view` preserves the view's manual order with Linear's `manual` sort.\n- `linear-read-issue` sends only read queries and never GraphQL mutations.\n- `linear-list-issues` sends only read queries and never GraphQL mutations.\n- `linear-create-issue --dry-run` resolves team, status, project, and labels without creating an issue.\n- `linear-comment-issue --dry-run` resolves the target issue without creating a comment.\n- `linear-delete-issue --dry-run` reads the target issue and guard checks without deleting it.\n- `linear-delete-issue` soft-deletes exactly one issue, requires exact `--confirm`, and does not expose permanent deletion.\n- `linear-create-issue --optional-label` skips missing optional labels while preserving required-label failures.\n- `linear-create-issue` can assign a user and parent issue after resolving both IDs; it does not create missing labels.\n- `linear-label-setup --dry-run` resolves team and labels without creating labels.\n- `linear-list-issues --without-labels` returns only issues whose `labels.nodes` list is empty.\n- `linear-list-issues --missing-label` returns issues missing at least one requested label.\n- `linear-update-issue` reads the issue before updating labels, assignee, parent, title, description, or `sortOrder`, then verifies the result.\n- `linear-update-issue --dry-run` resolves the target update without updating Linear.\n- `linear-update-issue --sort-order` changes Linear's shared manual issue order; use dry-run and full Custom View verification before live batch updates.\n- `linear-custom-view-setup --dry-run` resolves team, project, labels, and existing view state without creating a Custom View.\n- `linear-custom-view-update --dry-run` resolves Custom View metadata and filters without updating Linear.\n- `linear-custom-view-update` does not change manual issue ordering.\n- `linear-relation-setup --dry-run` reads both issues and existing relations without creating a relation.\n- `linear-relation-setup` supports `related`, `blocks`, and `blocked-by`; `blocked-by` is stored as a reversed `blocks` relation.\n- All scripts share one GraphQL client, API-key resolution, TLS setup through `certifi` when available, and token sanitization for error output.\n\n## Development\n\nCI runs on pull requests, pushes to `main`, and manual GitHub Actions dispatches. It does not call the live Linear API and does not require `LINEAR_API_KEY`; tests must use local mocks or fixtures.\n\nRun syntax checks:\n\n```bash\npython3 -m py_compile \\\n  linear-change-status/scripts/change_status.py \\\n  linear-comment-issue/scripts/comment_issue.py \\\n  linear-create-issue/scripts/create_issue.py \\\n  linear-delete-issue/scripts/delete_issue.py \\\n  linear-custom-view/scripts/custom_view.py \\\n  linear-custom-view-setup/scripts/custom_view_setup.py \\\n  linear-custom-view-update/scripts/custom_view_update.py \\\n  linear-label-setup/scripts/label_setup.py \\\n  linear-list-issues/scripts/list_issues.py \\\n  linear-read-issue/scripts/read_issue.py \\\n  linear-relation-setup/scripts/relation_setup.py \\\n  linear-update-issue/scripts/update_issue.py \\\n  linear_common/graphql.py\n```\n\nRun the local CI equivalent:\n\n```bash\nscripts/validate.sh\n```\n\nRun fixture tests only:\n\n```bash\npython3 -m unittest discover -s tests\n```\n\nRun a secret sanity check before pushing:\n\n```bash\nscripts/secret_scan.sh\n```\n\n`scripts/validate.sh` also blocks accidental project-specific or local-machine strings so this public repository stays portable.\n\nRun the local release gate after committing and pushing:\n\n```bash\nscripts/release_check.sh\n```\n\nRelease steps are documented in [`docs/release.md`](docs/release.md). Dependency updates are handled by Dependabot for GitHub Actions and Python requirements.\n\n## Contributing\n\nSee [`CONTRIBUTING.md`](CONTRIBUTING.md).\n\n## Changelog\n\nSee [`CHANGELOG.md`](CHANGELOG.md).\n\n## Security\n\nSee [`SECURITY.md`](SECURITY.md).\n\n## License\n\nMIT. See [`LICENSE`](LICENSE).\n\n## Disclaimer\n\nThis project is not affiliated with Linear. It uses Linear's public GraphQL API with a user-provided personal API key.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnicshik%2Flinear-skills","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnicshik%2Flinear-skills","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnicshik%2Flinear-skills/lists"}