mirror of
https://github.com/magnus919/agent-skills.git
synced 2026-09-16 22:16:52 +03:00
b8a5092c26
## What this adds Implements the request in #287 and the Tier 1 audit gaps for the `linear` skill's `scripts/linear` CLI, reconciled against the live Linear GraphQL schema. ### New verbs - `linear project update` — name, description, status, start/target dates, priority, with the same `--dry-run`/`--confirm` gate as issue mutations, and a local 255-character description guard matching Linear's `projectUpdate` limit (Linear rejects longer descriptions with a generic error). - `linear issue archive` / `linear issue unarchive` — both gated, returning `IssueArchivePayload.entity`. - `linear state list --team ENG` — first-class workflow-state discovery (previously states were only visible in the `issue move` failure path). ### Richer issue verbs - `issue create` now accepts `--project`, `--parent`, `--assignee`, `--label` (repeatable), `--state`, `--due`. - `issue update` now accepts `--assignee`, `--label` (add), `--remove-label`, `--due`, `--project`. ### Resolution rules (all require exactly one match, mirroring `resolve_team`) - Project: UUID or exact name - Parent: issue identifier or UUID - Assignee: exact name, display name, or email (via `users`) - Label: exact name within the issue's team (via `team.labels`) - Workflow state: exact name within the issue's team (existing `team.states` resolver, now reusable for `--state` on create) - Project status: exact name or type (via `projectStatuses`) ### Docs, tests, evals - SKILL.md command map, state-change gate, and error/recovery sections; README; `domain-and-workflows.md` (project semantics + 255-char limit), `graphql-contract.md` (resolution queries), `integration-boundaries.md` (intentional exclusions list), `sources.md` (2026-08-05 schema re-verification note). - 15 new offline tests (45 total) covering resolution, gates, dry-run intent, payload shapes, and field guards. - Added a sixth eval case (`safe-project-and-issue-mutations`). ## Validation - `python3 -m unittest linear/tests/test_linear.py` — 45/45 pass - `python3 scripts/validate-evals.py`, `ruby scripts/validate-skills.rb`, `python3 scripts/check-artifacts.py`, `python3 scripts/eval-coverage.py --modified-from origin/main`, skill-quality validator, marketplace/codex/llms freshness, jscpd — all green locally Closes #287 Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
46 lines
3.1 KiB
Markdown
46 lines
3.1 KiB
Markdown
# GraphQL Contract
|
|
|
|
Endpoint: `https://api.linear.app/graphql`. Send JSON GraphQL requests with `Content-Type:
|
|
application/json`. A personal API key is the value of the `Authorization` header. An OAuth access
|
|
token is sent in the `Authorization` header with the `Bearer ` prefix.
|
|
|
|
This CLI supports bounded reads for teams, issues, documents, projects, cycles, and workflow
|
|
states, plus issue create, update, move, archive, unarchive, and comment mutations, and project
|
|
update. Use `raw` for a documented operation outside that surface. Issue reads accept a UUID or
|
|
shorthand identifier. Document reads accept a UUID, slug ID, or Linear document URL; slug lookup
|
|
uses the `documents` filter.
|
|
|
|
Friendly-name resolution uses bounded queries: teams via the `teams` connection, users by exact
|
|
name/email via the `users` connection, labels within a team via `team.labels`, project statuses via
|
|
`projectStatuses`, and workflow states within a team via `team.states`. Each resolver requires
|
|
exactly one match and fails with the available names on ambiguity. Resolvers query at most 100
|
|
items; a workspace or team with more matches than the first page cannot be resolved by name.
|
|
|
|
For personal scripts, a personal API key is the simplest authentication method. OAuth is intended
|
|
for applications acting on behalf of users; access tokens are sent with the Bearer prefix. This CLI
|
|
does not initiate OAuth, store credentials, refresh tokens, or print either supported credential.
|
|
|
|
Filter input supports equality, inequality, collection membership, comparisons for number/date
|
|
fields, and string operators such as `contains` and `startsWith`. Relationship filters can narrow
|
|
results by related team, state, assignee, project, or labels. Prefer these filters to client-side
|
|
filtering and ask for only fields needed for the task.
|
|
|
|
All connections use Relay cursor pagination: request `first` and then pass `pageInfo.endCursor` as
|
|
`after` while `hasNextPage` is true. The CLI intentionally does not automatically paginate; keep
|
|
reads bounded with `--limit`. Use server filters rather than downloading a workspace and filtering
|
|
locally.
|
|
|
|
Check GraphQL's `errors` array even on HTTP 200 because data can be partial. Rate limits and query
|
|
complexity are reported in response headers. As accessed on 2026-07-17, the official rate-limit
|
|
page contains a conflicting API-key request limit (5,000 in prose and 2,500 in its table); inspect
|
|
current headers and documentation rather than hard-coding either value. It also documents API-key
|
|
complexity at 3,000,000 points per hour and a 10,000-point maximum for one query.
|
|
|
|
Linear does not version this GraphQL API. Inspect schema deprecations and the `[API]` changelog
|
|
before relying on a field. When a query fails after a schema change, re-run public introspection in
|
|
Apollo Studio, update the narrow field selection, and add an offline contract test before release.
|
|
|
|
Archived records are excluded from paginated responses by default and can be included with
|
|
`includeArchived: true` when the connection supports it. Do not add polling loops for updates:
|
|
Linear recommends webhooks for applications that need near-real-time changes.
|