@calltelemetry/openclaw-linear 0.4.1 → 0.5.1

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 CHANGED
@@ -1,211 +1,171 @@
1
1
  # @calltelemetry/openclaw-linear
2
2
 
3
- An OpenClaw plugin that connects your Linear workspace to AI agents. Issues get triaged automatically, agents respond to @mentions, and a full plan-implement-audit pipeline runs when you assign work to the agent.
3
+ An OpenClaw plugin that connects your Linear workspace to AI agents. Issues get triaged automatically, agents respond to @mentions, and a worker-audit pipeline runs when you assign work to the agent.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Auto-triage** New issues get story point estimates, labels, and priority automatically
8
- - **@mention routing** `@qa`, `@infra`, `@docs` in comments route to specialized agents
9
- - **Agent pipeline** Assign an issue to the agent and it plans, implements, and audits the work
10
- - **Branded replies** Each agent posts with its own name and avatar in Linear
11
- - **Real-time progress** Agent activity (thinking, acting, responding) shows in Linear's UI
12
- - **Unified `code_run` tool** One tool, three coding CLI backends (Codex, Claude Code, Gemini CLI), configurable per agent
13
- - **Issue management via `linearis`** Agents use the `linearis` CLI to update status, close issues, add comments, and more
7
+ - **Auto-triage** -- New issues get story point estimates, labels, and priority automatically
8
+ - **@mention routing** -- `@qa`, `@infra`, `@docs` in comments route to specialized agents
9
+ - **Worker-audit pipeline** -- Assign an issue and a worker implements it, then an independent auditor verifies the work against the issue's definition of done
10
+ - **Hard-enforced audit** -- The audit triggers automatically in plugin code, not as an LLM decision. Workers cannot self-certify completion.
11
+ - **Branded replies** -- Each agent posts with its own name and avatar in Linear
12
+ - **Real-time progress** -- Agent activity (thinking, acting, responding) shows in Linear's UI
13
+ - **Unified `code_run` tool** -- One tool, three coding CLI backends (Codex, Claude Code, Gemini CLI), configurable per agent
14
+ - **Issue management via `linearis`** -- Agents use the `linearis` CLI to update status, close issues, add comments, and more
15
+ - **Customizable prompts** -- Worker, audit, and rework prompts live in `prompts.yaml`, editable without rebuilding
16
+ - **Discord notifications** -- Optional dispatch lifecycle notifications to a Discord channel
14
17
 
15
18
  ## Architecture
16
19
 
20
+ ### Dispatch Pipeline (v2)
21
+
22
+ When an issue is assigned to the agent, the plugin runs a multi-stage pipeline with hard-enforced audit:
23
+
24
+ ```
25
+ Issue Assigned
26
+ |
27
+ v
28
+ +-----------------+
29
+ | DISPATCH | Tier assessment, worktree creation,
30
+ | | dispatch state registration
31
+ +-----------------+
32
+ |
33
+ v
34
+ +-----------------+
35
+ | WORKER | Plans approach, implements solution,
36
+ | (sub-agent) | posts summary comment on the issue.
37
+ | | CANNOT mark issue as Done.
38
+ +-----------------+
39
+ |
40
+ | (plugin code -- automatic, not LLM-mediated)
41
+ v
42
+ +-----------------+
43
+ | AUDIT | Independent auditor reads issue body
44
+ | (sub-agent) | (source of truth), verifies criteria,
45
+ | | runs tests, returns JSON verdict.
46
+ +-----------------+
47
+ |
48
+ v
49
+ +-----------------+
50
+ | VERDICT | Plugin code processes the verdict:
51
+ | (plugin code) | PASS --> done + notify
52
+ | | FAIL <= max --> rework (attempt++)
53
+ | | FAIL > max --> stuck + escalate
54
+ +-----------------+
55
+ ```
56
+
57
+ **What's hard-enforced vs. LLM-mediated:**
58
+
59
+ | Layer | Mechanism | Can be skipped? |
60
+ |-------|-----------|-----------------|
61
+ | Worker spawn | Plugin code (`runAgent`) | No |
62
+ | Audit trigger | Plugin code (fires after worker completes) | No |
63
+ | Verdict processing | Plugin code (pass/fail/escalate) | No |
64
+ | Worker implementation | LLM-mediated (the agent decides how to code) | N/A |
65
+ | Audit evaluation | LLM-mediated (the agent decides if criteria are met) | N/A |
66
+
67
+ ### State Machine
68
+
69
+ ```
70
+ DISPATCHED --> WORKING --> AUDITING --> DONE
71
+ ^ |
72
+ | FAIL ---+ (attempt++ if <= max)
73
+ +------------+ (re-enter WORKING)
74
+ |
75
+ (attempt > max) --> STUCK
76
+ ```
77
+
78
+ All state transitions use compare-and-swap (CAS) to prevent races from duplicate webhooks or concurrent events. `dispatch-state.json` is the canonical source of truth; Linear labels are derived side effects.
79
+
17
80
  ### Webhook Flow
18
81
 
19
82
  ```
20
83
  Linear OpenClaw Gateway AI Agents
21
84
  | | |
22
85
  | Webhook (issue created) | |
23
- | ────────────────────────>| |
86
+ | -----------------------> | |
24
87
  | | Dispatch triage agent |
25
- | | ───────────────────────>|
88
+ | | ----------------------> |
26
89
  | | |
27
90
  | | Estimate + labels |
28
- | | <───────────────────────|
91
+ | | <---------------------- |
29
92
  | Update issue | |
30
- | <────────────────────────| |
93
+ | <----------------------- | |
31
94
  | Post assessment comment | |
32
- | <────────────────────────| |
95
+ | <----------------------- | |
33
96
  ```
34
97
 
35
98
  ```
36
99
  Linear OpenClaw Gateway AI Agents
37
100
  | | |
38
101
  | "@qa check this" | |
39
- | ────────────────────────>| |
102
+ | -----------------------> | |
40
103
  | | Route to QA agent |
41
- | | ───────────────────────>|
104
+ | | ----------------------> |
42
105
  | | |
43
106
  | | Response |
44
- | | <───────────────────────|
107
+ | | <---------------------- |
45
108
  | Comment from "QA" | |
46
- | <────────────────────────| |
109
+ | <----------------------- | |
47
110
  ```
48
111
 
49
112
  ### Two Webhook Systems
50
113
 
51
114
  Linear delivers events through two separate webhook paths:
52
115
 
53
- 1. **Workspace webhook** (Settings > API > Webhooks) handles Comment, Issue, and User events
54
- 2. **OAuth app webhook** (Settings > API > Applications > your app) handles `AgentSessionEvent` (created/prompted)
116
+ 1. **Workspace webhook** (Settings > API > Webhooks) -- handles Comment, Issue, and User events
117
+ 2. **OAuth app webhook** (Settings > API > Applications > your app) -- handles `AgentSessionEvent` (created/prompted)
55
118
 
56
119
  Both must point to the same URL: `https://<your-domain>/linear/webhook`
57
120
 
58
121
  ### Source Layout
59
122
 
60
123
  ```
61
- index.ts Plugin entry point, CLI checks, tool/webhook registration
124
+ index.ts Plugin entry point, agent_end hook, notifier setup
125
+ prompts.yaml Externalized worker/audit/rework prompt templates
62
126
  src/
63
- webhook.ts Webhook handler routes events to agents, builds prompts
64
- pipeline.ts 3-stage pipeline: plan implement → audit
65
- agent.ts Agent execution wrapper
66
- active-session.ts In-process session registry (issueId session)
67
-
68
- code-tool.ts Unified code_run tool dispatches to configured backend
127
+ webhook.ts Webhook handler -- routes events to agents, dispatches pipeline
128
+ pipeline.ts v2 pipeline: spawnWorker, triggerAudit, processVerdict
129
+ dispatch-state.ts File-backed state with CAS transitions, session map, idempotency
130
+ dispatch-service.ts Background service -- stale detection, recovery, cleanup
131
+ notify.ts Notification provider (Discord + noop fallback)
132
+ agent.ts Agent execution wrapper (embedded runner + subprocess fallback)
133
+ active-session.ts In-process session registry (issueId -> session)
134
+ tier-assess.ts Issue complexity assessment (junior/medior/senior)
135
+
136
+ code-tool.ts Unified code_run tool -- dispatches to configured backend
69
137
  cli-shared.ts Shared helpers for CLI tools (buildLinearApi, resolveSession)
70
- codex-tool.ts Codex CLI runner (JSONL stream Linear activities)
71
- claude-tool.ts Claude Code CLI runner (JSONL stream Linear activities)
72
- gemini-tool.ts Gemini CLI runner (JSONL stream Linear activities)
138
+ codex-tool.ts Codex CLI runner (JSONL stream -> Linear activities)
139
+ claude-tool.ts Claude Code CLI runner (JSONL stream -> Linear activities)
140
+ gemini-tool.ts Gemini CLI runner (JSONL stream -> Linear activities)
73
141
  coding-tools.json Backend config (default tool, per-agent overrides, aliases)
74
142
 
75
143
  tools.ts Tool registration (code_run + orchestration)
76
144
  orchestration-tools.ts spawn_agent / ask_agent for multi-agent delegation
77
145
  linear-api.ts Linear GraphQL API client, token resolution, activity streaming
78
- client.ts Lightweight Linear GraphQL client (legacy, unused by tools)
79
146
  auth.ts OAuth token management and profile storage
80
147
  oauth-callback.ts OAuth callback handler
81
- cli.ts CLI subcommands (auth, status)
82
- codex-worktree.ts Git worktree management for isolated Codex runs
83
- ```
84
-
85
- ## Coding Tool (`code_run`)
86
-
87
- The plugin provides a single `code_run` tool that dispatches to one of three coding CLI backends. Agents call `code_run` without needing to know which backend is active — the dispatcher handles routing.
88
-
89
- ### Supported Backends
90
-
91
- | Backend | CLI | Stream Format | Key Flags |
92
- |---|---|---|---|
93
- | **Codex** (OpenAI) | `codex` | JSONL | `--full-auto`, `-q` |
94
- | **Claude Code** (Anthropic) | `claude` | JSONL (`stream-json`) | `--print`, `--dangerously-skip-permissions`, `--verbose` |
95
- | **Gemini CLI** (Google) | `gemini` | JSONL (`stream-json`) | `--yolo`, `-o stream-json` |
96
-
97
- All three stream JSONL events that get mapped to Linear agent activities in real-time (thoughts, actions, tool results).
98
-
99
- ### Backend Resolution Priority
100
-
101
- When `code_run` is called:
102
-
103
- 1. **Explicit `backend` parameter** — Agent passes `backend: "gemini"` (or any alias)
104
- 2. **Per-agent override** — `agentCodingTools` in `coding-tools.json`
105
- 3. **Global default** — `codingTool` in `coding-tools.json`
106
- 4. **Hardcoded fallback** — `"claude"`
107
-
108
- ### Configuration (`coding-tools.json`)
109
-
110
- ```json
111
- {
112
- "codingTool": "codex",
113
- "agentCodingTools": {
114
- "kaylee": "claude",
115
- "inara": "gemini"
116
- },
117
- "backends": {
118
- "claude": {
119
- "aliases": ["claude", "claude code", "anthropic"]
120
- },
121
- "codex": {
122
- "aliases": ["codex", "openai"]
123
- },
124
- "gemini": {
125
- "aliases": ["gemini", "google"]
126
- }
127
- }
128
- }
148
+ cli.ts CLI subcommands (auth, status, worktrees, prompts)
149
+ codex-worktree.ts Git worktree management for isolated runs
129
150
  ```
130
151
 
131
- - **`codingTool`** — Default backend for all agents
132
- - **`agentCodingTools`** — Per-agent overrides (keyed by agent ID)
133
- - **`backends.*.aliases`** — Alias strings so the agent (or user) can say "use google" and it resolves to `gemini`
152
+ ## Getting Started
134
153
 
135
- ### Backend-Specific Notes
136
-
137
- **Claude Code:**
138
- - Must unset `CLAUDECODE` env var to avoid "nested session" error
139
- - Requires `--verbose` alongside `stream-json` for full event output
140
- - Content blocks are arrays: `message.content[].type` can be `text` or `tool_use`
141
-
142
- **Gemini CLI:**
143
- - Working directory set via `spawn()` `cwd` option (no `-C` flag)
144
- - Model override via `-m <model>` flag
145
- - Stderr may include "YOLO mode" warnings — filtered from output
146
-
147
- **Codex:**
148
- - Uses git worktrees for isolated runs (see `codex-worktree.ts`)
149
- - Model/timeout configurable via plugin config (`codexModel`, `codexTimeoutMs`)
150
-
151
- ## Linear Issue Management (`linearis` Skill)
152
-
153
- Issue management (update status, close, assign, comment, labels, etc.) is handled by the **`linearis`** CLI, installed as an OpenClaw skill. This replaces custom GraphQL tools — agents use `linearis` via exec.
154
-
155
- ### Install
156
-
157
- ```bash
158
- npx clawhub install linearis
159
- npm install -g linearis
160
- ```
161
-
162
- ### Auth
163
-
164
- ```bash
165
- echo "lin_api_..." > ~/.linear_api_token
166
- ```
167
-
168
- Or set `LINEAR_API_TOKEN` env var.
169
-
170
- ### Key Commands
171
-
172
- ```bash
173
- linearis issues list -l 20 # List recent issues
174
- linearis issues list --team UAT # Filter by team
175
- linearis issues search "auth bug" # Full-text search
176
- linearis issues read API-123 # Get issue details
177
- linearis issues update API-123 --status "Done" # Close issue
178
- linearis issues update API-123 --status "In Progress"
179
- linearis issues update API-123 --assignee user123
180
- linearis issues update API-123 --labels "Bug" --label-by adding
181
- linearis issues create --title "Fix it" --team UAT --priority 2
182
- linearis comments create API-123 --body "Fixed in PR #456"
183
- linearis teams list
184
- linearis users list --active
185
- linearis projects list
186
- linearis documents list
187
- linearis usage # Full command reference
188
- ```
189
-
190
- All output is JSON, suitable for piping to `jq`.
191
-
192
- ## Prerequisites
154
+ ### Prerequisites
193
155
 
194
156
  - **OpenClaw** gateway running (v2026.2+)
195
157
  - **Linear** workspace with API access
196
158
  - **Public URL** for webhook delivery (Cloudflare Tunnel recommended)
197
- - **Coding CLIs** (at least one): `codex`, `claude`, `gemini` installed in PATH
198
- - **linearis** CLI for issue management
159
+ - **Coding CLIs** (at least one): `codex`, `claude`, `gemini` -- installed in PATH
160
+ - **linearis** CLI -- for issue management
199
161
 
200
- ## Install
162
+ ### 1. Install the Plugin
201
163
 
202
164
  ```bash
203
165
  openclaw plugins install @calltelemetry/openclaw-linear
204
166
  ```
205
167
 
206
- ## Setup
207
-
208
- ### 1. Create a Linear OAuth App
168
+ ### 2. Create a Linear OAuth App
209
169
 
210
170
  Go to **Linear Settings > API > Applications** and create a new application:
211
171
 
@@ -215,7 +175,7 @@ Go to **Linear Settings > API > Applications** and create a new application:
215
175
 
216
176
  Save the **Client ID** and **Client Secret**.
217
177
 
218
- ### 2. Set Credentials
178
+ ### 3. Set Credentials
219
179
 
220
180
  Add to your gateway's environment (systemd service or shell):
221
181
 
@@ -234,49 +194,20 @@ Environment=LINEAR_CLIENT_SECRET=your_client_secret
234
194
 
235
195
  Then reload: `systemctl --user daemon-reload && systemctl --user restart openclaw-gateway`
236
196
 
237
- ### 3. Expose the Gateway
197
+ ### 4. Expose the Gateway
238
198
 
239
- Linear needs to reach your gateway over HTTPS to deliver webhooks. A [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) is the recommended approach no open ports, no TLS certificates to manage.
240
-
241
- #### a. Install `cloudflared`
199
+ Linear needs to reach your gateway over HTTPS to deliver webhooks. A [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) is the recommended approach -- no open ports, no TLS certificates to manage.
242
200
 
243
201
  ```bash
244
- # RHEL / Rocky / Alma
202
+ # Install cloudflared (RHEL/Rocky/Alma)
245
203
  sudo dnf install -y cloudflared
246
204
 
247
- # Debian / Ubuntu
248
- sudo apt install -y cloudflared
249
-
250
- # macOS
251
- brew install cloudflare/cloudflare/cloudflared
252
- ```
253
-
254
- #### b. Authenticate with Cloudflare
255
-
256
- ```bash
205
+ # Authenticate and create tunnel
257
206
  cloudflared tunnel login
258
- ```
259
-
260
- This opens your browser. Log in, select the domain you want to use, and click **Authorize**.
261
-
262
- #### c. Create a tunnel
263
-
264
- ```bash
265
207
  cloudflared tunnel create openclaw
266
- ```
267
-
268
- Note the **Tunnel ID** (a UUID) from the output.
269
-
270
- #### d. Point a subdomain at the tunnel
271
-
272
- ```bash
273
208
  cloudflared tunnel route dns openclaw linear.yourdomain.com
274
209
  ```
275
210
 
276
- This creates a DNS record so `linear.yourdomain.com` routes through the tunnel.
277
-
278
- #### e. Configure the tunnel
279
-
280
211
  Create `~/.cloudflared/config.yml`:
