onetaskgraph-linear 0.2.21

A onetaskgraph source over the Linear API.
Documentation
# llmlint: ignore-file[contracts_have_one_source_or_a_drift_gate] Linear exposes its schema only through an authenticated, unversioned explorer, so an authoritative automated freshness check would require the credential that this repository's explicitly non-required live lane must skip when absent; this documentation-derived subset pins the acceptance criterion's recorded 2026-08-24 contract instead.
# Documentation-derived Linear GraphQL schema subset, pinned 2026-08-24, with
# `projectDelete` re-observed and pinned 2026-08-29 from the same published schema, and
# the whole document contract below — `document`, `documents`, `Document`,
# `DocumentConnection`, `DocumentFilter`, the two document inputs, both document payloads
# and the three document mutations — re-observed and pinned 2026-09-01 from it.
# Only the read/write contract exercised by this plugin is retained.
type Query {
  viewer: User!
  issue(id: String!): Issue
  issues(first: Int!, after: String, filter: IssueFilter): IssueConnection!
  project(id: String!): Project
  projects(first: Int!, after: String, filter: ProjectFilter): ProjectConnection!
  document(id: String!): Document!
  documents(first: Int, after: String, filter: DocumentFilter): DocumentConnection!
  issueLabels(first: Int, after: String, filter: IssueLabelFilter): IssueLabelConnection!
  projectLabels(filter: ProjectLabelFilter): ProjectLabelConnection!
  teams(filter: TeamFilter): TeamConnection!
  workflowStates(filter: WorkflowStateFilter): WorkflowStateConnection!
  projectStatuses(filter: ProjectStatusFilter): ProjectStatusConnection!
}
type Mutation {
  issueCreate(input: IssueCreateInput!): IssuePayload!
  issueUpdate(id: String!, input: IssueUpdateInput!): IssuePayload!
  projectCreate(input: ProjectCreateInput!): ProjectPayload!
  projectUpdate(id: String!, input: ProjectUpdateInput!): ProjectPayload!
  issueRelationCreate(input: IssueRelationCreateInput!): IssueRelationPayload!
  projectRelationCreate(input: ProjectRelationCreateInput!): ProjectRelationPayload!
  issueRelationDelete(id: String!): DeletePayload!
  projectRelationDelete(id: String!): DeletePayload!
  issueDelete(id: String!): DeletePayload!
  projectDelete(id: String!): ProjectArchivePayload!
  documentCreate(input: DocumentCreateInput!): DocumentPayload!
  documentUpdate(id: String!, input: DocumentUpdateInput!): DocumentPayload!
  documentDelete(id: String!): DocumentArchivePayload!
}

type User {
  id: ID!
}
type Issue {
  id: ID!
  title: String!
  description: String
  url: String
  createdAt: DateTime
  updatedAt: DateTime
  state: WorkflowState!
  labels: IssueLabelConnection!
  project: Project
  relations(first: Int!, after: String): IssueRelationConnection!
  inverseRelations(first: Int!, after: String): IssueRelationConnection!
}
type Project {
  id: ID!
  name: String!
  description: String
  url: String
  createdAt: DateTime
  updatedAt: DateTime
  status: ProjectStatus!
  labels: ProjectLabelConnection!
  relations(first: Int!, after: String): ProjectRelationConnection!
  inverseRelations(first: Int!, after: String): ProjectRelationConnection!
}
# Linear's own first-class document. It carries no `labels` field and no status: the only
# types of the published schema with `labels` are Issue, Project, Team, Initiative and
# Organization, which is why this source reports a document's labels as none rather than
# standing a slot up beside a first-class type.
type Document {
  id: ID!
  title: String!
  content: String
  url: String!
  createdAt: DateTime!
  updatedAt: DateTime!
  project: Project
}
type WorkflowState {
  id: ID!
  name: String!
  type: String!
}
type ProjectStatus {
  id: ID!
  name: String!
  type: String!
}
type IssueLabel {
  id: ID!
  name: String!
  color: String
}
type ProjectLabel {
  id: ID!
  name: String!
  color: String
}
type IssueConnection {
  nodes: [Issue!]!
  pageInfo: PageInfo!
}
type ProjectConnection {
  nodes: [Project!]!
  pageInfo: PageInfo!
}
type IssueLabelConnection {
  nodes: [IssueLabel!]!
  pageInfo: PageInfo!
}
type ProjectLabelConnection {
  nodes: [ProjectLabel!]!
  pageInfo: PageInfo!
}
type DocumentConnection {
  nodes: [Document!]!
  pageInfo: PageInfo!
}
type IssueRelationConnection {
  nodes: [IssueRelation!]!
  pageInfo: PageInfo!
}
type ProjectRelationConnection {
  nodes: [ProjectRelation!]!
  pageInfo: PageInfo!
}
type IssueRelation {
  id: ID!
  type: String!
  issue: Issue
  relatedIssue: Issue
}
type ProjectRelation {
  id: ID!
  type: String!
  project: Project
  relatedProject: Project
}
type Team {
  id: ID!
}
type TeamConnection {
  nodes: [Team!]!
}
type WorkflowStateConnection {
  nodes: [WorkflowState!]!
}
type ProjectStatusConnection {
  nodes: [ProjectStatus!]!
}
type IssuePayload {
  success: Boolean!
  issue: Issue
}
type ProjectPayload {
  success: Boolean!
  project: Project
}
type IssueRelationPayload {
  success: Boolean!
  issueRelation: IssueRelation
}
type ProjectRelationPayload {
  success: Boolean!
  projectRelation: ProjectRelation
}
type DocumentPayload {
  success: Boolean!
  document: Document!
}
type DeletePayload {
  success: Boolean!
}
type DocumentArchivePayload {
  success: Boolean!
}
type ProjectArchivePayload {
  success: Boolean!
}
type PageInfo {
  hasNextPage: Boolean!
  endCursor: String
}
input IssueFilter {
  and: [IssueFilter!]
}
input ProjectFilter {
  and: [ProjectFilter!]
}
# `DocumentFilter.project` is a `ProjectFilter` rather than the `NullableProjectFilter`
# `IssueFilter.project` is, so it carries no `null:` member and Linear cannot be asked for
# the documents belonging to no project. That predicate is the one this source applies to
# a fetched page itself.
input DocumentFilter {
  project: ProjectFilter
  and: [DocumentFilter!]
}
input TeamFilter {
  key: StringComparator
}
input WorkflowStateFilter {
  name: StringComparator
  team: IdComparator
}
input ProjectStatusFilter {
  name: StringComparator
}
input ProjectLabelFilter {
  name: StringComparator
}
input IssueLabelFilter {
  name: StringComparator
}
input StringComparator {
  eqIgnoreCase: String
}
input IdComparator {
  id: IdEquality
}
input IdEquality {
  eq: String
}
input IssueCreateInput {
  teamId: String!
  title: String!
  description: String
  stateId: String!
  labelIds: [String!]!
  projectId: String
}
input IssueUpdateInput {
  title: String!
  description: String
  stateId: String!
  labelIds: [String!]!
  projectId: String
}
input ProjectCreateInput {
  teamIds: [String!]!
  name: String!
  description: String
  statusId: String!
  labelIds: [String!]!
}
input ProjectUpdateInput {
  name: String!
  description: String
  statusId: String!
  labelIds: [String!]!
}
# Nullability as published: `title` alone is required of a create, and every member of an
# update is optional.
input DocumentCreateInput {
  title: String!
  content: String
  projectId: String
  teamId: String
}
input DocumentUpdateInput {
  title: String
  content: String
  projectId: String
}
input IssueRelationCreateInput {
  issueId: String!
  relatedIssueId: String!
  type: String!
}
input ProjectRelationCreateInput {
  projectId: String!
  relatedProjectId: String!
  type: String!
}
scalar DateTime