openclaw-linear 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -58
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +80 -3
- package/dist/index.js.map +1 -1
- package/dist/linear-api.d.ts +13 -0
- package/dist/linear-api.d.ts.map +1 -0
- package/dist/linear-api.js +120 -0
- package/dist/linear-api.js.map +1 -0
- package/dist/tools/linear-comment-tool.d.ts +3 -0
- package/dist/tools/linear-comment-tool.d.ts.map +1 -0
- package/dist/tools/linear-comment-tool.js +113 -0
- package/dist/tools/linear-comment-tool.js.map +1 -0
- package/dist/tools/linear-issue-tool.d.ts +3 -0
- package/dist/tools/linear-issue-tool.d.ts.map +1 -0
- package/dist/tools/linear-issue-tool.js +240 -0
- package/dist/tools/linear-issue-tool.js.map +1 -0
- package/dist/tools/linear-project-tool.d.ts +3 -0
- package/dist/tools/linear-project-tool.d.ts.map +1 -0
- package/dist/tools/linear-project-tool.js +126 -0
- package/dist/tools/linear-project-tool.js.map +1 -0
- package/dist/tools/linear-relation-tool.d.ts +3 -0
- package/dist/tools/linear-relation-tool.d.ts.map +1 -0
- package/dist/tools/linear-relation-tool.js +148 -0
- package/dist/tools/linear-relation-tool.js.map +1 -0
- package/dist/tools/linear-team-tool.d.ts +3 -0
- package/dist/tools/linear-team-tool.d.ts.map +1 -0
- package/dist/tools/linear-team-tool.js +64 -0
- package/dist/tools/linear-team-tool.js.map +1 -0
- package/dist/{queue-tool.d.ts → tools/queue-tool.d.ts} +1 -1
- package/dist/tools/queue-tool.d.ts.map +1 -0
- package/dist/{queue-tool.js → tools/queue-tool.js} +19 -4
- package/dist/tools/queue-tool.js.map +1 -0
- package/dist/work-queue.d.ts +8 -3
- package/dist/work-queue.d.ts.map +1 -1
- package/dist/work-queue.js +60 -14
- package/dist/work-queue.js.map +1 -1
- package/openclaw.plugin.json +6 -1
- package/package.json +2 -2
- package/skills/linear/SKILL.md +126 -0
- package/dist/queue-tool.d.ts.map +0 -1
- package/dist/queue-tool.js.map +0 -1
- package/skills/linear-queue/SKILL.md +0 -47
package/README.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# openclaw-linear
|
|
2
2
|
|
|
3
|
-
Linear
|
|
3
|
+
Linear integration for [OpenClaw](https://github.com/nichochar/openclaw). Receives Linear webhook events, routes them to agents, and provides tools for managing issues, comments, projects, teams, and relations via the Linear GraphQL API.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **Webhook handler** — receives Linear webhook events with HMAC signature verification (timing-safe), duplicate delivery detection, and body size limits
|
|
8
8
|
- **Event router** — filters by team and event type, routes issue assignments and comment mentions to the configured agent
|
|
9
9
|
- **Debounced dispatch** — batches events within a configurable window before dispatching
|
|
10
|
-
- **Work queue** — deterministic queue
|
|
11
|
-
- **Crash recovery** — resets stale `in_progress` queue items to `pending` on
|
|
10
|
+
- **Work queue** — deterministic queue writes structured items with priority sorting, deduplication, and 24h auto-cleanup — no LLM tokens spent on triage
|
|
11
|
+
- **Crash recovery** — resets stale `in_progress` queue items to `pending` on startup
|
|
12
|
+
- **Direct API integration** — all tools call the Linear GraphQL API directly, no external CLI binary required
|
|
12
13
|
|
|
13
14
|
## Install
|
|
14
15
|
|
|
@@ -23,17 +24,18 @@ Add the plugin to your OpenClaw config. Each OpenClaw instance runs one agent
|
|
|
23
24
|
```yaml
|
|
24
25
|
plugins:
|
|
25
26
|
linear:
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
apiKey: "lin_api_..." # Linear API key (required)
|
|
28
|
+
webhookSecret: "your-signing-secret" # Webhook secret (required)
|
|
29
|
+
agentMapping: # Filter: only handle events for these Linear users
|
|
28
30
|
"linear-user-uuid": "titus"
|
|
29
|
-
teamIds: ["ENG", "OPS"]
|
|
30
|
-
eventFilter: ["Issue", "Comment"]
|
|
31
|
-
debounceMs: 30000
|
|
32
|
-
stateActions:
|
|
31
|
+
teamIds: ["ENG", "OPS"] # Optional: filter to specific teams (empty = all)
|
|
32
|
+
eventFilter: ["Issue", "Comment"] # Optional: filter event types (empty = all)
|
|
33
|
+
debounceMs: 30000 # Optional: batch window in ms (default: 30000)
|
|
34
|
+
stateActions: # Optional: map state types/names to queue actions
|
|
33
35
|
backlog: "add"
|
|
34
36
|
unstarted: "add"
|
|
35
37
|
started: "ignore"
|
|
36
|
-
"In Review": "remove"
|
|
38
|
+
"In Review": "remove" # State names override type matches (case-insensitive)
|
|
37
39
|
completed: "remove"
|
|
38
40
|
canceled: "remove"
|
|
39
41
|
```
|
|
@@ -42,12 +44,77 @@ plugins:
|
|
|
42
44
|
|
|
43
45
|
| Field | Type | Required | Description |
|
|
44
46
|
|-------|------|----------|-------------|
|
|
47
|
+
| `apiKey` | string | **Yes** | Linear API key for authentication. Create one at [linear.app/settings/account/security](https://linear.app/settings/account/security). |
|
|
45
48
|
| `webhookSecret` | string | **Yes** | Shared secret for HMAC webhook signature verification. |
|
|
46
49
|
| `agentMapping` | object | No | Maps Linear user UUIDs to agent IDs. Acts as a filter — events for unmapped users are ignored. Since each instance runs one agent, this typically has one entry. |
|
|
47
50
|
| `teamIds` | string[] | No | Team keys to scope webhook processing. Empty = all teams. |
|
|
48
51
|
| `eventFilter` | string[] | No | Event types to handle (`Issue`, `Comment`). Empty = all. |
|
|
49
|
-
| `debounceMs` | integer | No | Debounce window in milliseconds. Events arriving within this window are batched into a single
|
|
50
|
-
| `stateActions` | object | No | Maps Linear state types or names to queue actions (`"add"`, `"remove"`, `"ignore"`).
|
|
52
|
+
| `debounceMs` | integer | No | Debounce window in milliseconds. Events arriving within this window are batched into a single dispatch. Default: `30000` (30s). |
|
|
53
|
+
| `stateActions` | object | No | Maps Linear state types or names to queue actions (`"add"`, `"remove"`, `"ignore"`). See [State Actions](#state-actions). |
|
|
54
|
+
|
|
55
|
+
## Tools
|
|
56
|
+
|
|
57
|
+
The plugin provides six tools that agents can use to interact with Linear. All tools use an `action` parameter to select the operation.
|
|
58
|
+
|
|
59
|
+
### `linear_queue` — notification inbox
|
|
60
|
+
|
|
61
|
+
Manage the queue of webhook-driven notifications.
|
|
62
|
+
|
|
63
|
+
| Action | Description |
|
|
64
|
+
|--------|-------------|
|
|
65
|
+
| `peek` | View all pending items sorted by priority |
|
|
66
|
+
| `pop` | Claim the highest-priority pending item |
|
|
67
|
+
| `drain` | Claim all pending items |
|
|
68
|
+
| `complete` | Finish work on a claimed item (requires `issueId`) |
|
|
69
|
+
|
|
70
|
+
### `linear_issue` — issue management
|
|
71
|
+
|
|
72
|
+
View, search, create, update, and delete Linear issues.
|
|
73
|
+
|
|
74
|
+
| Action | Required | Optional |
|
|
75
|
+
|--------|----------|----------|
|
|
76
|
+
| `view` | `issueId` | — |
|
|
77
|
+
| `list` | — | `state`, `assignee`, `team`, `project`, `limit` |
|
|
78
|
+
| `create` | `title` | `description`, `assignee`, `state`, `priority`, `team`, `project`, `parent`, `labels` |
|
|
79
|
+
| `update` | `issueId` | `title`, `description`, `assignee`, `state`, `priority`, `labels`, `project` |
|
|
80
|
+
| `delete` | `issueId` | — |
|
|
81
|
+
|
|
82
|
+
Issues are referenced by human-readable identifiers (e.g. `ENG-123`). Names are resolved automatically — `assignee` accepts display names or emails, `state` accepts workflow state names, `team` accepts team keys, and `labels` accepts label names.
|
|
83
|
+
|
|
84
|
+
### `linear_comment` — comments
|
|
85
|
+
|
|
86
|
+
Read, create, and update comments on issues.
|
|
87
|
+
|
|
88
|
+
| Action | Required | Optional |
|
|
89
|
+
|--------|----------|----------|
|
|
90
|
+
| `list` | `issueId` | — |
|
|
91
|
+
| `add` | `issueId`, `body` | `parentCommentId` |
|
|
92
|
+
| `update` | `commentId`, `body` | — |
|
|
93
|
+
|
|
94
|
+
### `linear_team` — teams and members
|
|
95
|
+
|
|
96
|
+
| Action | Required |
|
|
97
|
+
|--------|----------|
|
|
98
|
+
| `list` | — |
|
|
99
|
+
| `members` | `team` (key, e.g. `ENG`) |
|
|
100
|
+
|
|
101
|
+
### `linear_project` — projects
|
|
102
|
+
|
|
103
|
+
| Action | Required | Optional |
|
|
104
|
+
|--------|----------|----------|
|
|
105
|
+
| `list` | — | `team`, `status` |
|
|
106
|
+
| `view` | `projectId` | — |
|
|
107
|
+
| `create` | `name` | `team`, `description` |
|
|
108
|
+
|
|
109
|
+
### `linear_relation` — issue relations
|
|
110
|
+
|
|
111
|
+
| Action | Required |
|
|
112
|
+
|--------|----------|
|
|
113
|
+
| `list` | `issueId` |
|
|
114
|
+
| `add` | `issueId`, `type`, `relatedIssueId` |
|
|
115
|
+
| `delete` | `relationId` |
|
|
116
|
+
|
|
117
|
+
Relation types: `blocks`, `blocked-by`, `related`, `duplicate`.
|
|
51
118
|
|
|
52
119
|
## Webhook Setup
|
|
53
120
|
|
|
@@ -85,7 +152,7 @@ When an issue's state changes, the plugin resolves what to do based on the `stat
|
|
|
85
152
|
|
|
86
153
|
**Resolution order:** state name match → state type match → built-in default.
|
|
87
154
|
|
|
88
|
-
Linear has 6 fixed state types. Custom state names (e.g. "In Review", "QA") are team-specific but always belong to one of these types.
|
|
155
|
+
Linear has 6 fixed state types. Custom state names (e.g. "In Review", "QA") are team-specific but always belong to one of these types.
|
|
89
156
|
|
|
90
157
|
**Built-in defaults** (used when `stateActions` is not configured or a state isn't mapped):
|
|
91
158
|
|
|
@@ -113,59 +180,34 @@ Linear webhook POST
|
|
|
113
180
|
→ Event router filters by team/type, matches user via agentMapping
|
|
114
181
|
→ wake actions enqueued into debouncer (keyed by agent ID)
|
|
115
182
|
→ After debounce window expires:
|
|
116
|
-
→ Notifications
|
|
117
|
-
→ Deduped against existing non-done items — skips
|
|
118
|
-
→ Agent receives
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
## Work Queue
|
|
122
|
-
|
|
123
|
-
The plugin writes structured items to `queue/work-queue.json`:
|
|
124
|
-
|
|
125
|
-
```json
|
|
126
|
-
{
|
|
127
|
-
"items": [
|
|
128
|
-
{
|
|
129
|
-
"id": "ENG-42",
|
|
130
|
-
"issueId": "ENG-42",
|
|
131
|
-
"event": "issue.assigned",
|
|
132
|
-
"summary": "Fix login bug",
|
|
133
|
-
"status": "pending",
|
|
134
|
-
"priority": 1,
|
|
135
|
-
"addedAt": "2026-02-14T15:45:00.000Z",
|
|
136
|
-
"startedAt": null,
|
|
137
|
-
"completedAt": null
|
|
138
|
-
}
|
|
139
|
-
]
|
|
140
|
-
}
|
|
183
|
+
→ Notifications written to queue (deterministic, no LLM)
|
|
184
|
+
→ Deduped against existing non-done items — skips dispatch if nothing new
|
|
185
|
+
→ Agent receives: "3 new Linear notification(s) queued."
|
|
186
|
+
→ After agent completes an item, auto-wake continues if items remain
|
|
141
187
|
```
|
|
142
188
|
|
|
143
|
-
|
|
189
|
+
## Architecture
|
|
144
190
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
191
|
+
```text
|
|
192
|
+
src/
|
|
193
|
+
├── index.ts # Plugin entry point, activation, dispatch logic
|
|
194
|
+
├── webhook-handler.ts # HMAC verification, body parsing, dedup
|
|
195
|
+
├── event-router.ts # Event filtering, routing, state action resolution
|
|
196
|
+
├── linear-api.ts # GraphQL client, name/ID resolution helpers
|
|
197
|
+
├── work-queue.ts # Persistent JSONL queue with priority sorting
|
|
198
|
+
└── tools/
|
|
199
|
+
├── queue-tool.ts # linear_queue — notification inbox management
|
|
200
|
+
├── linear-issue-tool.ts # linear_issue — CRUD for issues
|
|
201
|
+
├── linear-comment-tool.ts # linear_comment — issue comments
|
|
202
|
+
├── linear-team-tool.ts # linear_team — teams and members
|
|
203
|
+
├── linear-project-tool.ts # linear_project — project management
|
|
204
|
+
└── linear-relation-tool.ts # linear_relation — issue relations
|
|
205
|
+
```
|
|
159
206
|
|
|
160
207
|
## Development
|
|
161
208
|
|
|
162
209
|
```bash
|
|
163
210
|
npm install
|
|
164
211
|
npm run build
|
|
165
|
-
|
|
166
|
-
# Type-check without emitting
|
|
167
|
-
npx tsc --noEmit
|
|
168
|
-
|
|
169
|
-
# Run tests
|
|
170
212
|
npm test
|
|
171
213
|
```
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAwBzE,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAYzE;AA0FD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAqLrD;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAStE;AAED,QAAA,MAAM,MAAM;;;;;;CAYX,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { createWebhookHandler } from "./webhook-handler.js";
|
|
2
2
|
import { createEventRouter } from "./event-router.js";
|
|
3
3
|
import { InboxQueue } from "./work-queue.js";
|
|
4
|
-
import { createQueueTool } from "./queue-tool.js";
|
|
4
|
+
import { createQueueTool } from "./tools/queue-tool.js";
|
|
5
|
+
import { setApiKey } from "./linear-api.js";
|
|
6
|
+
import { createIssueTool } from "./tools/linear-issue-tool.js";
|
|
7
|
+
import { createCommentTool } from "./tools/linear-comment-tool.js";
|
|
8
|
+
import { createTeamTool } from "./tools/linear-team-tool.js";
|
|
9
|
+
import { createProjectTool } from "./tools/linear-project-tool.js";
|
|
10
|
+
import { createRelationTool } from "./tools/linear-relation-tool.js";
|
|
5
11
|
const CHANNEL_ID = "linear";
|
|
6
12
|
const DEFAULT_DEBOUNCE_MS = 30_000;
|
|
7
13
|
const EVENT_LABELS = {
|
|
@@ -98,6 +104,12 @@ let activeDebouncer;
|
|
|
98
104
|
const activeDebouncerKeys = new Set();
|
|
99
105
|
export function activate(api) {
|
|
100
106
|
api.logger.info("Linear plugin activated");
|
|
107
|
+
const linearApiKey = api.pluginConfig?.["apiKey"];
|
|
108
|
+
if (typeof linearApiKey !== "string" || !linearApiKey) {
|
|
109
|
+
api.logger.error("[linear] apiKey is not configured — plugin is inert");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
setApiKey(linearApiKey);
|
|
101
113
|
const webhookSecret = api.pluginConfig?.["webhookSecret"];
|
|
102
114
|
if (typeof webhookSecret !== "string" || !webhookSecret) {
|
|
103
115
|
api.logger.error("[linear] webhookSecret is not configured — plugin is inert");
|
|
@@ -113,11 +125,76 @@ export function activate(api) {
|
|
|
113
125
|
const debounceMs = (typeof rawDebounceMs === "number" && rawDebounceMs > 0)
|
|
114
126
|
? rawDebounceMs
|
|
115
127
|
: DEFAULT_DEBOUNCE_MS;
|
|
128
|
+
const core = api.runtime;
|
|
129
|
+
const cfg = api.config;
|
|
116
130
|
const queuePath = api.resolvePath("queue/inbox.jsonl");
|
|
117
131
|
const queue = new InboxQueue(queuePath);
|
|
132
|
+
// Recover any stale in_progress items from a previous crash
|
|
133
|
+
queue.recover().then((count) => {
|
|
134
|
+
if (count > 0) {
|
|
135
|
+
api.logger.info(`[linear] Recovered ${count} stale in_progress queue item(s)`);
|
|
136
|
+
}
|
|
137
|
+
}).catch((err) => {
|
|
138
|
+
api.logger.error(`[linear] Queue recovery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
139
|
+
});
|
|
118
140
|
api.registerTool(createQueueTool(queue));
|
|
141
|
+
api.registerTool(createIssueTool());
|
|
142
|
+
api.registerTool(createCommentTool());
|
|
143
|
+
api.registerTool(createTeamTool());
|
|
144
|
+
api.registerTool(createProjectTool());
|
|
145
|
+
api.registerTool(createRelationTool());
|
|
146
|
+
// Auto-wake: after a "complete" action, dispatch a fresh session if items remain
|
|
147
|
+
api.on("after_tool_call", async (event) => {
|
|
148
|
+
if (event.toolName !== "linear_queue")
|
|
149
|
+
return;
|
|
150
|
+
if (event.params.action !== "complete")
|
|
151
|
+
return;
|
|
152
|
+
if (event.error)
|
|
153
|
+
return;
|
|
154
|
+
const remaining = await queue.peek();
|
|
155
|
+
if (remaining.length === 0)
|
|
156
|
+
return;
|
|
157
|
+
const remainingCount = remaining.length;
|
|
158
|
+
const peerId = `queue-wake-${Date.now()}`;
|
|
159
|
+
const route = core.channel.routing.resolveAgentRoute({
|
|
160
|
+
cfg,
|
|
161
|
+
channel: CHANNEL_ID,
|
|
162
|
+
accountId: "default",
|
|
163
|
+
peer: { kind: "direct", id: peerId },
|
|
164
|
+
});
|
|
165
|
+
const body = `${remainingCount} item(s) remaining in queue. Use the linear_queue tool to continue processing.`;
|
|
166
|
+
const ctx = core.channel.reply.finalizeInboundContext({
|
|
167
|
+
Body: body,
|
|
168
|
+
BodyForAgent: body,
|
|
169
|
+
RawBody: body,
|
|
170
|
+
CommandBody: body,
|
|
171
|
+
From: `${CHANNEL_ID}:${peerId}`,
|
|
172
|
+
To: `${CHANNEL_ID}:${route.agentId ?? "default"}`,
|
|
173
|
+
SessionKey: route.sessionKey,
|
|
174
|
+
AccountId: route.accountId ?? "default",
|
|
175
|
+
ChatType: "direct",
|
|
176
|
+
ConversationLabel: `Linear: queue check (${remainingCount} remaining)`,
|
|
177
|
+
SenderId: peerId,
|
|
178
|
+
Provider: CHANNEL_ID,
|
|
179
|
+
Surface: CHANNEL_ID,
|
|
180
|
+
OriginatingChannel: CHANNEL_ID,
|
|
181
|
+
OriginatingTo: `${CHANNEL_ID}:${peerId}`,
|
|
182
|
+
});
|
|
183
|
+
core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
184
|
+
ctx,
|
|
185
|
+
cfg,
|
|
186
|
+
dispatcherOptions: {
|
|
187
|
+
deliver: async () => { },
|
|
188
|
+
onError: (err) => {
|
|
189
|
+
api.logger.error(`[linear] Queue wake error: ${err instanceof Error ? err.message : String(err)}`);
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
}).catch((err) => {
|
|
193
|
+
api.logger.error(`[linear] Queue wake dispatch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
194
|
+
});
|
|
195
|
+
});
|
|
119
196
|
const stateActions = api.pluginConfig?.["stateActions"] ?? undefined;
|
|
120
|
-
const
|
|
197
|
+
const routeEvent = createEventRouter({
|
|
121
198
|
agentMapping,
|
|
122
199
|
logger: api.logger,
|
|
123
200
|
eventFilter: eventFilter.length ? eventFilter : undefined,
|
|
@@ -140,7 +217,7 @@ export function activate(api) {
|
|
|
140
217
|
webhookSecret,
|
|
141
218
|
logger: api.logger,
|
|
142
219
|
onEvent: (event) => {
|
|
143
|
-
const actions =
|
|
220
|
+
const actions = routeEvent(event);
|
|
144
221
|
for (const action of actions) {
|
|
145
222
|
api.logger.info(`[event-router] ${action.type} agent=${action.agentId} event=${action.event}: ${action.detail}`);
|
|
146
223
|
if (action.type === "wake") {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAqB,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,UAAU,EAAqB,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function setApiKey(key: string): void;
|
|
2
|
+
/** Reset API key (for testing). */
|
|
3
|
+
export declare function _resetApiKey(): void;
|
|
4
|
+
export declare function graphql<T>(query: string, variables?: Record<string, unknown>): Promise<T>;
|
|
5
|
+
export declare function resolveIssueId(identifier: string): Promise<string>;
|
|
6
|
+
/** Reset issue ID cache (for testing). */
|
|
7
|
+
export declare function _resetIssueIdCache(): void;
|
|
8
|
+
export declare function resolveTeamId(key: string): Promise<string>;
|
|
9
|
+
export declare function resolveStateId(teamId: string, stateName: string): Promise<string>;
|
|
10
|
+
export declare function resolveUserId(nameOrEmail: string): Promise<string>;
|
|
11
|
+
export declare function resolveLabelIds(teamId: string, names: string[]): Promise<string[]>;
|
|
12
|
+
export declare function resolveProjectId(name: string): Promise<string>;
|
|
13
|
+
//# sourceMappingURL=linear-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-api.d.ts","sourceRoot":"","sources":["../src/linear-api.ts"],"names":[],"mappings":"AAIA,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE3C;AAED,mCAAmC;AACnC,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAED,wBAAsB,OAAO,CAAC,CAAC,EAC7B,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,CAAC,CAAC,CA4BZ;AAMD,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BxE;AAED,0CAA0C;AAC1C,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBhE;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBxE;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CAyBnB;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBpE"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const API_URL = "https://api.linear.app/graphql";
|
|
2
|
+
let apiKey;
|
|
3
|
+
export function setApiKey(key) {
|
|
4
|
+
apiKey = key;
|
|
5
|
+
}
|
|
6
|
+
/** Reset API key (for testing). */
|
|
7
|
+
export function _resetApiKey() {
|
|
8
|
+
apiKey = undefined;
|
|
9
|
+
}
|
|
10
|
+
export async function graphql(query, variables) {
|
|
11
|
+
if (!apiKey) {
|
|
12
|
+
throw new Error("Linear API key not set — call setApiKey() first");
|
|
13
|
+
}
|
|
14
|
+
const res = await fetch(API_URL, {
|
|
15
|
+
method: "POST",
|
|
16
|
+
headers: {
|
|
17
|
+
Authorization: apiKey,
|
|
18
|
+
"Content-Type": "application/json",
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify({ query, variables }),
|
|
21
|
+
});
|
|
22
|
+
if (!res.ok) {
|
|
23
|
+
throw new Error(`Linear API HTTP ${res.status}: ${res.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
const json = (await res.json());
|
|
26
|
+
if (json.errors?.length) {
|
|
27
|
+
throw new Error(`Linear API error: ${json.errors[0].message}`);
|
|
28
|
+
}
|
|
29
|
+
return json.data;
|
|
30
|
+
}
|
|
31
|
+
// --- Name/ID resolution helpers ---
|
|
32
|
+
const issueIdCache = new Map();
|
|
33
|
+
export async function resolveIssueId(identifier) {
|
|
34
|
+
const cached = issueIdCache.get(identifier);
|
|
35
|
+
if (cached)
|
|
36
|
+
return cached;
|
|
37
|
+
const match = identifier.match(/^([A-Za-z]+)-(\d+)$/);
|
|
38
|
+
if (!match) {
|
|
39
|
+
throw new Error(`Invalid issue identifier format: ${identifier} (expected e.g. ENG-123)`);
|
|
40
|
+
}
|
|
41
|
+
const [, teamKey, numStr] = match;
|
|
42
|
+
const num = parseInt(numStr, 10);
|
|
43
|
+
const data = await graphql(`query($teamKey: String!, $num: Float!) {
|
|
44
|
+
issues(filter: { team: { key: { eq: $teamKey } }, number: { eq: $num } }) {
|
|
45
|
+
nodes { id }
|
|
46
|
+
}
|
|
47
|
+
}`, { teamKey: teamKey.toUpperCase(), num });
|
|
48
|
+
if (data.issues.nodes.length === 0) {
|
|
49
|
+
throw new Error(`Issue ${identifier} not found`);
|
|
50
|
+
}
|
|
51
|
+
const id = data.issues.nodes[0].id;
|
|
52
|
+
issueIdCache.set(identifier, id);
|
|
53
|
+
return id;
|
|
54
|
+
}
|
|
55
|
+
/** Reset issue ID cache (for testing). */
|
|
56
|
+
export function _resetIssueIdCache() {
|
|
57
|
+
issueIdCache.clear();
|
|
58
|
+
}
|
|
59
|
+
export async function resolveTeamId(key) {
|
|
60
|
+
const data = await graphql(`query($key: String!) {
|
|
61
|
+
teams(filter: { key: { eq: $key } }) {
|
|
62
|
+
nodes { id }
|
|
63
|
+
}
|
|
64
|
+
}`, { key: key.toUpperCase() });
|
|
65
|
+
if (data.teams.nodes.length === 0) {
|
|
66
|
+
throw new Error(`Team with key "${key}" not found`);
|
|
67
|
+
}
|
|
68
|
+
return data.teams.nodes[0].id;
|
|
69
|
+
}
|
|
70
|
+
export async function resolveStateId(teamId, stateName) {
|
|
71
|
+
const data = await graphql(`query($teamId: String!, $name: String!) {
|
|
72
|
+
workflowStates(filter: { team: { id: { eq: $teamId } }, name: { eqIgnoreCase: $name } }) {
|
|
73
|
+
nodes { id }
|
|
74
|
+
}
|
|
75
|
+
}`, { teamId, name: stateName });
|
|
76
|
+
if (data.workflowStates.nodes.length === 0) {
|
|
77
|
+
throw new Error(`Workflow state "${stateName}" not found`);
|
|
78
|
+
}
|
|
79
|
+
return data.workflowStates.nodes[0].id;
|
|
80
|
+
}
|
|
81
|
+
export async function resolveUserId(nameOrEmail) {
|
|
82
|
+
const data = await graphql(`query($term: String!) {
|
|
83
|
+
users(filter: { or: [{ name: { eqIgnoreCase: $term } }, { email: { eq: $term } }] }) {
|
|
84
|
+
nodes { id }
|
|
85
|
+
}
|
|
86
|
+
}`, { term: nameOrEmail });
|
|
87
|
+
if (data.users.nodes.length === 0) {
|
|
88
|
+
throw new Error(`User "${nameOrEmail}" not found`);
|
|
89
|
+
}
|
|
90
|
+
return data.users.nodes[0].id;
|
|
91
|
+
}
|
|
92
|
+
export async function resolveLabelIds(teamId, names) {
|
|
93
|
+
const data = await graphql(`query($teamId: String!) {
|
|
94
|
+
issueLabels(filter: { team: { id: { eq: $teamId } } }) {
|
|
95
|
+
nodes { id name }
|
|
96
|
+
}
|
|
97
|
+
}`, { teamId });
|
|
98
|
+
const labelMap = new Map(data.issueLabels.nodes.map((l) => [l.name.toLowerCase(), l.id]));
|
|
99
|
+
const ids = [];
|
|
100
|
+
for (const name of names) {
|
|
101
|
+
const id = labelMap.get(name.toLowerCase());
|
|
102
|
+
if (!id) {
|
|
103
|
+
throw new Error(`Label "${name}" not found in team`);
|
|
104
|
+
}
|
|
105
|
+
ids.push(id);
|
|
106
|
+
}
|
|
107
|
+
return ids;
|
|
108
|
+
}
|
|
109
|
+
export async function resolveProjectId(name) {
|
|
110
|
+
const data = await graphql(`query($name: String!) {
|
|
111
|
+
projects(filter: { name: { eqIgnoreCase: $name } }) {
|
|
112
|
+
nodes { id name }
|
|
113
|
+
}
|
|
114
|
+
}`, { name });
|
|
115
|
+
if (data.projects.nodes.length === 0) {
|
|
116
|
+
throw new Error(`Project "${name}" not found`);
|
|
117
|
+
}
|
|
118
|
+
return data.projects.nodes[0].id;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=linear-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-api.js","sourceRoot":"","sources":["../src/linear-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-comment-tool.d.ts","sourceRoot":"","sources":["../../src/tools/linear-comment-tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAqCxD,wBAAgB,iBAAiB,IAAI,YAAY,CA4BhD"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { jsonResult } from "openclaw/plugin-sdk";
|
|
3
|
+
import { graphql, resolveIssueId } from "../linear-api.js";
|
|
4
|
+
const Params = Type.Object({
|
|
5
|
+
action: Type.Unsafe({
|
|
6
|
+
type: "string",
|
|
7
|
+
enum: ["list", "add", "update"],
|
|
8
|
+
description: "list: get all comments on an issue. " +
|
|
9
|
+
"add: post a new comment. " +
|
|
10
|
+
"update: edit an existing comment.",
|
|
11
|
+
}),
|
|
12
|
+
issueId: Type.Optional(Type.String({
|
|
13
|
+
description: "Issue identifier (e.g. ENG-123). Required for list and add.",
|
|
14
|
+
})),
|
|
15
|
+
commentId: Type.Optional(Type.String({
|
|
16
|
+
description: "Comment ID. Required for update.",
|
|
17
|
+
})),
|
|
18
|
+
body: Type.Optional(Type.String({
|
|
19
|
+
description: "Comment body (markdown). Required for add and update.",
|
|
20
|
+
})),
|
|
21
|
+
parentCommentId: Type.Optional(Type.String({
|
|
22
|
+
description: "Parent comment ID for threading a reply (used with add).",
|
|
23
|
+
})),
|
|
24
|
+
});
|
|
25
|
+
export function createCommentTool() {
|
|
26
|
+
return {
|
|
27
|
+
name: "linear_comment",
|
|
28
|
+
label: "Linear Comment",
|
|
29
|
+
description: "Manage comments on Linear issues. Actions: list, add, update.",
|
|
30
|
+
parameters: Params,
|
|
31
|
+
async execute(_toolCallId, params) {
|
|
32
|
+
try {
|
|
33
|
+
switch (params.action) {
|
|
34
|
+
case "list":
|
|
35
|
+
return await listComments(params);
|
|
36
|
+
case "add":
|
|
37
|
+
return await addComment(params);
|
|
38
|
+
case "update":
|
|
39
|
+
return await updateComment(params);
|
|
40
|
+
default:
|
|
41
|
+
return jsonResult({
|
|
42
|
+
error: `Unknown action: ${params.action}`,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
return jsonResult({
|
|
48
|
+
error: `linear_comment error: ${err instanceof Error ? err.message : String(err)}`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async function listComments(params) {
|
|
55
|
+
if (!params.issueId) {
|
|
56
|
+
return jsonResult({ error: "issueId is required for list" });
|
|
57
|
+
}
|
|
58
|
+
const id = await resolveIssueId(params.issueId);
|
|
59
|
+
const data = await graphql(`query($id: String!) {
|
|
60
|
+
issue(id: $id) {
|
|
61
|
+
comments(first: 100) {
|
|
62
|
+
nodes {
|
|
63
|
+
id
|
|
64
|
+
body
|
|
65
|
+
createdAt
|
|
66
|
+
updatedAt
|
|
67
|
+
user { id name }
|
|
68
|
+
parent { id }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}`, { id });
|
|
73
|
+
return jsonResult({ comments: data.issue.comments.nodes });
|
|
74
|
+
}
|
|
75
|
+
async function addComment(params) {
|
|
76
|
+
if (!params.issueId) {
|
|
77
|
+
return jsonResult({ error: "issueId is required for add" });
|
|
78
|
+
}
|
|
79
|
+
if (!params.body) {
|
|
80
|
+
return jsonResult({ error: "body is required for add" });
|
|
81
|
+
}
|
|
82
|
+
const issueId = await resolveIssueId(params.issueId);
|
|
83
|
+
const input = {
|
|
84
|
+
issueId,
|
|
85
|
+
body: params.body,
|
|
86
|
+
};
|
|
87
|
+
if (params.parentCommentId) {
|
|
88
|
+
input.parentId = params.parentCommentId;
|
|
89
|
+
}
|
|
90
|
+
const data = await graphql(`mutation($input: CommentCreateInput!) {
|
|
91
|
+
commentCreate(input: $input) {
|
|
92
|
+
success
|
|
93
|
+
comment { id body }
|
|
94
|
+
}
|
|
95
|
+
}`, { input });
|
|
96
|
+
return jsonResult(data.commentCreate);
|
|
97
|
+
}
|
|
98
|
+
async function updateComment(params) {
|
|
99
|
+
if (!params.commentId) {
|
|
100
|
+
return jsonResult({ error: "commentId is required for update" });
|
|
101
|
+
}
|
|
102
|
+
if (!params.body) {
|
|
103
|
+
return jsonResult({ error: "body is required for update" });
|
|
104
|
+
}
|
|
105
|
+
const data = await graphql(`mutation($id: String!, $input: CommentUpdateInput!) {
|
|
106
|
+
commentUpdate(id: $id, input: $input) {
|
|
107
|
+
success
|
|
108
|
+
comment { id body }
|
|
109
|
+
}
|
|
110
|
+
}`, { id: params.commentId, input: { body: params.body } });
|
|
111
|
+
return jsonResult(data.commentUpdate);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=linear-comment-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linear-comment-tool.js","sourceRoot":"","sources":["../../src/tools/linear-comment-tool.ts"],"names":[],"mappings":"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"}
|