281
212
 
282
213
  ```yaml
@@ -289,21 +220,14 @@ ingress:
289
220
  - service: http_status:404
290
221
  ```
291
222
 
292
- #### f. Start the tunnel
223
+ Start the tunnel:
293
224
 
294
225
  ```bash
295
- # Install as a system service (starts on boot)
296
226
  sudo cloudflared service install
297
227
  sudo systemctl enable --now cloudflared
298
228
  ```
299
229
 
300
- To test without installing as a service:
301
-
302
- ```bash
303
- cloudflared tunnel run openclaw
304
- ```
305
-
306
- #### g. Verify the tunnel
230
+ Verify:
307
231
 
308
232
  ```bash
309
233
  curl -s https://linear.yourdomain.com/linear/webhook \
@@ -312,21 +236,13 @@ curl -s https://linear.yourdomain.com/linear/webhook \
312
236
  # Should return: "ok"
313
237
  ```
314
238
 
315
- ### 4. Authorize with Linear
239
+ ### 5. Authorize with Linear
316
240
 
317
241
  ```bash
318
242
  openclaw openclaw-linear auth
319
243
  ```
320
244
 
321
- This opens your browser to authorize the agent. The plugin needs these OAuth scopes:
322
-
323
- | Scope | What it enables |
324
- |---|---|
325
- | `read` / `write` | Read and update issues, post comments |
326
- | `app:assignable` | Agent appears in Linear's assignment menus |
327
- | `app:mentionable` | Users can @mention the agent in comments |
328
-
329
- After authorization, restart the gateway:
245
+ This opens your browser to authorize the agent. After authorization, restart the gateway:
330
246
 
331
247
  ```bash
332
248
  systemctl --user restart openclaw-gateway
@@ -338,31 +254,24 @@ Verify it's working:
338
254
  openclaw openclaw-linear status
339
255
  ```
340
256
 
341
- You should see `token: profile` in the gateway logs.
342
-
343
- ### 5. Configure Agents
257
+ ### 6. Configure Agents
344
258
 
345
259
  Create `~/.openclaw/agent-profiles.json` to define your agent team:
346
260
 
347
261
  ```json
348
262
  {
349
263
  "agents": {
350
- "lead": {
351
- "label": "Lead",
352
- "mission": "Product owner. Sets direction, prioritizes backlog.",
264
+ "coder": {
265
+ "label": "Coder",
266
+ "mission": "Full-stack engineer. Plans, implements, and ships code.",
353
267
  "isDefault": true,
354
- "mentionAliases": ["lead"],
355
- "avatarUrl": "https://example.com/lead.png"
268
+ "mentionAliases": ["coder"],
269
+ "avatarUrl": "https://example.com/coder.png"
356
270
  },
357
271
  "qa": {
358
272
  "label": "QA",
359
273
  "mission": "Test engineer. Quality guardian, test strategy.",
360
274
  "mentionAliases": ["qa", "tester"]
361
- },
362
- "infra": {
363
- "label": "Infra",
364
- "mission": "Backend engineer. Performance, reliability, observability.",
365
- "mentionAliases": ["infra", "backend"]
366
275
  }
367
276
  }
368
277
  }
@@ -370,9 +279,9 @@ Create `~/.openclaw/agent-profiles.json` to define your agent team:
370
279
 
371
280
  Each agent name must match an agent definition in your `~/.openclaw/openclaw.json`.
372
281
 
373
- One agent must be marked `isDefault: true` this is the agent that handles issue assignments and the pipeline.
282
+ One agent must be marked `isDefault: true` -- this is the agent that handles issue assignments and the dispatch pipeline.
374
283
 
375
- ### 6. Configure Coding Tools
284
+ ### 7. Configure Coding Tools
376
285
 
377
286
  Create `coding-tools.json` in the plugin root:
378
287
 
@@ -388,7 +297,7 @@ Create `coding-tools.json` in the plugin root:
388
297
  }
389
298
  ```
390
299
 
391
- ### 7. Install linearis
300
+ ### 8. Install linearis
392
301
 
393
302
  ```bash
394
303
  npm install -g linearis
@@ -396,7 +305,7 @@ npx clawhub install linearis
396
305
  echo "lin_api_YOUR_KEY" > ~/.linear_api_token
397
306
  ```
398
307
 
399
- ### 8. Verify
308
+ ### 9. Verify
400
309
 
