linear
Load for any Linear read or write: issues, projects, cycles, milestones, initiatives, labels.
- License 许可
- MIT
- 最近更新
- 2026-11-12
- Stars
- ★ 93
- Forks
- 37
01 前言 Front Matter
- name
- linear
- tags
- [ "integration" ]
- license
- MIT
- summary
- Bash CLI over Linear's GraphQL API, read live: read, search, create, or update issues, projects, cycles, milestones, initiatives, and labels.
- metadata
- { "bugs": "https://github.com/vanillagreencom/kendex/issues", "author": "vanillagreen", "source": "kendex", "repository": "https://github.com/vanillagreencom/kendex" }
- description
- Load for any Linear read or write: issues, projects, cycles, milestones, initiatives, labels.
- user-invocable
- true
02 资源文件 220
- 参考文档DEVELOPMENT.md16.4 KB
- 其他kendex.settings.toml.example3.4 KB
- 参考文档patterns/workflow-actions.md9.5 KB
- 参考文档README.md4.6 KB
- 参考文档references/authentication.md3.5 KB
- 参考文档references/request-journal.md2.5 KB
- 脚本scripts/commands/attachments.sh6.7 KB
- 脚本scripts/commands/auth-check.sh6.7 KB
- 脚本scripts/commands/auth-mint.sh902 B
- 脚本scripts/commands/comments.sh12.3 KB
- 脚本scripts/commands/cycles.sh8.8 KB
- 脚本scripts/commands/documents.sh3.9 KB
- 脚本scripts/commands/initiatives.sh17.9 KB
- 脚本scripts/commands/issues.sh162.8 KB
- 脚本scripts/commands/labels.sh14.5 KB
- 脚本scripts/commands/milestones.sh10.2 KB
- 脚本scripts/commands/project-labels.sh8.0 KB
- 脚本scripts/commands/projects.sh44.3 KB
- 脚本scripts/commands/session-status.sh23.7 KB
- 脚本scripts/commands/statuses.sh4.9 KB
- 脚本scripts/commands/teams.sh4.2 KB
- 脚本scripts/commands/users.sh4.1 KB
- 脚本scripts/lib/attachments.sh8.1 KB
- 脚本scripts/lib/auth.sh9.7 KB
- 脚本scripts/lib/bash-version.sh366 B
- 脚本scripts/lib/common.sh97.8 KB
- 脚本scripts/lib/cycle-dates.sh3.0 KB
- 脚本scripts/lib/formatters.sh30.7 KB
- 脚本scripts/lib/issue-validation.sh26.7 KB
- 脚本scripts/lib/kendex-env.sh18.0 KB
- 脚本scripts/lib/pages.sh16.7 KB
- 脚本scripts/linear.sh9.1 KB
- 脚本tests/api-key-precedence.test.sh7.8 KB
- 脚本tests/assert-outstanding-jobs.test.sh2.4 KB
- 脚本tests/assert-subshell.test.sh3.0 KB
- 脚本tests/assert-verdict.test.sh2.8 KB
- 脚本tests/attachments.test.sh9.5 KB
- 脚本tests/bash4-runtime-contract.test.sh940 B
- 脚本tests/blocked-by-open.test.sh10.6 KB
- 脚本tests/bulk-update-diagnostics.test.sh4.8 KB
- 脚本tests/comments-body-file.test.sh2.2 KB
- 脚本tests/comments-bulk-list.test.sh5.7 KB
- 脚本tests/comments-create-attach.test.sh8.5 KB
- 脚本tests/completion-validation-bundle-children.test.sh22.7 KB
- 脚本tests/completion-validation-parented-root.test.sh5.3 KB
- 脚本tests/controls/api-key-precedence.control.sh551 B
- 脚本tests/controls/assert-outstanding-jobs.control.sh464 B
- 脚本tests/controls/assert-subshell.control.sh419 B
- 脚本tests/controls/assert-verdict.control.sh392 B
- 脚本tests/controls/attachments.control.sh260 B
- 脚本tests/controls/bash4-runtime-contract.control.sh356 B
- 脚本tests/controls/blocked-by-open.control.sh507 B
- 脚本tests/controls/bulk-update-diagnostics.control.sh526 B
- 脚本tests/controls/comments-body-file.control.sh428 B
- 脚本tests/controls/comments-bulk-list.control.sh471 B
- 脚本tests/controls/comments-create-attach.control.sh415 B
- 脚本tests/controls/completion-validation-bundle-children.control.sh592 B
- 脚本tests/controls/completion-validation-parented-root.control.sh517 B
- 脚本tests/controls/cross-team-guard.control.sh285 B
- 脚本tests/controls/done-when-outside.control.sh2.5 KB
- 脚本tests/controls/estimate-clear.control.sh325 B
- 脚本tests/controls/graphql-query-large-variables.control.sh440 B
- 脚本tests/controls/initiatives-projects-fields.control.sh448 B
- 脚本tests/controls/interrupt.control.sh654 B
- 脚本tests/controls/issues-activate-agent.control.sh387 B
- 脚本tests/controls/issues-activate-assignee.control.sh321 B
- 脚本tests/controls/issues-add-relation-hierarchy.control.sh322 B
- 脚本tests/controls/issues-archive-trash-entity-verify.control.sh467 B
- 脚本tests/controls/issues-assignee-email.control.sh718 B
- 脚本tests/controls/issues-bulk-get.control.sh260 B
- 脚本tests/controls/issues-complete-done-when.control.sh670 B
- 脚本tests/controls/issues-complete-summary.control.sh252 B
- 脚本tests/controls/issues-complete-supersedes.control.sh201 B
- 脚本tests/controls/issues-create-agent-label-guard.control.sh375 B
- 脚本tests/controls/issues-create-attach.control.sh1.2 KB
- 脚本tests/controls/issues-create-format-ids.control.sh468 B
- 脚本tests/controls/issues-create-parent.control.sh378 B
- 脚本tests/controls/issues-create-project-map.control.sh503 B
- 脚本tests/controls/issues-create-reach-guard.control.sh562 B
- 脚本tests/controls/issues-create-team-labels.control.sh953 B
- 脚本tests/controls/issues-description-file.control.sh445 B
- 脚本tests/controls/issues-get-github-sync.control.sh382 B
- 脚本tests/controls/issues-header-shape-guard.control.sh1.3 KB
- 脚本tests/controls/issues-list-filters.control.sh298 B
- 脚本tests/controls/issues-list-search-server-filter.control.sh402 B
- 脚本tests/controls/issues-remove-relation-completed-blocker.control.sh257 B
- 脚本tests/controls/issues-update-attach.control.sh2.3 KB
- 脚本tests/controls/issues-update-done-when.control.sh241 B
- 脚本tests/controls/issues-update-format-safe.control.sh466 B
- 脚本tests/controls/issues-update-unknown-label-refuses.control.sh384 B
- 脚本tests/controls/label-name-spaces.control.sh430 B
- 脚本tests/controls/label-taxonomy.control.sh416 B
- 脚本tests/controls/list-bounds.control.sh282 B
- 脚本tests/controls/live-resource-pages-cap.control.sh156 B
- 脚本tests/controls/live-resource-pages-chain.control.sh234 B
- 脚本tests/controls/live-resource-pages-children.control.sh311 B
- 脚本tests/controls/live-resource-pages-entity.control.sh289 B
- 脚本tests/controls/live-resource-pages-replay-content.control.sh483 B
- 脚本tests/controls/live-resource-pages-replay-issues.control.sh481 B
- 脚本tests/controls/live-resource-pages-replay-projects.control.sh596 B
- 脚本tests/controls/live-resource-pages-replay-workspace.control.sh481 B
- 脚本tests/controls/live-resource-pages-result.control.sh290 B
- 脚本tests/controls/live-resource-pages.control.sh240 B
- 脚本tests/controls/milestone-project-scope.control.sh711 B
- 脚本tests/controls/mutation-isolation.control.sh714 B
- 脚本tests/controls/oauth-auth.control.sh500 B
- 脚本tests/controls/project-name-canceled-duplicate.control.sh835 B
- 脚本tests/controls/projects-audit-map.control.sh788 B
- 脚本tests/controls/projects-list-pagination.control.sh394 B
- 脚本tests/controls/quota-hold.control.sh172 B
- 脚本tests/controls/rate-limited-http-400.control.sh364 B
- 脚本tests/controls/related-inverse.control.sh452 B
- 脚本tests/controls/request-journal.control.sh227 B
- 脚本tests/controls/roster-orphan.control.sh363 B
- 脚本tests/controls/run-status-errexit.control.sh815 B
- 脚本tests/controls/session-status-cycles.control.sh283 B
- 脚本tests/controls/session-status-issues.control.sh452 B
- 脚本tests/controls/stdin-final-line.control.sh425 B
- 脚本tests/controls/team-ref-resolution.control.sh214 B
- 脚本tests/controls/team-target-fail-closed.control.sh381 B
- 脚本tests/controls/teams-keys.control.sh570 B
- 脚本tests/cross-team-guard.test.sh13.0 KB
- 脚本tests/done-when-outside.test.sh8.7 KB
- 脚本tests/estimate-clear.test.sh7.2 KB
- 脚本tests/graphql-query-large-variables.test.sh2.6 KB
- 脚本tests/initiatives-projects-fields.test.sh14.6 KB
- 脚本tests/interrupt.test.sh5.7 KB
- 脚本tests/issues-activate-agent.test.sh8.2 KB
- 脚本tests/issues-activate-assignee.test.sh10.0 KB
- 脚本tests/issues-add-relation-hierarchy.test.sh10.2 KB
- 脚本tests/issues-archive-trash-entity-verify.test.sh6.0 KB
- 脚本tests/issues-assignee-email.test.sh7.2 KB
- 脚本tests/issues-bulk-get.test.sh10.5 KB
- 脚本tests/issues-complete-done-when.test.sh24.4 KB
- 脚本tests/issues-complete-summary.test.sh9.7 KB
- 脚本tests/issues-complete-supersedes.test.sh10.2 KB
- 脚本tests/issues-create-agent-label-guard.test.sh11.3 KB
- 脚本tests/issues-create-attach.test.sh15.3 KB
- 脚本tests/issues-create-format-ids.test.sh3.7 KB
- 脚本tests/issues-create-parent.test.sh8.3 KB
- 脚本tests/issues-create-project-map.test.sh11.3 KB
- 脚本tests/issues-create-reach-guard.test.sh7.9 KB
- 脚本tests/issues-create-team-labels.test.sh5.7 KB
- 脚本tests/issues-description-file.test.sh8.6 KB
- 脚本tests/issues-get-github-sync.test.sh3.5 KB
- 脚本tests/issues-header-shape-guard.test.sh24.7 KB
- 脚本tests/issues-list-filters.test.sh7.8 KB
- 脚本tests/issues-list-search-server-filter.test.sh7.9 KB
- 脚本tests/issues-remove-relation-completed-blocker.test.sh7.4 KB
- 脚本tests/issues-update-attach.test.sh22.9 KB
- 脚本tests/issues-update-done-when.test.sh7.0 KB
- 脚本tests/issues-update-format-safe.test.sh5.4 KB
- 脚本tests/issues-update-unknown-label-refuses.test.sh5.5 KB
- 脚本tests/label-name-spaces.test.sh6.5 KB
- 脚本tests/label-taxonomy.test.sh21.8 KB
- 脚本tests/lib/assert.sh30.8 KB
- 脚本tests/lib/control-runner.sh709 B
- 参考文档tests/lib/fixtures/issue-team-labels.json1.7 KB
- 参考文档tests/lib/fixtures/label-team-issue.json746 B
- 参考文档tests/lib/fixtures/recorded/attachments-list.json1.4 KB
- 参考文档tests/lib/fixtures/recorded/comments-bulk-list.json3.9 KB
- 参考文档tests/lib/fixtures/recorded/comments-list.json3.1 KB
- 参考文档tests/lib/fixtures/recorded/cycles-list.json1.5 KB
- 参考文档tests/lib/fixtures/recorded/documents-list.json1.1 KB
- 参考文档tests/lib/fixtures/recorded/initiatives-get.json1.3 KB
- 参考文档tests/lib/fixtures/recorded/initiatives-list.json1.5 KB
- 参考文档tests/lib/fixtures/recorded/issues-bulk-get.json5.2 KB
- 参考文档tests/lib/fixtures/recorded/issues-bundle.json7.4 KB
- 参考文档tests/lib/fixtures/recorded/issues-children-pending-raw.json3.6 KB
- 参考文档tests/lib/fixtures/recorded/issues-children-pending.json3.6 KB
- 参考文档tests/lib/fixtures/recorded/issues-children-recursive.json6.3 KB
- 参考文档tests/lib/fixtures/recorded/issues-children.json1.7 KB
- 参考文档tests/lib/fixtures/recorded/issues-get.json3.3 KB
- 参考文档tests/lib/fixtures/recorded/issues-list.json3.0 KB
- 参考文档tests/lib/fixtures/recorded/issues-relations.json1.6 KB
- 参考文档tests/lib/fixtures/recorded/labels-list.json1.6 KB
- 参考文档tests/lib/fixtures/recorded/milestones-list.json1.1 KB
- 参考文档tests/lib/fixtures/recorded/project-labels-list.json1.5 KB
- 参考文档tests/lib/fixtures/recorded/projects-dependencies.json1.4 KB
- 参考文档tests/lib/fixtures/recorded/projects-get.json1.9 KB
- 参考文档tests/lib/fixtures/recorded/projects-list.json2.2 KB
- 参考文档tests/lib/fixtures/recorded/README.md1.9 KB
- 参考文档tests/lib/fixtures/recorded/session-status.json71.2 KB
- 参考文档tests/lib/fixtures/recorded/statuses-get.json1.2 KB
- 参考文档tests/lib/fixtures/recorded/statuses-list.json1.9 KB
- 参考文档tests/lib/fixtures/recorded/teams-get.json3.6 KB
- 参考文档tests/lib/fixtures/recorded/teams-keys.json720 B
- 参考文档tests/lib/fixtures/recorded/teams-list.json3.9 KB
- 参考文档tests/lib/fixtures/recorded/users-list.json1.1 KB
- 参考文档tests/lib/fixtures/recorded/users-me.json810 B
- 脚本tests/list-bounds.test.sh5.4 KB
- 脚本tests/live-resource-pages-cap.test.sh873 B
- 脚本tests/live-resource-pages-chain.test.sh1.1 KB
- 脚本tests/live-resource-pages-children.test.sh2.2 KB
- 脚本tests/live-resource-pages-entity.test.sh1.5 KB
- 脚本tests/live-resource-pages-replay-content.test.sh752 B
- 脚本tests/live-resource-pages-replay-issues.test.sh836 B
- 脚本tests/live-resource-pages-replay-projects.test.sh802 B
- 脚本tests/live-resource-pages-replay-workspace.test.sh763 B
- 脚本tests/live-resource-pages-result.test.sh1.6 KB
- 脚本tests/live-resource-pages.test.sh3.4 KB
- 脚本tests/milestone-project-scope.test.sh10.2 KB
- 脚本tests/must-fail-controls.sh23.5 KB
- 脚本tests/mutation-isolation.test.sh17.1 KB
- 脚本tests/oauth-auth.test.sh27.0 KB
- 脚本tests/project-name-canceled-duplicate.test.sh6.6 KB
- 脚本tests/projects-audit-map.test.sh11.5 KB
- 脚本tests/projects-list-pagination.test.sh5.4 KB
- 脚本tests/quota-hold.test.sh10.3 KB
- 脚本tests/rate-limited-http-400.test.sh14.6 KB
- 脚本tests/related-inverse.test.sh4.9 KB
- 脚本tests/request-journal.test.sh15.7 KB
- 脚本tests/roster-orphan.test.sh7.3 KB
- 脚本tests/run-status-errexit.test.sh3.6 KB
- 脚本tests/session-status-cycles.test.sh4.3 KB
- 脚本tests/session-status-issues.test.sh6.0 KB
- 脚本tests/stdin-final-line.test.sh3.5 KB
- 脚本tests/team-ref-resolution.test.sh9.1 KB
- 脚本tests/team-target-fail-closed.test.sh19.2 KB
- 脚本tests/teams-keys.test.sh2.5 KB
03 SKILL.md 正文
Linear CLI
.agents/skills/linear/scripts/linear.sh <resource> <action> [options]
Every read and write goes to Linear's API as it runs; no tracker data is stored locally. linear.sh <resource> --help prints per-resource options. --format values: safe (the default, flat and null-safe), compact (a smaller shape for workflow routing), ids (identifiers only), table, raw (the GraphQL nesting, so never assume top-level jq paths). safe renames fields: identifier→id, id→uuid, state.name→state, state.type→state_type, sortOrder→sort_order.
Commands
| Resource | Actions |
|---|---|
issues |
list, get, bulk-get, create, update, bulk-update, archive, trash/delete, children, list-relations, add-relation, remove-relation, activate, block, unblock, complete, validate-completion |
comments / labels / project-labels |
list, create, update, delete (comments also bulk-list, labels also audit) |
projects |
list, get, create, update, delete, list-dependencies, add-dependency, remove-dependency, post-update, list-updates, reorder, set-sort-order, audit; create/update take --lead EMAIL|ID and repeatable --link LABEL=URL |
initiatives / milestones |
list, get, create, update, delete (initiatives also add-project, remove-project; create/update take --owner EMAIL|ID, --lead-team KEY|NAME, --labels A,B, and repeatable --link LABEL=URL) |
teams / users / statuses / documents |
list, get (users also has me; teams keys reads {urlKey, keys} for outbound tracker links without changing teams list's array) |
cycles |
list, create, update |
attachments |
list (every file an issue references), fetch (download one) |
auth-check |
Report the selected credential, actor, team and writes_enabled for writes that need a configured team (--strict exits non-zero when no team is configured) |
auth-mint |
Mint application token JSON from the client pair without writing files |
journal |
Start, stop or read a bounded local request-attempt journal; off by default (request journal) |
session-status |
Aggregated status for the /start workflow |
Aliases: issues relations → list-relations, projects dependencies → list-dependencies. Singular resource names (issue, project, …) route to the plural. There is no view/show: single-issue lookups are issues get <ID>; only issues get <ID>, without --with-bundle and in the default safe format, carries github_sync, the GitHub issues Linear's GitHub sync links the issue to, each as owner/repo#N lowercased. Safe issues get and issues list rows carry in_pr_bundle, true when the description holds **In-PR bundle**: yes. Multi-issue lookups are issues bulk-get <ID1> <ID2> ..., which is also the post-mutation verification path. Comments for several issues are one comments bulk-list <ID1> <ID2> ... call (--stdin takes one identifier per line), never a loop or parallel comments list readers.
The removed cache and sync verbs refuse with one linear: removed= line (linear.sh --help).
Schema reference over ctx7: /websites/studio_apollographql_public_linear-api_variant_current (API), /linear/linear (SDK), /websites/linear_app_developers (guides). patterns/workflow-actions.md covers multi-step state changes.
Reads
Read the time an issue entered a state from its history: the matching toState row's createdAt. Read every history page needed to identify the latest transition into that state. updated_at records the issue's latest update, which can be a different change. Use Linear's API or activity history; issues get exposes no history field. If the transition is unavailable, report its time as unread.
linear.sh issues list --project "Phase 2" --state "Todo,In Progress" --max
linear.sh issues get ABC-100 --with-bundle
linear.sh labels list --max --format=safe
issues list --all-projects enumerates every project in one command (each row carries its project name); --no-project returns only unassigned issues. Both are mutually exclusive with --project. Use --all-projects; never loop per project. An unrecognized filter flag is rejected. Repeated --label flags (and --labels a,b) require ALL named labels.
A list of issues, projects, labels, project labels, teams, users, cycles, documents or initiatives returns its first --limit rows (75 by default, a positive whole number) and prints a linear-list: truncated line on stderr when rows were left unread; --max reads every page. milestones list, statuses list, comments list and attachments list always read every row and take neither. A read follows each nested collection (labels, relations, children, comments) to its end. A read that cannot finish its chain (a failed later page, a missing or repeated cursor, or a chain still open after 400 pages) exits nonzero with no output, never a partial result. An audit that must see the whole backlog passes --max. A text search over issues uses issues list --search TERMS, which Linear filters by title and description server-side, never a --max list piped to a local filter.
A quota refusal exits nonzero with JSON stderr code:"RATELIMITED". Its quota receipt supplies the selected deadline; requests_reset keeps the raw request-header time. Same-binding GraphQL calls share a private hold on this host. Receipt fields, storage failures and held writes: Quota Holds.
The transport retries a rate refusal, a 5xx query/download or an unanswered query/download at most twice. A known hold can stop a GraphQL retry before HTTP. A 5xx or unanswered mutation is sent once with linear-http: write=unconfirmed: read its result before resending. Waits double, or use a longer Retry-After. A Retry-After over 60 seconds or any other HTTP error fails immediately.
Team Target
LINEAR_TEAM has no default. Existing-issue writes, including comments create, route by the issue identifier and need no configured team. Other writes refuse when it is unset; reads drop the team filter. --team <key-or-name> overrides LINEAR_TEAM per call only on issues create, projects create, cycles create, labels create, labels audit, projects audit, cycles list, statuses list and statuses get; the --team filter of issues list, projects list and labels list takes a key or name too. On these reads and statuses list|get, an empty or dash-led --team value refuses before any request rather than reading every team. Run auth-check --strict before the first mutation that needs a configured team in a project.
Every lane writes with one app token, and Linear lets that token write in every team, so linear.sh keeps writes in LINEAR_TEAM itself. Before any write it refuses issues create whose --team is another team, and issues update, bulk-update, activate, block, unblock, complete, archive and trash (or its alias delete) on an issue outside LINEAR_TEAM, judged by reading the issue's current team for each identifier or UUID, once per distinct reference per invocation. A failed team read refuses as refused=cross-team-unread before any write. Reads, comments create, add-relation and remove-relation run in any team. The refusal line is linear: refused=cross-team action=<verb> issue=<ID> team=<KEY> own-team=<KEY> route=peer-mail: give cross-team work to the overseer of that team's repository with lane-mail peer send --repo [REPO]. No setting turns the guard off. With no LINEAR_TEAM, an existing-issue write runs unchecked and prints linear: cross-team-guard=inactive.
Set LINEAR_APP_TOKEN or the client pair in the project's private env file (.env.local unless KENDEX_ENV_FILE names another); op:// references are supported. Use auth-mint on the host with the real pair to publish a token to the fleet. Credential precedence, expiry, caching and attribution: authentication.
LINEAR_API_KEY and KENDEX_USER_EMAIL, the operator's email, also belong in the private env file. Non-secret defaults belong in committed kendex.settings.toml [env]. The kendex app's Customize tab writes the key, team and email. A LINEAR_API_KEY from project files beats an inherited key. When the personal key is selected, auth-check warns with fingerprints if it shadows a different inherited key. Every other key uses process environment precedence over the private env file.
Shared label maintenance
LINEAR_TEAM requires a target before writes that do not address an issue; it does not restrict an API key or check a label's owning team. auth-check verifies authentication and the local target, not the key's permission mask. Inspect key permissions in Linear settings; report fingerprints only.
Before changing a label definition, read its ID, team, parent and group status. An empty team means workspace scope. Read issue use across affected teams and check references in their manifests, scripts, gates and generated instructions. A team-restricted key cannot establish workspace-wide issue use.
The workspace owner coordinates shared label changes with affected repository maintainers. A repository taxonomy names that owner. Keep generic labels shared and project-specific labels team-scoped. Obtain approval for the concrete affected set and the exact proposed change before any shared-label definition change, replacement or deletion. Issue-label assignment authority does not authorize changing a shared label definition.
Prepare dependent repository corrections before the label change. After an authorized change, refresh each affected inventory, render instructions from their source, and run its taxonomy and repository checks. Record the label IDs, issue assignments and repository commits together. If the API cannot change scope, prepare a replacement plan with history and recovery limits before requesting migration approval.
Issue Creation Routing
Orchestration and review sessions file through the TPM pipeline (project-management skill), which owns labels, project, priority, estimate, and relations. An owner-authorized, well-specified single filing is judged in the filing session, with no analysis agent or audit JSON: project-management workflows/audit-issues.md § 4.1.
issues create needs a LINEAR_AGENT_LABELS label before API calls when set; --no-agent-label allows bare creates. Unless LINEAR_REQUIRE_REACH is set empty, create needs Reached by: and, with --review-born --priority 2, Symptom:; placeholders and null tokens are absent. Under that key, authored create/update/bulk-update bodies refuse a checkbox outside ## Done when, an invalid Post-merge: trigger or Deadline, or a missing nonempty quoted > **Story:** and > **Why this matters:** opening. A header over 500 characters prints a linear: advisory=issue-header-length line and writes (issues --help). Write the quoted Story and Why this matters opening for the owner, by project-management templates/issue-description-template.md and communication references/reports.md § Work-item descriptions and comments; an opening holding a file path, a Slack or mailbox id or a UTC time stamp prints a linear: advisory=issue-opening-detail line and writes. Filing-line and review-born rules: project-management SKILL.md § Disposition, Name what reaches it.
Under a declared label taxonomy (project-management references/labels.md § Project Taxonomy Contract), issues create, issues update --labels, issues bulk-update --labels, issues activate and issues block refuse before any write a label it does not declare, naming the label and the taxonomy file. The taxonomy check does not refuse an undeclared label the issue already carries. issues create refuses declared labels absent from Linear. labels create and labels update --name refuse an undeclared name, and a name a workspace label already uses (on create, only a --team label). labels audit lists the undeclared labels on the team's open issues and the same-name team/workspace pairs. With no taxonomy declared, none of this applies.
Under a declared project map, issues create, issues update --project and issues bulk-update --project refuse a project off it, and projects audit lists what lies outside it: the project-management skill's references/project-map.md § Routing and § Audit.
Attachments
issues create, issues update, and comments create take repeatable --attach PATH. Unreadable files refuse before API work. Images embed as markdown appended to the description/body being written; an issues update without --description appends to the stored description. Other files become issue attachments or comment links. Existing-issue uploads need a live ID.
Issue results report attachments_requested and ordered {url, repo_path} receipts in attachments after all bindings succeed. Creates/field updates need default JSON for receipts; successful --format=ids creates print only the ID.
A failed issues create or issues update upload or binding exits nonzero with JSON naming what to resume, and issues --help gives the resume route; a failed upload writes no issue fields. A comments create upload failure only exits nonzero with its stderr cause.
Resolve a cited artifact
Read a cited repository path when it exists. When it is absent, list the issue's attachments; a failed list is a read failure to report, not a missing attachment.
linear.sh attachments list [ISSUE_ID]
linear.sh attachments fetch [URL] --output tmp/[FILENAME]
Read the issue description's **Artifacts** list first: its [repository path](url) links name the current copy, on this issue or another, so the link whose label is the cited path selects the entry with that url, whatever its context. With no such link, match the original cited repository path against repo_path, scoped to that issue or the research/source issue its brief explicitly names. For attachments with no repo_path and no such link, accept a filename match only when it is unique within that issue. Use an attachment URL in the brief to select the matching url when references collide. Fetch the match into tmp/ and read that file; keep the repository path as the tracker reference. Resolve companion files, such as a plan's JSON or research metadata, the same way. Do not write a machine's tmp/ path into an issue or delegation for another checkout.
No match leaves the calling workflow's missing-file behavior unchanged. Multiple matches without a distinguishing reference require clarification. A failed fetch is a download failure; report it instead of treating the research as absent. Consumers without attachments keep reading repository files as before.
Blocked Label vs Issue Relations
For a cross-team relation, select a minted app token through LINEAR_APP_TOKEN (credential selection). Confirm credential: "app-token" with auth-check and check that the actor can access both teams.
A blocker that is itself a Linear issue is a relation (--blocked-by); an external one (vendor, license) is the blocked label plus a comment.
Blocking relations may connect issues with the same direct parent, two top-level issues, or a blocked leaf to an issue outside its ancestors. An ancestor/descendant pair is refused at any depth; use --related for traceability. The two issues need not share a project. One query reads child status and parent chains. An incomplete chain refuses.
A blocking relation pointing at a Done or Canceled issue is satisfied history, not stale metadata. The relation stays for provenance; never remove or "fix" it, and audits must never classify it as stale. The only legitimate audit output for a completed-blocker relation is a scheduling signal ("gates cleared, ready to schedule"). issues remove-relation refuses such a relation before any write, with one linear: refused=completed-blocker line. Its --peer-rule-violation route, the project-management skill's tpm-audit structural repair, removes one only when the pair breaks the blocking-level rule above.
Normalized issue lists, gets, bulk gets, bundles, recursive children, relation reads, and session status keep each blocking relation in blocked_by and list only nonterminal blockers in blocked_by_open.
Option Behavior
What each option accepts: issues --help. Refused before any write, on create and update: --cycle on a non-UUID, --project/--milestone/--assignee on a reference that matches nothing, and --priority on an out-of-range value. Resolve state names from statuses list for the issue's team. Verifying is a started state after In Review. The verification pass reads its post-merge checks.
A name selects one project on issues create / update / bulk-update --project, projects get, projects list-dependencies, milestones --project, and initiatives add-project / remove-project. Issue creation resolves the name within LINEAR_TEAM or --team. Updates and bulk updates resolve it within each issue's recorded team. Multiple live matches in that team refuse with each project's UUID and team name. A canceled project sharing the name loses to the live one, and a name with no live match is refused, naming each match and its state; pass a UUID to reach a canceled project. Name filters never resolve: issues list --project and documents list --project match on the name alone, so their results can mix a live project with its canceled twin.
--labels REPLACES the whole issue-label set. Fetch current labels, compute the final set, validate it against labels list --max --format=safe (which reports is_group so parent/group labels can be rejected), then pass the complete set. issues update --labels and issues activate --agent resolve names live against the issue's own team and workspace labels. An unresolved name refuses before mutation and names the team and label. --clear-labels is the only way to empty the set.
agent:*labels are mutually exclusive, one per issue;issues activateapplies them with the "In Progress" transition (semantics:issues --help). Its default output is JSON;--format idsor--format=idsprints only the identifier.issues activateassigns an issue nobody is assigned to the user whose email isKENDEX_USER_EMAIL, in the same mutation, and never replaces an assignee. It says which happened in one stderr line,assignee-set,assignee-keptorassignee-skippedwith itscause=, and in the result'sassigneefield; a skip still activates, and a failed issue read, users lookup or update fails the activation with no line (lines:issues --help).--assigneeon create and update takes the same address form: a value containing@matches a user's whole email, case-insensitively; a user id is sent as given.issues updateandbulk-updaterefuse completed-type states if the new description has open Done-when boxes or checked boxes without indented, nonblankEvidence:directly below. Refusals list the issue, boxes andfix=issues complete. Bulk lists each refusal before writes. Partial failures emit per-issue results,partial: true, and exit nonzero.issues blockapplies theblockedlabel, creates the blocking relation, and comments. A rejected relation fails the command.issues completeposts an optional summary before setting Done. Use--done-when-met allor a comma-separated list of box numbers to tick verified Done-when boxes in the same update that sets the state. With--post-merge-at, it validates the checklist against the merged PR'smergedAtand sets Verifying while a post-merge box remains open. It requires every branch-provable box to be checked. Each post-merge box uses the project-management skill's Done-when form and trigger deadline window. Every call parses the Done-when checklist. An open branch box, or an open box outside## Done when, refuses before any summary or state write. Without--post-merge-at, an open post-merge box keeps the current started state; other states refuse. Every checked box needs a nonblankEvidence:line indented directly below it.--done-when-mettakes--evidence-file PATH, with oneN: textline per box, and writes evidence with the tick and state. Select already-ticked boxes to add evidence from their existing evidence comments. An item with no Done-when section, a container among them, completes as Done. orch's container-close ticks a container's one box, "Every child Done or cancelled", as it sets it Done; an all-canceled container is set Canceled, its box open. container-close owns child validation, the bundle summary and the Done transition, and needs no merge time. Its default output is JSON;--format idsor--format=idsprints only the identifier. A failed state update after a posted summary exits nonzero and reports on stderr in either format.
validate-completion
The pre-merge check on state plus summary comment: issues validate-completion. The expected-state matrix is in issues --help § Validate-Completion: session root vs bundle children vs --container parents, and the fail-closed flag pairing.
A "labelIds not exclusive child labels" error means two labels from one exclusive group. Requires Bash 4.0+ (macOS system Bash 3.2 is unsupported), curl, and jq.
04 同仓库更多 Skills
youtube-publish
Load to draft a YouTube upload, comment or reply, or send a draft after the user's recorded approval.
xcode-run
Load to install or dispatch a macOS GitHub Actions build, test or simulator screenshot run for an Xcode project.
worktree
Load to create, list, remove, push, or repair a git worktree.
social-media-content-calendar
Load to plan a social media campaign, build a content calendar, or adapt existing material into post drafts.
slack
Load to bind an overseer's mailbox to a private Slack channel, run or check the relay, or post an alert or a file to Slack.
second-opinion
Load for a cross-model review, challenge, audit, or quick consult.