[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CAJFH5VSJAXRGQPA2F5F5F":3,"skill-same:01M6CAJFH5VSJAXRGQPA2F5F5F":99},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":40,"linkOnly":41,"markdownContent":42,"markdownBody":43,"frontMatter":44,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":6,"ownerHtmlUrl":65,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":66,"install":67,"resources":80},"01M6CAJFH5VSJAXRGQPA2F5F5F","linear",null,"Linear: manage issues, projects, teams via GraphQL + curl.","jleechanorg\u002Fjleechan-skills","jleechanorg","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F221404966?v=4","01M6C1VJ99XG950X1DWPEBCBGX","01M6C1VJDK5YVDNT3362RT5WSB",6,"MIT","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Fproductivity\u002Flinear\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",[5,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],"api","via","project","manage","management","curl","hermes agent","hermes","projects","macos","GraphQL","productivity","issues","project management","teams","windows","linux","2026-11-10 10:12:30",false,"---\nname: linear\ndescription: \"Linear: manage issues, projects, teams via GraphQL + curl.\"\nversion: 1.0.0\nauthor: Hermes Agent\nlicense: MIT\nplatforms: [linux, macos, windows]\nprerequisites:\n  env_vars: [LINEAR_API_KEY]\n  commands: [curl]\nmetadata:\n  hermes:\n    tags: [Linear, Project Management, Issues, GraphQL, API, Productivity]\n---\n\n# Linear — Issue & Project Management\n\nManage Linear issues, projects, and teams directly via the GraphQL API using `curl`. No MCP server, no OAuth flow, no extra dependencies.\n\n## Setup\n\n1. Get a personal API key from **Linear Settings > Account > Security & access > Personal API keys** (URL: https:\u002F\u002Flinear.app\u002Fsettings\u002Faccount\u002Fsecurity). Note: the org-level *Settings > API* page only shows OAuth apps and workspace-member keys, not personal keys.\n2. Set `LINEAR_API_KEY` in your environment (via `hermes setup` or your env config)\n\n## API Basics\n\n- **Endpoint:** `https:\u002F\u002Fapi.linear.app\u002Fgraphql` (POST)\n- **Auth header:** `Authorization: $LINEAR_API_KEY` (no \"Bearer\" prefix for API keys)\n- **All requests are POST** with `Content-Type: application\u002Fjson`\n- **Both UUIDs and short identifiers** (e.g., `ENG-123`) work for `issue(id:)`\n\nBase curl pattern:\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ viewer { id name } }\"}' | python3 -m json.tool\n```\n\n## Python helper script (ergonomic alternative)\n\nFor faster one-liners that don't need hand-written GraphQL, this skill ships a stdlib Python CLI at `scripts\u002Flinear_api.py`. Zero dependencies. Same auth (reads `LINEAR_API_KEY`).\n\n```bash\nSCRIPT=$(dirname \"$(find ~\u002F.hermes -path '*skills\u002Fproductivity\u002Flinear\u002Fscripts\u002Flinear_api.py' 2>\u002Fdev\u002Fnull | head -1)\")\u002Flinear_api.py\n\npython3 \"$SCRIPT\" whoami\npython3 \"$SCRIPT\" list-teams\npython3 \"$SCRIPT\" get-issue ENG-42\npython3 \"$SCRIPT\" get-document 38359beef67c      # fetch a doc by slugId from the URL\npython3 \"$SCRIPT\" raw 'query { viewer { name } }'\n```\n\nAll subcommands: `whoami`, `list-teams`, `list-projects`, `list-states`, `list-issues`, `get-issue`, `search-issues`, `create-issue`, `update-issue`, `update-status`, `add-comment`, `list-documents`, `get-document`, `search-documents`, `raw`. Run with `--help` for flags.\n\nUse the script when: you want a quick answer without crafting GraphQL. Use curl when: you need a query the script doesn't wrap, or you want to compose filters inline.\n\n## Workflow States\n\nLinear uses `WorkflowState` objects with a `type` field. **6 state types:**\n\n| Type | Description |\n|------|-------------|\n| `triage` | Incoming issues needing review |\n| `backlog` | Acknowledged but not yet planned |\n| `unstarted` | Planned\u002Fready but not started |\n| `started` | Actively being worked on |\n| `completed` | Done |\n| `canceled` | Won't do |\n\nEach team has its own named states (e.g., \"In Progress\" is type `started`). To change an issue's status, you need the `stateId` (UUID) of the target state — query workflow states first.\n\n**Priority values:** 0 = None, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low\n\n## Common Queries\n\n### Get current user\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ viewer { id name email } }\"}' | python3 -m json.tool\n```\n\n### List teams\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ teams { nodes { id name key } } }\"}' | python3 -m json.tool\n```\n\n### List workflow states for a team\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ workflowStates(filter: { team: { key: { eq: \\\"ENG\\\" } } }) { nodes { id name type } } }\"}' | python3 -m json.tool\n```\n\n### List issues (first 20)\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issues(first: 20) { nodes { identifier title priority state { name type } assignee { name } team { key } url } pageInfo { hasNextPage endCursor } } }\"}' | python3 -m json.tool\n```\n\n### List my assigned issues\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ viewer { assignedIssues(first: 25) { nodes { identifier title state { name type } priority url } } } }\"}' | python3 -m json.tool\n```\n\n### Get a single issue (by identifier like ENG-123)\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issue(id: \\\"ENG-123\\\") { id identifier title description priority state { id name type } assignee { id name } team { key } project { name } labels { nodes { name } } comments { nodes { body user { name } createdAt } } url } }\"}' | python3 -m json.tool\n```\n\n### Search issues by text\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issueSearch(query: \\\"bug login\\\", first: 10) { nodes { identifier title state { name } assignee { name } url } } }\"}' | python3 -m json.tool\n```\n\n### Filter issues by state type\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issues(filter: { state: { type: { in: [\\\"started\\\"] } } }, first: 20) { nodes { identifier title state { name } assignee { name } } } }\"}' | python3 -m json.tool\n```\n\n### Filter by team and assignee\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issues(filter: { team: { key: { eq: \\\"ENG\\\" } }, assignee: { email: { eq: \\\"user@example.com\\\" } } }, first: 20) { nodes { identifier title state { name } priority } } }\"}' | python3 -m json.tool\n```\n\n### List projects\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ projects(first: 20) { nodes { id name description progress lead { name } teams { nodes { key } } url } } }\"}' | python3 -m json.tool\n```\n\n### List team members\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ users { nodes { id name email active } } }\"}' | python3 -m json.tool\n```\n\n### List labels\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issueLabels { nodes { id name color } } }\"}' | python3 -m json.tool\n```\n\n## Common Mutations\n\n### Create an issue\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"query\": \"mutation($input: IssueCreateInput!) { issueCreate(input: $input) { success issue { id identifier title url } } }\",\n    \"variables\": {\n      \"input\": {\n        \"teamId\": \"TEAM_UUID\",\n        \"title\": \"Fix login bug\",\n        \"description\": \"Users cannot login with SSO\",\n        \"priority\": 2\n      }\n    }\n  }' | python3 -m json.tool\n```\n\n### Update issue status\nFirst get the target state UUID from the workflow states query above, then:\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { stateId: \\\"STATE_UUID\\\" }) { success issue { identifier state { name type } } } }\"}' | python3 -m json.tool\n```\n\n### Assign an issue\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { assigneeId: \\\"USER_UUID\\\" }) { success issue { identifier assignee { name } } } }\"}' | python3 -m json.tool\n```\n\n### Set priority\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { priority: 1 }) { success issue { identifier priority } } }\"}' | python3 -m json.tool\n```\n\n### Add a comment\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { commentCreate(input: { issueId: \\\"ISSUE_UUID\\\", body: \\\"Investigated. Root cause is X.\\\" }) { success comment { id body } } }\"}' | python3 -m json.tool\n```\n\n### Set due date\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { dueDate: \\\"2026-04-01\\\" }) { success issue { identifier dueDate } } }\"}' | python3 -m json.tool\n```\n\n### Add labels to an issue\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { labelIds: [\\\"LABEL_UUID_1\\\", \\\"LABEL_UUID_2\\\"] }) { success issue { identifier labels { nodes { name } } } } }\"}' | python3 -m json.tool\n```\n\n### Add issue to a project\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { projectId: \\\"PROJECT_UUID\\\" }) { success issue { identifier project { name } } } }\"}' | python3 -m json.tool\n```\n\n### Create a project\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"query\": \"mutation($input: ProjectCreateInput!) { projectCreate(input: $input) { success project { id name url } } }\",\n    \"variables\": {\n      \"input\": {\n        \"name\": \"Q2 Auth Overhaul\",\n        \"description\": \"Replace legacy auth with OAuth2 and PKCE\",\n        \"teamIds\": [\"TEAM_UUID\"]\n      }\n    }\n  }' | python3 -m json.tool\n```\n\n## Documents\n\nLinear **Documents** are prose docs (RFCs, specs, notes) stored alongside issues. They have their own `documents` root query and `document(id:)` single-fetch.\n\n### Document URLs and `slugId`\n\nDocument URLs look like:\n```\nhttps:\u002F\u002Flinear.app\u002F\u003Cworkspace>\u002Fdocument\u002F\u003Cslug>-\u003ChexSlugId>\n```\n\nThe trailing hex segment is the `slugId`. Example: `https:\u002F\u002Flinear.app\u002Fnousresearch\u002Fdocument\u002Frfc-hermes-permission-gateway-discord-38359beef67c` → `slugId` is `38359beef67c`.\n\n**Important schema detail:** the Markdown body is in the `content` field. The ProseMirror JSON is in `contentState` (not `contentData` — that field does not exist and the API returns 400).\n\n### Fetch a document by slugId\n\n`document(id:)` only accepts UUIDs. To fetch by the URL's hex slug, filter the collection:\n\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"query($s: String!) { documents(filter: { slugId: { eq: $s } }, first: 1) { nodes { id title content contentState slugId url creator { name } project { name } updatedAt } } }\", \"variables\": {\"s\": \"38359beef67c\"}}' \\\n  | python3 -m json.tool\n```\n\nOr via the Python helper:\n```bash\npython3 scripts\u002Flinear_api.py get-document 38359beef67c\n```\n\n### Fetch a document by UUID\n\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ document(id: \\\"11700cff-b514-4db3-afcc-3ed1afacba1c\\\") { title content url } }\"}' \\\n  | python3 -m json.tool\n```\n\n### List recent documents\n\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ documents(first: 25, orderBy: updatedAt) { nodes { id title slugId url updatedAt project { name } } } }\"}' \\\n  | python3 -m json.tool\n```\n\n### Search documents by title\n\nLinear's schema has no `searchDocuments` root. Use a title-substring filter instead:\n\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ documents(filter: { title: { containsIgnoreCase: \\\"RFC\\\" } }, first: 25) { nodes { title slugId url } } }\"}' \\\n  | python3 -m json.tool\n```\n\n## Pagination\n\nLinear uses Relay-style cursor pagination:\n\n```bash\n# First page\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issues(first: 20) { nodes { identifier title } pageInfo { hasNextPage endCursor } } }\"}' | python3 -m json.tool\n\n# Next page — use endCursor from previous response\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issues(first: 20, after: \\\"CURSOR_FROM_PREVIOUS\\\") { nodes { identifier title } pageInfo { hasNextPage endCursor } } }\"}' | python3 -m json.tool\n```\n\nDefault page size: 50. Max: 250. Always use `first: N` to limit results.\n\n## Filtering Reference\n\nComparators: `eq`, `neq`, `in`, `nin`, `lt`, `lte`, `gt`, `gte`, `contains`, `startsWith`, `containsIgnoreCase`\n\nCombine filters with `or: [...]` for OR logic (default is AND within a filter object).\n\n## Typical Workflow\n\n1. **Query teams** to get team IDs and keys\n2. **Query workflow states** for target team to get state UUIDs\n3. **List or search issues** to find what needs work\n4. **Create issues** with team ID, title, description, priority\n5. **Update status** by setting `stateId` to the target workflow state\n6. **Add comments** to track progress\n7. **Mark complete** by setting `stateId` to the team's \"completed\" type state\n\n## Rate Limits\n\n- 5,000 requests\u002Fhour per API key\n- 3,000,000 complexity points\u002Fhour\n- Use `first: N` to limit results and reduce complexity cost\n- Monitor `X-RateLimit-Requests-Remaining` response header\n\n## Important Notes\n\n- Always use `terminal` tool with `curl` for API calls — do NOT use `web_extract` or `browser`\n- Always check the `errors` array in GraphQL responses — HTTP 200 can still contain errors\n- If `stateId` is omitted when creating issues, Linear defaults to the first backlog state\n- The `description` field supports Markdown\n- Use `python3 -m json.tool` or `jq` to format JSON responses for readability\n","# Linear — Issue & Project Management\n\nManage Linear issues, projects, and teams directly via the GraphQL API using `curl`. No MCP server, no OAuth flow, no extra dependencies.\n\n## Setup\n\n1. Get a personal API key from **Linear Settings > Account > Security & access > Personal API keys** (URL: https:\u002F\u002Flinear.app\u002Fsettings\u002Faccount\u002Fsecurity). Note: the org-level *Settings > API* page only shows OAuth apps and workspace-member keys, not personal keys.\n2. Set `LINEAR_API_KEY` in your environment (via `hermes setup` or your env config)\n\n## API Basics\n\n- **Endpoint:** `https:\u002F\u002Fapi.linear.app\u002Fgraphql` (POST)\n- **Auth header:** `Authorization: $LINEAR_API_KEY` (no \"Bearer\" prefix for API keys)\n- **All requests are POST** with `Content-Type: application\u002Fjson`\n- **Both UUIDs and short identifiers** (e.g., `ENG-123`) work for `issue(id:)`\n\nBase curl pattern:\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ viewer { id name } }\"}' | python3 -m json.tool\n```\n\n## Python helper script (ergonomic alternative)\n\nFor faster one-liners that don't need hand-written GraphQL, this skill ships a stdlib Python CLI at `scripts\u002Flinear_api.py`. Zero dependencies. Same auth (reads `LINEAR_API_KEY`).\n\n```bash\nSCRIPT=$(dirname \"$(find ~\u002F.hermes -path '*skills\u002Fproductivity\u002Flinear\u002Fscripts\u002Flinear_api.py' 2>\u002Fdev\u002Fnull | head -1)\")\u002Flinear_api.py\n\npython3 \"$SCRIPT\" whoami\npython3 \"$SCRIPT\" list-teams\npython3 \"$SCRIPT\" get-issue ENG-42\npython3 \"$SCRIPT\" get-document 38359beef67c      # fetch a doc by slugId from the URL\npython3 \"$SCRIPT\" raw 'query { viewer { name } }'\n```\n\nAll subcommands: `whoami`, `list-teams`, `list-projects`, `list-states`, `list-issues`, `get-issue`, `search-issues`, `create-issue`, `update-issue`, `update-status`, `add-comment`, `list-documents`, `get-document`, `search-documents`, `raw`. Run with `--help` for flags.\n\nUse the script when: you want a quick answer without crafting GraphQL. Use curl when: you need a query the script doesn't wrap, or you want to compose filters inline.\n\n## Workflow States\n\nLinear uses `WorkflowState` objects with a `type` field. **6 state types:**\n\n| Type | Description |\n|------|-------------|\n| `triage` | Incoming issues needing review |\n| `backlog` | Acknowledged but not yet planned |\n| `unstarted` | Planned\u002Fready but not started |\n| `started` | Actively being worked on |\n| `completed` | Done |\n| `canceled` | Won't do |\n\nEach team has its own named states (e.g., \"In Progress\" is type `started`). To change an issue's status, you need the `stateId` (UUID) of the target state — query workflow states first.\n\n**Priority values:** 0 = None, 1 = Urgent, 2 = High, 3 = Medium, 4 = Low\n\n## Common Queries\n\n### Get current user\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ viewer { id name email } }\"}' | python3 -m json.tool\n```\n\n### List teams\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ teams { nodes { id name key } } }\"}' | python3 -m json.tool\n```\n\n### List workflow states for a team\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ workflowStates(filter: { team: { key: { eq: \\\"ENG\\\" } } }) { nodes { id name type } } }\"}' | python3 -m json.tool\n```\n\n### List issues (first 20)\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issues(first: 20) { nodes { identifier title priority state { name type } assignee { name } team { key } url } pageInfo { hasNextPage endCursor } } }\"}' | python3 -m json.tool\n```\n\n### List my assigned issues\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ viewer { assignedIssues(first: 25) { nodes { identifier title state { name type } priority url } } } }\"}' | python3 -m json.tool\n```\n\n### Get a single issue (by identifier like ENG-123)\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issue(id: \\\"ENG-123\\\") { id identifier title description priority state { id name type } assignee { id name } team { key } project { name } labels { nodes { name } } comments { nodes { body user { name } createdAt } } url } }\"}' | python3 -m json.tool\n```\n\n### Search issues by text\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issueSearch(query: \\\"bug login\\\", first: 10) { nodes { identifier title state { name } assignee { name } url } } }\"}' | python3 -m json.tool\n```\n\n### Filter issues by state type\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issues(filter: { state: { type: { in: [\\\"started\\\"] } } }, first: 20) { nodes { identifier title state { name } assignee { name } } } }\"}' | python3 -m json.tool\n```\n\n### Filter by team and assignee\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issues(filter: { team: { key: { eq: \\\"ENG\\\" } }, assignee: { email: { eq: \\\"user@example.com\\\" } } }, first: 20) { nodes { identifier title state { name } priority } } }\"}' | python3 -m json.tool\n```\n\n### List projects\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ projects(first: 20) { nodes { id name description progress lead { name } teams { nodes { key } } url } } }\"}' | python3 -m json.tool\n```\n\n### List team members\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ users { nodes { id name email active } } }\"}' | python3 -m json.tool\n```\n\n### List labels\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issueLabels { nodes { id name color } } }\"}' | python3 -m json.tool\n```\n\n## Common Mutations\n\n### Create an issue\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"query\": \"mutation($input: IssueCreateInput!) { issueCreate(input: $input) { success issue { id identifier title url } } }\",\n    \"variables\": {\n      \"input\": {\n        \"teamId\": \"TEAM_UUID\",\n        \"title\": \"Fix login bug\",\n        \"description\": \"Users cannot login with SSO\",\n        \"priority\": 2\n      }\n    }\n  }' | python3 -m json.tool\n```\n\n### Update issue status\nFirst get the target state UUID from the workflow states query above, then:\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { stateId: \\\"STATE_UUID\\\" }) { success issue { identifier state { name type } } } }\"}' | python3 -m json.tool\n```\n\n### Assign an issue\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { assigneeId: \\\"USER_UUID\\\" }) { success issue { identifier assignee { name } } } }\"}' | python3 -m json.tool\n```\n\n### Set priority\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { priority: 1 }) { success issue { identifier priority } } }\"}' | python3 -m json.tool\n```\n\n### Add a comment\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { commentCreate(input: { issueId: \\\"ISSUE_UUID\\\", body: \\\"Investigated. Root cause is X.\\\" }) { success comment { id body } } }\"}' | python3 -m json.tool\n```\n\n### Set due date\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { dueDate: \\\"2026-04-01\\\" }) { success issue { identifier dueDate } } }\"}' | python3 -m json.tool\n```\n\n### Add labels to an issue\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { labelIds: [\\\"LABEL_UUID_1\\\", \\\"LABEL_UUID_2\\\"] }) { success issue { identifier labels { nodes { name } } } } }\"}' | python3 -m json.tool\n```\n\n### Add issue to a project\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"mutation { issueUpdate(id: \\\"ENG-123\\\", input: { projectId: \\\"PROJECT_UUID\\\" }) { success issue { identifier project { name } } } }\"}' | python3 -m json.tool\n```\n\n### Create a project\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"query\": \"mutation($input: ProjectCreateInput!) { projectCreate(input: $input) { success project { id name url } } }\",\n    \"variables\": {\n      \"input\": {\n        \"name\": \"Q2 Auth Overhaul\",\n        \"description\": \"Replace legacy auth with OAuth2 and PKCE\",\n        \"teamIds\": [\"TEAM_UUID\"]\n      }\n    }\n  }' | python3 -m json.tool\n```\n\n## Documents\n\nLinear **Documents** are prose docs (RFCs, specs, notes) stored alongside issues. They have their own `documents` root query and `document(id:)` single-fetch.\n\n### Document URLs and `slugId`\n\nDocument URLs look like:\n```\nhttps:\u002F\u002Flinear.app\u002F\u003Cworkspace>\u002Fdocument\u002F\u003Cslug>-\u003ChexSlugId>\n```\n\nThe trailing hex segment is the `slugId`. Example: `https:\u002F\u002Flinear.app\u002Fnousresearch\u002Fdocument\u002Frfc-hermes-permission-gateway-discord-38359beef67c` → `slugId` is `38359beef67c`.\n\n**Important schema detail:** the Markdown body is in the `content` field. The ProseMirror JSON is in `contentState` (not `contentData` — that field does not exist and the API returns 400).\n\n### Fetch a document by slugId\n\n`document(id:)` only accepts UUIDs. To fetch by the URL's hex slug, filter the collection:\n\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"query($s: String!) { documents(filter: { slugId: { eq: $s } }, first: 1) { nodes { id title content contentState slugId url creator { name } project { name } updatedAt } } }\", \"variables\": {\"s\": \"38359beef67c\"}}' \\\n  | python3 -m json.tool\n```\n\nOr via the Python helper:\n```bash\npython3 scripts\u002Flinear_api.py get-document 38359beef67c\n```\n\n### Fetch a document by UUID\n\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ document(id: \\\"11700cff-b514-4db3-afcc-3ed1afacba1c\\\") { title content url } }\"}' \\\n  | python3 -m json.tool\n```\n\n### List recent documents\n\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ documents(first: 25, orderBy: updatedAt) { nodes { id title slugId url updatedAt project { name } } } }\"}' \\\n  | python3 -m json.tool\n```\n\n### Search documents by title\n\nLinear's schema has no `searchDocuments` root. Use a title-substring filter instead:\n\n```bash\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ documents(filter: { title: { containsIgnoreCase: \\\"RFC\\\" } }, first: 25) { nodes { title slugId url } } }\"}' \\\n  | python3 -m json.tool\n```\n\n## Pagination\n\nLinear uses Relay-style cursor pagination:\n\n```bash\n# First page\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issues(first: 20) { nodes { identifier title } pageInfo { hasNextPage endCursor } } }\"}' | python3 -m json.tool\n\n# Next page — use endCursor from previous response\ncurl -s -X POST https:\u002F\u002Fapi.linear.app\u002Fgraphql \\\n  -H \"Authorization: $LINEAR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"query\": \"{ issues(first: 20, after: \\\"CURSOR_FROM_PREVIOUS\\\") { nodes { identifier title } pageInfo { hasNextPage endCursor } } }\"}' | python3 -m json.tool\n```\n\nDefault page size: 50. Max: 250. Always use `first: N` to limit results.\n\n## Filtering Reference\n\nComparators: `eq`, `neq`, `in`, `nin`, `lt`, `lte`, `gt`, `gte`, `contains`, `startsWith`, `containsIgnoreCase`\n\nCombine filters with `or: [...]` for OR logic (default is AND within a filter object).\n\n## Typical Workflow\n\n1. **Query teams** to get team IDs and keys\n2. **Query workflow states** for target team to get state UUIDs\n3. **List or search issues** to find what needs work\n4. **Create issues** with team ID, title, description, priority\n5. **Update status** by setting `stateId` to the target workflow state\n6. **Add comments** to track progress\n7. **Mark complete** by setting `stateId` to the team's \"completed\" type state\n\n## Rate Limits\n\n- 5,000 requests\u002Fhour per API key\n- 3,000,000 complexity points\u002Fhour\n- Use `first: N` to limit results and reduce complexity cost\n- Monitor `X-RateLimit-Requests-Remaining` response header\n\n## Important Notes\n\n- Always use `terminal` tool with `curl` for API calls — do NOT use `web_extract` or `browser`\n- Always check the `errors` array in GraphQL responses — HTTP 200 can still contain errors\n- If `stateId` is omitted when creating issues, Linear defaults to the first backlog state\n- The `description` field supports Markdown\n- Use `python3 -m json.tool` or `jq` to format JSON responses for readability\n",{"name":5,"author":45,"license":14,"version":46,"metadata":47,"platforms":55,"description":7,"prerequisites":56},"Hermes Agent","1.0.0",{"hermes":48},{"tags":49},[50,51,52,33,53,54],"Linear","Project Management","Issues","API","Productivity",[39,32,38],{"commands":57,"env_vars":58},[28],[59],"LINEAR_API_KEY","main","05df7380981a2c4af868ce0fa57962ae0eea62a9","hermes\u002Fskills\u002Fproductivity\u002Flinear",0,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills","https:\u002F\u002Fgithub.com\u002Fjleechanorg","2026-11-12 14:45:07",{"source":8,"skillName":5,"commands":68,"prompt":78,"zipAvailable":79},[69,72,75],{"tool":70,"command":71},"npx","npx skills add jleechanorg\u002Fjleechan-skills --skill linear",{"tool":73,"command":74},"bunx","bunx skills add jleechanorg\u002Fjleechan-skills --skill linear",{"tool":76,"command":77},"pnpm","pnpm dlx skills add jleechanorg\u002Fjleechan-skills --skill linear","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Fproductivity\u002Flinear\u002FSKILL.md",true,[81,87,91,95],{"path":82,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":85,"sourceHtmlUrl":86},"scripts\u002Flinear_api.py","SCRIPT","脚本",15603,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002Fhermes\u002Fskills\u002Fproductivity\u002Flinear\u002Fscripts\u002Flinear_api.py",{"path":88,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":89,"sourceHtmlUrl":90},"scripts\u002Frun-tool.ps1",3297,"https:\u002F\u002Fgithub.com\u002Fcookeyholder\u002Fusing-ai-skills\u002Fblob\u002Fmain\u002Fuse-modern-go\u002Fscripts\u002Frun-tool.ps1",{"path":92,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":93,"sourceHtmlUrl":94},"scripts\u002Frun-tool.sh",2032,"https:\u002F\u002Fgithub.com\u002Fcookeyholder\u002Fusing-ai-skills\u002Fblob\u002Fmain\u002Fuse-modern-go\u002Fscripts\u002Frun-tool.sh",{"path":96,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":97,"sourceHtmlUrl":98},"scripts\u002FVERSION",7,"https:\u002F\u002Fgithub.com\u002Fcookeyholder\u002Fusing-ai-skills\u002Fblob\u002Fmain\u002Fuse-modern-go\u002Fscripts\u002FVERSION",[100,118,140,154,168,184],{"skillNo":101,"name":102,"nameZh":6,"description":103,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":104,"categories":105,"keywords":106,"publishedAt":40},"01M716Y5MTJ6GYJZ2ATXCJK8G4","instinct","Use when the user invokes \u002Finstinct or \u002Fin, or asks to \"message Instinct\", \"ask Instinct\", \"tell Instinct\", \"check Instinct\", or read replies from the configured peer assistant. iMessage first, WhatsApp Web as fallback.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Finstinct\u002FSKILL.md",[],[102,107,108,109,110,111,112,113,114,115,116,117],"user","when","replies","check","use","identity","whatsapp","gmail","read","message","ask",{"skillNo":119,"name":120,"nameZh":6,"description":121,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":129,"publishedAt":40},"01M716Y4HF7FVVMJSA2CCVN5VF","hr","Compatibility alias for history-resume; produce the same fresh-state, provenance-aware resume briefing.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhr\u002FSKILL.md",[124],{"categoryNo":125,"categoryName":126,"taxonomyType":127,"taxonomyTypeDesc":128},"01JBSEEDCAT000000000000038","人力资源","PROFESSION","适用职业",[120,130,131,132,133,134,135,136,137,138,139],"resume","compatibility","provenance","for","history","produce","alias","briefing","state","fresh",{"skillNo":141,"name":142,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":144,"categories":145,"keywords":147,"publishedAt":40},"01M716Y1FFNFKFJYYKF8HQA6T8","history-resume","Resume briefing for the current repository branch or worktree using fresh state and admitted history sources.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhistory-resume\u002FSKILL.md",[146],{"categoryNo":125,"categoryName":126,"taxonomyType":127,"taxonomyTypeDesc":128},[134,130,148,149,107,150,137,151,133,152,153,138,139],"history resume","branch","analysis","repository","worktree","sources",{"skillNo":155,"name":156,"nameZh":6,"description":157,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":158,"categories":159,"keywords":160,"publishedAt":40},"01M716XWXJ8EPHK4RH9T14TR85","grok","Alias for the canonical grokbot browser conversation workflow; \u002Fgrok talks to the Grok bot the same way \u002Fdot talks to Dot.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fgrok\u002FSKILL.md",[],[156,161,162,163,133,164,136,165,166,167],"dot","bot","workflow","canonical","conversation","browser","grokbot",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":174,"publishedAt":40},"01M70N9Q07DTE0EW5KFXMMMSJ0","codexa-bench","Compare `codexa` and normal `codex` on a fair split of comparable work by default; use `--strict` for duplicate runs of the exact same task.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcodexa-bench\u002FSKILL.md",[],[175,176,177,111,178,133,179,180,181,182,183],"codexa bench","work","split","default","duplicate","task","compare","normal","codex",{"skillNo":185,"name":186,"nameZh":6,"description":187,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":188,"licenseFileUrl":189,"sourceHtmlUrl":190,"categories":191,"keywords":201,"publishedAt":40},"01M6C24S2X60SP8BBFGAEKPEGW","frontend-design","Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML\u002FCSS layouts, or when styling\u002Fbeautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FSKILL.md",[192,195,198],{"categoryNo":193,"categoryName":194,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":196,"categoryName":197,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":199,"categoryName":200,"taxonomyType":127,"taxonomyTypeDesc":128},"01JBSEEDCAT000000000000032","设计师",[202,203,204,111,205,206,207,107,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,108,226],"frontend","design","frontend design","generic","ui design","react","html","components","code","artifacts","ui","aesthetics","Production","web components","landing","applications","quality","web","css","create","examples","with","react components","web ui","pages"]