401
310
  ```bash
402
311
  systemctl --user restart openclaw-gateway
@@ -425,62 +334,164 @@ Once set up, the plugin responds to Linear events automatically:
425
334
  | What you do in Linear | What happens |
426
335
  |---|---|
427
336
  | Create a new issue | Agent triages it (estimate, labels, priority) and posts an assessment |
428
- | Assign an issue to the agent | Agent triages and posts assessment |
429
- | Trigger an agent session | 3-stage pipeline: plan, implement, audit |
337
+ | Assign an issue to the agent | Worker-audit pipeline runs: implement, then independent audit |
338
+ | Trigger an agent session | Agent responds directly in the session |
430
339
  | Comment `@qa check the tests` | QA agent responds with its expertise |
431
- | Comment `@infra why is this slow` | Infra agent investigates and replies |
432
340
  | Ask "close this issue" | Agent runs `linearis issues update API-123 --status Done` |
433
341
  | Ask "use gemini to review" | Agent calls `code_run` with `backend: "gemini"` |
434
342
 
435
- ## Configuration Reference
343
+ ### Pipeline Behavior
436
344
 
437
- ### Environment Variables
345
+ When an issue is assigned:
438
346
 
439
- | Variable | Required | Description |
440
- |---|---|---|
441
- | `LINEAR_CLIENT_ID` | Yes | OAuth app client ID |
442
- | `LINEAR_CLIENT_SECRET` | Yes | OAuth app client secret |
443
- | `LINEAR_API_KEY` | No | Personal API key (fallback if no OAuth) |
444
- | `LINEAR_REDIRECT_URI` | No | Override the OAuth callback URL |
445
- | `OPENCLAW_GATEWAY_PORT` | No | Gateway port (default: 18789) |
347
+ 1. **Tier assessment** -- The plugin evaluates issue complexity (junior/medior/senior) and selects an appropriate model
348
+ 2. **Worktree creation** -- A git worktree is created for isolated work
349
+ 3. **Worker runs** -- The worker agent plans and implements the solution, posts a summary comment
350
+ 4. **Audit runs** -- An independent audit agent reads the issue body (source of truth), verifies acceptance criteria, runs tests, and returns a JSON verdict
351
+ 5. **Verdict** -- If the audit passes, the issue is marked done. If it fails, the worker is re-spawned with the audit gaps (up to `maxReworkAttempts` times). If it fails too many times, the issue is marked stuck and an escalation notification is sent.
352
+
353
+ Workers **cannot** mark issues as done or modify issue status -- that's handled entirely by the plugin's verdict processing code.
354
+
355
+ ## Prompt Customization
356
+
357
+ Worker, audit, and rework prompts are externalized in `prompts.yaml`. Edit them to customize agent behavior without rebuilding the plugin.
358
+
359
+ ### Managing Prompts
360
+
361
+ ```bash
362
+ openclaw openclaw-linear prompts show # Print current prompts.yaml
363
+ openclaw openclaw-linear prompts path # Print resolved file path
364
+ openclaw openclaw-linear prompts validate # Validate structure and template variables
365
+ ```
366
+
367
+ ### Template Variables
368
+
369
+ | Variable | Description |
370
+ |---|---|
371
+ | `{{identifier}}` | Issue identifier (e.g., `API-123`) |
372
+ | `{{title}}` | Issue title |
373
+ | `{{description}}` | Full issue body |
374
+ | `{{worktreePath}}` | Path to the git worktree |
375
+ | `{{tier}}` | Assessed complexity tier |
376
+ | `{{attempt}}` | Current attempt number (0-based) |
377
+ | `{{gaps}}` | Audit gaps from previous failed attempt (rework only) |
378
+
379
+ ### Override Path
380
+
381
+ Set `promptsPath` in plugin config to load prompts from a custom location:
382
+
383
+ ```json
384
+ {
385
+ "plugins": {
386
+ "entries": {
387
+ "openclaw-linear": {
388
+ "config": {
389
+ "promptsPath": "/path/to/my/prompts.yaml"
390
+ }
391
+ }
392
+ }
393
+ }
394
+ }
395
+ ```
396
+
397
+ ## Notifications
398
+
399
+ The plugin can post dispatch lifecycle events to a Discord channel. Configure `flowDiscordChannel` in plugin config with the channel ID.
400
+
401
+ Events posted:
402
+
403
+ | Event | Message |
404
+ |---|---|
405
+ | Dispatch | `**API-123** dispatched -- Fix auth bug` |
406
+ | Worker started | `**API-123** worker started (attempt 0)` |
407
+ | Audit in progress | `**API-123** audit in progress` |
408
+ | Audit passed | `**API-123** passed audit. PR ready.` |
409
+ | Audit failed | `**API-123** failed audit (attempt 1). Gaps: missing test coverage` |
410
+ | Escalation | `**API-123** needs human review -- audit failed 3x` |
411
+
412
+ ## Coding Tool (`code_run`)
413
+
414
+ The plugin provides a single `code_run` tool that dispatches to one of three coding CLI backends. Agents call `code_run` without needing to know which backend is active.
415
+
416
+ ### Supported Backends
417
+
418
+ | Backend | CLI | Stream Format | Key Flags |
419
+ |---|---|---|---|
420
+ | **Codex** (OpenAI) | `codex` | JSONL | `--full-auto`, `-q` |
421
+ | **Claude Code** (Anthropic) | `claude` | JSONL (`stream-json`) | `--print`, `--dangerously-skip-permissions`, `--verbose` |
422
+ | **Gemini CLI** (Google) | `gemini` | JSONL (`stream-json`) | `--yolo`, `-o stream-json` |
423
+
424
+ ### Backend Resolution Priority
425
+
426
+ 1. **Explicit `backend` parameter** -- Agent passes `backend: "gemini"` (or any alias)
427
+ 2. **Per-agent override** -- `agentCodingTools` in `coding-tools.json`
428
+ 3. **Global default** -- `codingTool` in `coding-tools.json`
429
+ 4. **Hardcoded fallback** -- `"claude"`
430
+
431
+ ## Linear Issue Management (`linearis` Skill)
432
+
433
+ Issue management is handled by the **`linearis`** CLI, installed as an OpenClaw skill. Agents use `linearis` via exec.
434
+
435
+ ```bash
436
+ linearis issues list -l 20 # List recent issues
437
+ linearis issues search "auth bug" # Full-text search
438
+ linearis issues read API-123 # Get issue details
439
+ linearis issues update API-123 --status "Done"
440
+ linearis issues update API-123 --labels "Bug" --label-by adding
441
+ linearis comments create API-123 --body "Fixed in PR #456"
442
+ linearis usage # Full command reference
443
+ ```
444
+
445
+ ## Configuration Reference
446
446
 
447
447
  ### Plugin Config
448
448
 
449
- Optional overrides in `openclaw.json` under the plugin entry:
449
+ Set in `openclaw.json` under the plugin entry:
450
450
 
451
451
  | Key | Type | Default | Description |
452
452
  |---|---|---|---|
453
- | `defaultAgentId` | string | | Override which agent handles pipeline/triage |
453
+ | `defaultAgentId` | string | `"default"` | Agent ID for pipeline workers and audit |
454
454
  | `enableAudit` | boolean | `true` | Run the auditor stage after implementation |
455
455
  | `enableOrchestration` | boolean | `true` | Allow agents to use `spawn_agent`/`ask_agent` |
456
- | `codexBaseRepo` | string | `/home/claw/ai-workspace` | Git repo path for Codex worktrees |
457
- | `codexModel` | string | | Default Codex model |
458
- | `codexTimeoutMs` | number | `600000` | Default timeout for coding CLIs |
456
+ | `codexBaseRepo` | string | `"/home/claw/ai-workspace"` | Git repo path for worktrees |
457
+ | `codexModel` | string | -- | Default Codex model |
458
+ | `codexTimeoutMs` | number | `600000` | Default timeout for coding CLIs (ms) |
459
+ | `worktreeBaseDir` | string | `"~/.openclaw/worktrees"` | Base directory for persistent git worktrees |
460
+ | `dispatchStatePath` | string | `"~/.openclaw/linear-dispatch-state.json"` | Path to dispatch state file |
461
+ | `flowDiscordChannel` | string | -- | Discord channel ID for lifecycle notifications |
462
+ | `promptsPath` | string | -- | Override path for `prompts.yaml` |
463
+ | `maxReworkAttempts` | number | `2` | Max audit failures before escalation |
459
464
 
460
- ### Coding Tools Config (`coding-tools.json`)
465
+ ### Environment Variables
461
466
 
462
- | Key | Type | Default | Description |
463
- |---|---|---|---|
464
- | `codingTool` | string | `"claude"` | Default coding backend |
465
- | `agentCodingTools` | object | `{}` | Per-agent backend overrides (`agentId → backendId`) |
466
- | `backends` | object | `{}` | Per-backend config (aliases, etc.) |
467
- | `backends.*.aliases` | string[] | `[backendId]` | Alias names that resolve to this backend |
467
+ | Variable | Required | Description |
468
+ |---|---|---|
469
+ | `LINEAR_CLIENT_ID` | Yes | OAuth app client ID |
470
+ | `LINEAR_CLIENT_SECRET` | Yes | OAuth app client secret |
471
+ | `LINEAR_API_KEY` | No | Personal API key (fallback if no OAuth) |
472
+ | `LINEAR_REDIRECT_URI` | No | Override the OAuth callback URL |
473
+ | `OPENCLAW_GATEWAY_PORT` | No | Gateway port (default: 18789) |
468
474
 
469
475
  ### Agent Profile Fields
470
476
 
471
477
  | Field | Required | Description |
472
478
  |---|---|---|
473
479
  | `label` | Yes | Display name shown on comments in Linear |
474
- | `mission` | Yes | Role description (injected as context when the agent runs) |
475
- | `isDefault` | One agent | Handles issue triage and the pipeline |
480
+ | `mission` | Yes | Role description (injected as context) |
481
+ | `isDefault` | One agent | Handles issue triage and the dispatch pipeline |
476
482
  | `mentionAliases` | Yes | `@mention` triggers (e.g., `["qa", "tester"]`) |
477
483
  | `avatarUrl` | No | Avatar for branded comments |
478
484
 
479
485
  ### CLI
480
486
 
481
487
  ```bash
