Skip to content

Avilocap/linear-agents

Repository files navigation

Linear Agents

Note: 100% of the code in this project was generated using artificial intelligence (Anthropic's Claude Code).

Two AI agents that integrate natively with Linear using the Linear Agents platform:

  • Enrique — Enriches tasks with technical analysis
  • Devora — Implements changes and creates Pull Requests

How it works

Enrique (Task Enrichment)

When assigned to a task, Enrique:

  1. Downloads and processes attached media (images, videos with transcription)
  2. Analyzes the relevant codebases using Claude Code
  3. Updates the task description with:
    • Technical Analysis — Implementation approach with specific file references
    • Complexity Estimate — Low / Medium / High with justification
    • Acceptance Criteria — Functionality, UX, and Technical requirements

Devora (Implementation)

When assigned to a task, Devora:

  1. Creates isolated git worktrees for affected repositories
  2. Implements changes using Claude Code based on the technical analysis
  3. Commits, pushes, and creates Pull Requests on GitHub
  4. Links PRs directly in the Linear activity panel
  5. Cleans up worktrees when PRs are merged or closed

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                           LINEAR AGENT FLOW                                 │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Linear (assign agent)                                                      │
│        │                                                                    │
│        ▼                                                                    │
│  AgentSessionEvent webhook                                                  │
│        │                                                                    │
│        ▼                                                                    │
│  Express server (OAuth authenticated)                                       │
│        │                                                                    │
│        ├──► Enrique: Claude Code analysis → Update description              │
│        │                                                                    │
│        └──► Devora: Git worktree → Claude Code → GitHub PR                  │
│                                                                             │
│  Activity updates streamed to Linear via Agent Activities API               │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│                           GITHUB CLEANUP                                    │
├─────────────────────────────────────────────────────────────────────────────┤
│  GitHub (PR closed) → Webhook → Remove worktree                             │
└─────────────────────────────────────────────────────────────────────────────┘

Key components:

  • Express receives webhooks from Linear and GitHub
  • OAuth tokens authenticate API calls (auto-refresh supported)
  • Agent Activities provide real-time progress in Linear's native UI
  • Claude Code (claude -p) analyzes and implements in non-interactive mode
  • Git worktrees provide isolated environments for each implementation
  • GitHub CLI (gh) creates Pull Requests automatically
  • Cloudflare Tunnel exposes the local server with a fixed URL

Setup

Requirements

Installation

git clone https://github.com/Avilocap/linear-agents.git
cd linear-agents
npm install
cp .env.example .env

Create Linear OAuth Apps

You need two OAuth Apps in Linear (one per agent identity):

  1. Go to Linear Settings → API → OAuth Applications → New Application

  2. Create Enrique app:

    • Name: Enrique
    • Redirect URI: https://your-domain.com/oauth/callback
    • Webhook URL: https://your-domain.com/webhook/agent/enrique
    • Webhook events: Enable Agent session events
    • Capabilities: Enable Assignable and Mentionable
  3. Create Devora app:

    • Name: Devora
    • Redirect URI: https://your-domain.com/oauth/callback
    • Webhook URL: https://your-domain.com/webhook/agent/devora
    • Webhook events: Enable Agent session events
    • Capabilities: Enable Assignable and Mentionable
  4. Copy credentials to .env:

ENRIQUE_CLIENT_ID=...
ENRIQUE_CLIENT_SECRET=...
ENRIQUE_WEBHOOK_SECRET=...

DEVORA_CLIENT_ID=...
DEVORA_CLIENT_SECRET=...
DEVORA_WEBHOOK_SECRET=...

OAUTH_REDIRECT_URI=https://your-domain.com/oauth/callback

GitHub Webhook

For each repository that Devora will work with:

  1. Go to Repository Settings → Webhooks → Add webhook
  2. URL: https://your-domain.com/webhook/github
  3. Content type: application/json
  4. Secret: Save to GITHUB_WEBHOOK_SECRET
  5. Events: Select Pull requests only

Environment Variables

PORT=3000

# Linear OAuth Apps
ENRIQUE_CLIENT_ID=
ENRIQUE_CLIENT_SECRET=
ENRIQUE_WEBHOOK_SECRET=

DEVORA_CLIENT_ID=
DEVORA_CLIENT_SECRET=
DEVORA_WEBHOOK_SECRET=

OAUTH_REDIRECT_URI=https://your-domain.com/oauth/callback

# OpenAI (for video transcription)
OPENAI_API_KEY=

# GitHub
GITHUB_TOKEN=
GITHUB_WEBHOOK_SECRET=

# Optional
PROJECT_ROOT=/path/to/your/projects
LINEAR_TEAM_KEY=YOUR_TEAM

Cloudflare Tunnel

cloudflared login
cloudflared tunnel create linear-agents
cloudflared tunnel route dns linear-agents your-subdomain.yourdomain.com

Start & Install Agents

./start.sh

Then install each agent by visiting:

  • https://your-domain.com/oauth/install/enrique
  • https://your-domain.com/oauth/install/devora

Approve as admin in Linear. Tokens are stored in .tokens.json.

Endpoints

Method Path Auth Description
GET /oauth/install/:agent Start OAuth install flow
GET /oauth/callback OAuth callback
POST /webhook/agent/enrique Linear signature Enrique session events
POST /webhook/agent/devora Linear signature Devora session events
POST /webhook/github GitHub signature PR cleanup events
GET /health Health check

Usage

Assign an agent to a task

  1. Open a Linear task
  2. Click Delegate to agent (or use the a keyboard shortcut)
  3. Select Enrique or Devora

The agent will show real-time progress in Linear's native activity panel.

Mention an agent

You can also trigger agents by mentioning them in comments:

  • @Enrique analiza esta tarea
  • @Devora implementa esto

Unattended execution (macOS launchd)

Create plist files in ~/Library/LaunchAgents/:

  • com.zinkee.linear-agents.plist — Node server
  • com.zinkee.linear-agents-tunnel.plist — Cloudflare tunnel

Both with RunAtLoad and KeepAlive enabled.

# Start
launchctl load ~/Library/LaunchAgents/com.zinkee.linear-agents.plist
launchctl load ~/Library/LaunchAgents/com.zinkee.linear-agents-tunnel.plist

# Restart
./restart.sh

# Logs
tail -f logs/server.log

File Structure

linear-agents/
├── src/
│   ├── server.js          # Express server with OAuth + webhooks
│   ├── enricher.js        # Enrique agent logic
│   ├── implementer.js     # Devora agent logic
│   ├── activity-emitter.js # Linear Agent Activities client
│   ├── linear-client.js   # Authenticated GraphQL client
│   ├── token-store.js     # OAuth token persistence
│   └── worktree-manager.js # Git worktree management
├── .env.example
├── .tokens.json           # OAuth tokens (gitignored)
├── package.json
├── start.sh
└── restart.sh

License

MIT

About

Linear Agents: Enrique (task enrichment) + Devora (implementation)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors