linear

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Linear GraphQL

Linear GraphQL

Use this skill for raw Linear GraphQL work during Symphony app-server sessions.
在Symphony应用服务器会话期间,使用此技能执行原生Linear GraphQL相关工作。

Primary tool

核心工具

Use the
linear_graphql
client tool exposed by Symphony's app-server session. It reuses Symphony's configured Linear auth for the session.
Tool input:
json
{
  "query": "query or mutation document",
  "variables": {
    "optional": "graphql variables object"
  }
}
Tool behavior:
  • Send one GraphQL operation per tool call.
  • Treat a top-level
    errors
    array as a failed GraphQL operation even if the tool call itself completed.
  • Keep queries/mutations narrowly scoped; ask only for the fields you need.
使用Symphony应用服务器会话提供的
linear_graphql
客户端工具,它会复用当前会话中Symphony已配置的Linear认证信息。
工具输入:
json
{
  "query": "query or mutation document",
  "variables": {
    "optional": "graphql variables object"
  }
}
工具行为:
  • 每次工具调用仅发送一个GraphQL操作。
  • 即便工具调用本身执行完成,若返回结果中存在顶层
    errors
    数组,也视为GraphQL操作失败。
  • 保持查询/mutation的作用域尽可能窄,仅请求你需要的字段。

Discovering unfamiliar operations

查找不熟悉的操作

When you need an unfamiliar mutation, input type, or object field, use targeted introspection through
linear_graphql
.
List mutation names:
graphql
query ListMutations {
  __type(name: "Mutation") {
    fields {
      name
    }
  }
}
Inspect a specific input object:
graphql
query CommentCreateInputShape {
  __type(name: "CommentCreateInput") {
    inputFields {
      name
      type {
        kind
        name
        ofType {
          kind
          name
        }
      }
    }
  }
}
当你需要使用不熟悉的mutation、输入类型或对象字段时,可通过
linear_graphql
执行定向introspection查询。
列出所有mutation名称:
graphql
query ListMutations {
  __type(name: "Mutation") {
    fields {
      name
    }
  }
}
查看指定输入对象的结构:
graphql
query CommentCreateInputShape {
  __type(name: "CommentCreateInput") {
    inputFields {
      name
      type {
        kind
        name
        ofType {
          kind
          name
        }
      }
    }
  }
}

Common workflows

常用工作流

Query an issue by key, identifier, or id

按key、标识符或id查询issue

Use these progressively:
  • Start with
    issue(id: $key)
    when you have a ticket key such as
    MT-686
    .
  • Fall back to
    issues(filter: ...)
    when you need identifier search semantics.
  • Once you have the internal issue id, prefer
    issue(id: $id)
    for narrower reads.
Lookup by issue key:
graphql
query IssueByKey($key: String!) {
  issue(id: $key) {
    id
    identifier
    title
    state {
      id
      name
      type
    }
    project {
      id
      name
    }
    branchName
    url
    description
    updatedAt
    links {
      nodes {
        id
        url
        title
      }
    }
  }
}
Lookup by identifier filter:
graphql
query IssueByIdentifier($identifier: String!) {
  issues(filter: { identifier: { eq: $identifier } }, first: 1) {
    nodes {
      id
      identifier
      title
      state {
        id
        name
        type
      }
      project {
        id
        name
      }
      branchName
      url
      description
      updatedAt
    }
  }
}
Resolve a key to an internal id:
graphql
query IssueByIdOrKey($id: String!) {
  issue(id: $id) {
    id
    identifier
    title
  }
}
Read the issue once the internal id is known:
graphql
query IssueDetails($id: String!) {
  issue(id: $id) {
    id
    identifier
    title
    url
    description
    state {
      id
      name
      type
    }
    project {
      id
      name
    }
    attachments {
      nodes {
        id
        title
        url
        sourceType
      }
    }
  }
}
按以下优先级依次使用:
  • 如果你有工单key(例如
    MT-686
    ),优先使用
    issue(id: $key)
    查询。
  • 如果你需要按标识符语义搜索,可回退使用
    issues(filter: ...)
  • 拿到issue的内部id后,优先使用
    issue(id: $id)
    执行更精准的查询。
