agentsclimarketplace

Linear hello world

Skill jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/linear-pack/skills/linear-hello-world

'Create your first Linear issue and query using the SDK and GraphQL API.From its SKILL.md

Install
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill linear-hello-world

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

5.8 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it

Linear Hello World

Overview

Create your first issue, query teams, and explore the Linear data model using the @linear/sdk. Linear's API is GraphQL-based -- the SDK wraps it with typed models, lazy-loaded relations, and pagination helpers.

Prerequisites

  • @linear/sdk installed (npm install @linear/sdk)
  • LINEAR_API_KEY environment variable set (starts with lin_api_)
  • Access to at least one Linear team

Instructions

Step 1: Connect and Identify

import { LinearClient } from "@linear/sdk";

const client = new LinearClient({ apiKey: process.env.LINEAR_API_KEY! });

// Get current authenticated user
const me = await client.viewer;
console.log(`Hello, ${me.name}! (${me.email})`);

// Get your organization
const org = await me.organization;
console.log(`Workspace: ${org.name}`);

Step 2: List Teams

Every issue in Linear belongs to a team. Teams have a short key (e.g., "ENG") used in identifiers like ENG-123.

const teams = await client.teams();
console.log("Your teams:");
for (const team of teams.nodes) {
  console.log(`  ${team.key} — ${team.name} (${team.id})`);
}

Step 3: Create Your First Issue

const team = teams.nodes[0];

const result = await client.createIssue({
  teamId: team.id,
  title: "Hello from Linear SDK!",
  description: "This issue was created using the `@linear/sdk` TypeScript SDK.",
  priority: 3, // 0=None, 1=Urgent, 2=High, 3=Medium, 4=Low
});

if (result.success) {
  const issue = await result.issue;
  console.log(`Created: ${issue?.identifier} — ${issue?.title}`);
  console.log(`URL: ${issue?.url}`);
}

Step 4: Query Issues

// Get recent issues from a team
const issues = await client.issues({
  filter: {
    team: { key: { eq: team.key } },
    state: { type: { nin: ["completed", "canceled"] } },
  },
  first: 10,
});

console.log(`\nOpen issues in ${team.key}:`);
for (const issue of issues.nodes) {
  const state = await issue.state;
  console.log(`  ${issue.identifier}: ${issue.title} [${state?.name}]`);
}

Step 5: Explore Workflow States

Each team has customizable workflow states organized by type: triage, backlog, unstarted, started, completed, canceled.

const states = await team.states();
console.log(`\nWorkflow states for ${team.key}:`);
for (const state of states.nodes) {
  console.log(`  ${state.name} (type: ${state.type}, position: ${state.position})`);
}

Step 6: Fetch a Single Issue by Identifier

// Search for a specific issue by its human-readable identifier
const searchResults = await client.issueSearch("ENG-1");
const found = searchResults.nodes[0];
if (found) {
  console.log(`\nFound: ${found.identifier}`);
  console.log(`  Title: ${found.title}`);
  console.log(`  Priority: ${found.priority}`);
  console.log(`  Created: ${found.createdAt}`);
  const assignee = await found.assignee;
  console.log(`  Assignee: ${assignee?.name ?? "Unassigned"}`);
}

Step 7: Raw GraphQL Query

The SDK exposes the underlying GraphQL client for custom queries.

const response = await client.client.rawRequest(`
  query TeamDashboard($teamKey: String!) {
    teams(filter: { key: { eq: $teamKey } }) {
      nodes {
        name
        key
        issues(first: 5, orderBy: updatedAt) {
          nodes {
            identifier
            title
            priority
            state { name type }
            assignee { name }
          }
        }
      }
    }
  }
`, { teamKey: "ENG" });

console.log(JSON.stringify(response.data, null, 2));

Error Handling

ErrorCauseSolution
Authentication requiredInvalid API keyRegenerate at Settings > Account > API
Entity not foundInvalid ID or no accessUse client.teams() first to get valid IDs
Validation errorMissing required fieldteamId and title are required for createIssue
Cannot read properties of nullAccessing nullable relationUse optional chaining: (await issue.assignee)?.name

Examples

Complete Hello World Script

import { LinearClient } from "@linear/sdk";

async function main() {
  const client = new LinearClient({ apiKey: process.env.LINEAR_API_KEY! });

  const me = await client.viewer;
  console.log(`Connected as ${me.name}\n`);

  const teams = await client.teams();
  const team = teams.nodes[0];

  // Create issue
  const result = await client.createIssue({
    teamId: team.id,
    title: "Hello from Linear SDK!",
    description: "Testing the API integration.",
    priority: 3,
  });

  if (result.success) {
    const issue = await result.issue;
    console.log(`Created: ${issue?.identifier} — ${issue?.url}`);

    // Read it back
    const fetched = await client.issue(issue!.id);
    console.log(`Verified: ${fetched.title}`);

    // Clean up
    await fetched.delete();
    console.log("Deleted test issue.");
  }
}

main().catch(console.error);

Resources

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,144. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.