482
- openclaw openclaw-linear auth # Run OAuth authorization
483
- openclaw openclaw-linear status # Check connection and token status
488
+ openclaw openclaw-linear auth # Run OAuth authorization
489
+ openclaw openclaw-linear status # Check connection and token status
490
+ openclaw openclaw-linear worktrees # List active worktrees
491
+ openclaw openclaw-linear worktrees --prune <path> # Remove a worktree
492
+ openclaw openclaw-linear prompts show # Print current prompts
493
+ openclaw openclaw-linear prompts path # Print resolved prompts file path
494
+ openclaw openclaw-linear prompts validate # Validate prompt structure
484
495
  ```
485
496
 
486
497
  ## Troubleshooting
@@ -492,18 +503,21 @@ systemctl --user status openclaw-gateway # Is the gateway running?
492
503
  openclaw openclaw-linear status # Is the token valid?
493
504
  journalctl --user -u openclaw-gateway -f # Watch live logs
494
505
  linearis issues list -l 1 # Is linearis authenticated?
506
+ openclaw openclaw-linear prompts validate # Are prompts valid?
495
507
  ```
496
508
 
497
509
  ### Common Issues
498
510
 
499
511
  | Problem | Cause | Fix |
500
512
  |---|---|---|
501
- | Agent says "closing" but doesn't | No issue management tool available | Install `linearis` skill: `npx clawhub install linearis` |
502
- | `code_run` uses wrong backend | Default/per-agent config mismatch | Check `coding-tools.json` |
503
- | Claude Code "nested session" error | `CLAUDECODE` env var set | Plugin handles this automatically (unsets the var) |
504
- | Gateway rejects plugin config keys | Strict validator in `openclaw.json` | Custom config goes in `coding-tools.json`, not `openclaw.json` |
505
- | Webhook events not arriving | Wrong webhook URL | Both workspace and OAuth app webhooks must point to `/linear/webhook` |
506
- | OAuth token expired | Tokens expire ~24h | Auto-refreshes via refresh token; restart gateway if stuck |
513
+ | Agent says "closing" but doesn't | No issue management tool | Install `linearis`: `npx clawhub install linearis` |
514
+ | `code_run` uses wrong backend | Config mismatch | Check `coding-tools.json` |
515
+ | Claude Code "nested session" error | `CLAUDECODE` env var set | Plugin handles this automatically |
516
+ | Gateway rejects plugin config keys | Strict validator | Custom config goes in `coding-tools.json` |
517
+ | Webhook events not arriving | Wrong URL | Both webhooks must point to `/linear/webhook` |
518
+ | OAuth token expired | Tokens expire ~24h | Auto-refreshes; restart gateway if stuck |
519
+ | Audit always fails | Bad prompt template | Run `openclaw openclaw-linear prompts validate` |
520
+ | Dispatch stuck | Worker timed out or crashed | Check `dispatch-state.json`, re-assign issue |
507
521
 
508
522
  ## License
509
523