按issue key查询:
graphql
query IssueByKey($key: String!) {
  issue(id: $key) {
    id
    identifier
    title
    state {
      id
      name
      type
    }
    project {
      id
      name
    }
    branchName
    url
    description
    updatedAt
    links {
      nodes {
        id
        url
        title
      }
    }
  }
}
按标识符过滤查询:
graphql
query IssueByIdentifier($identifier: String!) {
  issues(filter: { identifier: { eq: $identifier } }, first: 1) {
    nodes {
      id
      identifier
      title
      state {
        id
        name
        type
      }
      project {
        id
        name
      }
      branchName
      url
      description
      updatedAt
    }
  }
}
将key转换为内部id:
graphql
query IssueByIdOrKey($id: String!) {
  issue(id: $id) {
    id
    identifier
    title
  }
}
已知内部id时查询issue详情:
graphql
query IssueDetails($id: String!) {
  issue(id: $id) {
    id
    identifier
    title
    url
    description
    state {
      id
      name
      type
    }
    project {
      id
      name
    }
    attachments {
      nodes {
        id
        title
        url
        sourceType
      }
    }
  }
}

Query team workflow states for an issue

查询issue所属团队的工作流状态

Use this before changing issue state when you need the exact
stateId
:
graphql
query IssueTeamStates($id: String!) {
  issue(id: $id) {
    id
    team {
      id
      key
      name
      states {
        nodes {
          id
          name
          type
        }
      }
    }
  }
}
在变更issue状态需要获取准确的
stateId
时,可先执行此查询:
graphql
query IssueTeamStates($id: String!) {
  issue(id: $id) {
    id
    team {
      id
      key
      name
      states {
        nodes {
          id
          name
          type
        }
      }
    }
  }
}

Edit an existing comment

编辑已有评论

Use
commentUpdate
through
linear_graphql
:
graphql
mutation UpdateComment($id: String!, $body: String!) {
  commentUpdate(id: $id, input: { body: $body }) {
    success
    comment {
      id
      body
    }
  }
}
通过
linear_graphql
使用
commentUpdate
graphql
mutation UpdateComment($id: String!, $body: String!) {
  commentUpdate(id: $id, input: { body: $body }) {
    success
    comment {
      id
      body
    }
  }
}

Create a comment

新建评论

Use
commentCreate
through
linear_graphql
:
graphql
mutation CreateComment($issueId: String!, $body: String!) {
  commentCreate(input: { issueId: $issueId, body: $body }) {
    success
    comment {
      id
      url
    }
  }
}
通过
linear_graphql
使用
commentCreate
graphql
mutation CreateComment($issueId: String!, $body: String!) {
  commentCreate(input: { issueId: $issueId, body: $body }) {
    success
    comment {
      id
      url
    }
  }
}

Move an issue to a different state

移动issue到其他状态

Use
issueUpdate
with the destination
stateId
:
graphql
mutation MoveIssueToState($id: String!, $stateId: String!) {
  issueUpdate(id: $id, input: { stateId: $stateId }) {
    success
    issue {
      id
      identifier
      state {
        id
        name
      }
    }
  }
}
使用
issueUpdate
并传入目标
stateId
graphql
mutation MoveIssueToState($id: String!, $stateId: String!) {
  issueUpdate(id: $id, input: { stateId: $stateId }) {
    success
    issue {
      id
      identifier
      state {
        id
        name
      }
    }
  }
}

Attach a GitHub PR to an issue

为issue关联GitHub PR

Use the GitHub-specific attachment mutation when linking a PR:
graphql
mutation AttachGitHubPR($issueId: String!, $url: String!, $title: String) {
  attachmentLinkGitHubPR(
    issueId: $issueId
    url: $url
    title: $title
    linkKind: links
  ) {
    success
    attachment {
      id
      title
      url
    }
  }
}
If you only need a plain URL attachment and do not care about GitHub-specific link metadata, use:
graphql
mutation AttachURL($issueId: String!, $url: String!, $title: String) {
  attachmentLinkURL(issueId: $issueId, url: $url, title: $title) {
    success
    attachment {
      id
      title
      url
    }
  }
}
关联PR时请使用GitHub专属的attachment mutation:
graphql
mutation AttachGitHubPR($issueId: String!, $url: String!, $title: String) {
  attachmentLinkGitHubPR(
    issueId: $issueId
    url: $url
    title: $title
    linkKind: links
  ) {
    success
    attachment {
      id
      title
      url
    }
  }
}
如果你只需要普通的URL附件,不需要GitHub专属的链接元数据,可使用:
graphql
mutation AttachURL($issueId: String!, $url: String!, $title: String) {
  attachmentLinkURL(issueId: $issueId, url: $url, title: $title) {
    success
    attachment {
      id
      title
      url
    }
  }
}

