Setup
1. Create a Linear OAuth app
- Go to linear.app/settings/api
- Create a new application
- Set the callback URL:
https://your-host/api/auth/linear/callback - Note the Client ID and Client Secret
2. Configure environment variables
3. Connect via OAuth
/api/auth/linear/callback stores the access token and associates it with the current user session.
Webhook Events
Linear webhooks arrive at/api/webhooks/linear. Supported event types:
| Event | Action |
|---|---|
Issue.created | Creates a profClaw task |
Issue.updated | Updates local ticket state |
Comment.created | Syncs comment to profClaw |
IssueLabel.created | Updates label mapping |
State Mapping
Linear uses workflow states per team. The Linear adapter maps these to profClaw statuses:| Linear State Type | profClaw Status |
|---|---|
triage | open |
backlog | open |
unstarted | open |
started | in_progress |
completed | closed |
cancelled | cancelled |
Priority Mapping
| Linear Priority | profClaw Priority |
|---|---|
| Urgent (1) | critical |
| High (2) | high |
| Medium (3) | medium |
| Low (4) | low |
| No priority (0) | low |
Label Mapping
Linear labels are synced as profClaw ticket labels. TheLabelMapper (src/integrations/linear.ts) maintains a cache of the label ID-to-name mapping per team.
Bidirectional Sync
Configure the Linear sync adapter insettings.yml:
updatedAt cursor. Pushes happen immediately on local ticket mutations.
Linear Client
TheLinearClient class (src/integrations/linear-client.ts) wraps the Linear GraphQL API:
createIssue(input)- Create a new issueupdateIssue(id, input)- Update title, description, state, priority, or labelsdeleteIssue(id)- Archive an issuegetIssue(id)- Fetch a single issue with state and labelslistIssues(options)- Paginated list with cursor supportaddComment(issueId, body)- Add a commentgetTeamStates(teamId)- Fetch workflow states for mappinggetTeamLabels(teamId)- Fetch label definitions
Authorization: Bearer <token> header.