Class: Agentilda::Linear::API
- Inherits:
-
Object
- Object
- Agentilda::Linear::API
- Defined in:
- lib/agentilda/linear/api.rb
Overview
Linear's GraphQL API, wrapped as thinly as GitHub wraps
gh, and for the same reason: it is a seam. Every example in the suite
injects a transport here, so nothing in the tests reaches Linear.
Only the dozen operations an import needs are here. This is not a client
library, and it should not grow into one — anything Linear can do that
.plans cannot express does not belong in a tool whose whole premise is
that the folder is the source of truth.
Constant Summary collapse
- ENDPOINT =
"https://api.linear.app/graphql"- TOKEN_VARIABLE =
The environment variable holding a personal API key.
"LINEAR_API_KEY"
Class Method Summary collapse
-
.token_from_env ⇒ String?
The token, from the environment.
Instance Method Summary collapse
-
#create_issue(input) ⇒ Hash
{id:, identifier:, url:}. -
#create_label(name, team_id) ⇒ Hash
{id:, name:}. -
#create_project(input) ⇒ Hash
{id:, name:, url:}. -
#initialize(token: nil, transport: nil, endpoint: ENDPOINT) ⇒ API
constructor
A new instance of API.
- #link(issue_id:, url:, title:) ⇒ void
-
#projects(team_id) ⇒ Array<Hash>
{id:, name:, url:}. -
#query(query, **variables) ⇒ Hash
The
dataobject. -
#team(key) ⇒ Hash
The team, its workflow states and its labels, in one round trip.
- #update_issue(id, input) ⇒ Hash
- #update_project(id, input) ⇒ Hash
Constructor Details
#initialize(token: nil, transport: nil, endpoint: ENDPOINT) ⇒ API
Returns a new instance of API.
29 30 31 32 33 34 35 36 37 |
# File 'lib/agentilda/linear/api.rb', line 29 def initialize(token: nil, transport: nil, endpoint: ENDPOINT) @token = token @transport = transport @endpoint = endpoint return if transport || (token && !token.empty?) raise Error, "no Linear token. Set #{TOKEN_VARIABLE}, or use the MCP transport:\n " \ "agentilda linear import <TEAM> -p <PROJECT> --format json" end |
Class Method Details
.token_from_env ⇒ String?
Returns the token, from the environment.
24 |
# File 'lib/agentilda/linear/api.rb', line 24 def self.token_from_env = ENV[TOKEN_VARIABLE].to_s.strip.then { |t| t.empty? ? nil : t } |
Instance Method Details
#create_issue(input) ⇒ Hash
Returns {id:, identifier:, url:}.
67 |
# File 'lib/agentilda/linear/api.rb', line 67 def create_issue(input) = unwrap(query(ISSUE_CREATE, input:), "issueCreate", "issue") |
#create_label(name, team_id) ⇒ Hash
Returns {id:, name:}.
77 78 79 |
# File 'lib/agentilda/linear/api.rb', line 77 def create_label(name, team_id) unwrap(query(LABEL_CREATE, input: {name:, teamId: team_id}), "issueLabelCreate", "issueLabel") end |
#create_project(input) ⇒ Hash
Returns {id:, name:, url:}.
58 |
# File 'lib/agentilda/linear/api.rb', line 58 def create_project(input) = unwrap(query(PROJECT_CREATE, input:), "projectCreate", "project") |
#link(issue_id:, url:, title:) ⇒ void
This method returns an undefined value.
85 86 87 |
# File 'lib/agentilda/linear/api.rb', line 85 def link(issue_id:, url:, title:) query(ATTACHMENT_CREATE, input: {issueId: issue_id, url:, title:}) end |
#projects(team_id) ⇒ Array<Hash>
Returns {id:, name:, url:}.
54 |
# File 'lib/agentilda/linear/api.rb', line 54 def projects(team_id) = query(PROJECTS, teamId: team_id).dig("team", "projects", "nodes").to_a |
#query(query, **variables) ⇒ Hash
Returns the data object.
93 94 95 96 97 98 99 |
# File 'lib/agentilda/linear/api.rb', line 93 def query(query, **variables) body = transport.call(query, variables) errors = body["errors"] raise Error, "Linear rejected the request: #{describe(errors)}" if errors&.any? body.fetch("data") { raise Error, "Linear returned no data" } end |
#team(key) ⇒ Hash
The team, its workflow states and its labels, in one round trip.
44 45 46 47 48 49 50 |
# File 'lib/agentilda/linear/api.rb', line 44 def team(key) node = query(TEAM, key: key.to_s.upcase).dig("teams", "nodes")&.first raise Error, "no Linear team has the key #{key.to_s.upcase}" unless node {id: node["id"], name: node["name"], key: node["key"], states: node.dig("states", "nodes").to_a, labels: node.dig("labels", "nodes").to_a} end |
#update_issue(id, input) ⇒ Hash
72 |
# File 'lib/agentilda/linear/api.rb', line 72 def update_issue(id, input) = unwrap(query(ISSUE_UPDATE, id:, input:), "issueUpdate", "issue") |
#update_project(id, input) ⇒ Hash
63 |
# File 'lib/agentilda/linear/api.rb', line 63 def update_project(id, input) = unwrap(query(PROJECT_UPDATE, id:, input:), "projectUpdate", "project") |