Introspection patterns used during schema discovery

schema查找时使用的introspection模式

Use these when the exact field or mutation shape is unclear:
graphql
query QueryFields {
  __type(name: "Query") {
    fields {
      name
    }
  }
}
graphql
query IssueFieldArgs {
  __type(name: "Query") {
    fields {
      name
      args {
        name
        type {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
            }
          }
        }
      }
    }
  }
}
当不确定字段或mutation的准确结构时使用:
graphql
query QueryFields {
  __type(name: "Query") {
    fields {
      name
    }
  }
}
graphql
query IssueFieldArgs {
  __type(name: "Query") {
    fields {
      name
      args {
        name
        type {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
            }
          }
        }
      }
    }
  }
}

Upload a video to a comment

上传视频到评论

Do this in three steps:
  1. Call
    linear_graphql
    with
    fileUpload
    to get
    uploadUrl
    ,
    assetUrl
    , and any required upload headers.
  2. Upload the local file bytes to
    uploadUrl
    with
    curl -X PUT
    and the exact headers returned by
    fileUpload
    .
  3. Call
    linear_graphql
    again with
    commentCreate
    (or
    commentUpdate
    ) and include the resulting
    assetUrl
    in the comment body.
Useful mutations:
graphql
mutation FileUpload(
  $filename: String!
  $contentType: String!
  $size: Int!
  $makePublic: Boolean
) {
  fileUpload(
    filename: $filename
    contentType: $contentType
    size: $size
    makePublic: $makePublic
  ) {
    success
    uploadFile {
      uploadUrl
      assetUrl
      headers {
        key
        value
      }
    }
  }
}
分三步执行:
  1. 调用
    linear_graphql
    fileUpload
    接口获取
    uploadUrl
    assetUrl
    以及所有需要的上传请求头。
  2. 使用
    curl -X PUT
    命令,携带
    fileUpload
    返回的所有请求头,将本地文件字节上传到
    uploadUrl
  3. 再次调用
    linear_graphql
    commentCreate
    (或
    commentUpdate
    )接口,将获取到的
    assetUrl
    加入评论内容中。
常用mutation:
graphql
mutation FileUpload(
  $filename: String!
  $contentType: String!
  $size: Int!
  $makePublic: Boolean
) {
  fileUpload(
    filename: $filename
    contentType: $contentType
    size: $size
    makePublic: $makePublic
  ) {
    success
    uploadFile {
      uploadUrl
      assetUrl
      headers {
        key
        value
      }
    }
  }
}

Usage rules

使用规则

  • Use
    linear_graphql
    for comment edits, uploads, and ad-hoc Linear API queries.
  • Prefer the narrowest issue lookup that matches what you already know: key -> identifier search -> internal id.
  • For state transitions, fetch team states first and use the exact
    stateId
    instead of hardcoding names inside mutations.
  • Prefer
    attachmentLinkGitHubPR
    over a generic URL attachment when linking a GitHub PR to a Linear issue.
  • Do not introduce new raw-token shell helpers for GraphQL access.
  • If you need shell work for uploads, only use it for signed upload URLs returned by
    fileUpload
    ; those URLs already carry the needed authorization.
  • 评论编辑、上传操作以及临时的Linear API查询请使用
    linear_graphql
  • 优先使用与你已知信息最匹配的最精准issue查找方式:key -> 标识符搜索 -> 内部id。
  • 进行状态流转时,请先获取团队状态列表,使用准确的
    stateId
    ,不要在mutation中硬编码状态名称。
  • 将GitHub PR关联到Linear issue时,优先使用
    attachmentLinkGitHubPR
    ,不要使用通用URL附件。
  • 不要新增使用裸token的shell工具来访问GraphQL。
  • 如果需要使用shell执行上传操作,仅对
    fileUpload
    返回的签名上传URL使用shell,这些URL已经携带了所需的授权信息。