openclaw-linear-plugin 0.1.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/LICENSE +21 -0
- package/README.md +155 -0
- package/openclaw.plugin.json +79 -0
- package/package.json +41 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 stumct
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# OpenClaw Linear Plugin
|
|
2
|
+
|
|
3
|
+
Receive [Linear](https://linear.app) Agent Session webhooks and run [OpenClaw](https://github.com/openclaw/openclaw) agents on issues.
|
|
4
|
+
|
|
5
|
+
When a Linear issue is delegated to your agent app, this plugin:
|
|
6
|
+
1. Receives the webhook
|
|
7
|
+
2. Starts an OpenClaw agent session
|
|
8
|
+
3. Posts the agent's response back to Linear
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install openclaw-linear-plugin
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Prerequisites
|
|
17
|
+
|
|
18
|
+
### 1. Create a Linear Agent Application
|
|
19
|
+
|
|
20
|
+
1. Go to [Linear Settings → API → Applications](https://linear.app/settings/api/applications/new)
|
|
21
|
+
2. Create a new application with:
|
|
22
|
+
- Name: Your agent name (e.g., "DevBot")
|
|
23
|
+
- Webhook URL: `https://your-gateway/plugins/linear/linear`
|
|
24
|
+
- Enable **Agent session events** in webhook categories
|
|
25
|
+
|
|
26
|
+
### 2. Install the App via OAuth
|
|
27
|
+
|
|
28
|
+
Complete the OAuth flow with these parameters:
|
|
29
|
+
```
|
|
30
|
+
https://linear.app/oauth/authorize?
|
|
31
|
+
client_id=YOUR_CLIENT_ID&
|
|
32
|
+
response_type=code&
|
|
33
|
+
scope=read,write,app:assignable,app:mentionable&
|
|
34
|
+
actor=app&
|
|
35
|
+
redirect_uri=YOUR_REDIRECT_URI
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The `actor=app` parameter is required for agent functionality.
|
|
39
|
+
|
|
40
|
+
### 3. Expose Your Gateway
|
|
41
|
+
|
|
42
|
+
The webhook URL must be publicly accessible. If using [Tailscale](https://tailscale.com), enable Funnel:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
tailscale funnel 18789 # Replace with your gateway port
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Configuration
|
|
49
|
+
|
|
50
|
+
Add to your `openclaw.json`:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"plugins": {
|
|
55
|
+
"entries": {
|
|
56
|
+
"linear": {
|
|
57
|
+
"enabled": true,
|
|
58
|
+
"config": {
|
|
59
|
+
"devAgentId": "dev",
|
|
60
|
+
"linearWebhookSecret": "lin_wh_...",
|
|
61
|
+
"linearApiKey": "lin_oauth_...",
|
|
62
|
+
"defaultDir": "/path/to/repo",
|
|
63
|
+
"delegateOnCreate": true,
|
|
64
|
+
"startOnCreate": true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Config Options
|
|
73
|
+
|
|
74
|
+
| Option | Type | Description |
|
|
75
|
+
|--------|------|-------------|
|
|
76
|
+
| `devAgentId` | string | Agent ID to handle issues (default: `"dev"`) |
|
|
77
|
+
| `linearWebhookSecret` | string | Webhook signing secret from Linear |
|
|
78
|
+
| `linearApiKey` | string | OAuth token from Linear app installation |
|
|
79
|
+
| `defaultDir` | string | Default repository directory |
|
|
80
|
+
| `repoByTeam` | object | Map team keys to repo directories |
|
|
81
|
+
| `repoByProject` | object | Map project keys to repo directories |
|
|
82
|
+
| `delegateOnCreate` | boolean | Auto-delegate issues to app (default: `true`) |
|
|
83
|
+
| `startOnCreate` | boolean | Move issues to "started" state (default: `true`) |
|
|
84
|
+
| `notifyChannel` | string | Optional: Channel for notifications (e.g., `"discord"`) |
|
|
85
|
+
| `notifyTo` | string | Optional: Notification target (e.g., `"channel:123456"`) |
|
|
86
|
+
| `externalUrlBase` | string | Optional: External session URL template |
|
|
87
|
+
| `externalUrlLabel` | string | Optional: Label for external URL link |
|
|
88
|
+
|
|
89
|
+
### External URL Template
|
|
90
|
+
|
|
91
|
+
Use placeholders for dynamic URLs:
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"externalUrlBase": "https://your-app.com/sessions/{session}",
|
|
95
|
+
"externalUrlLabel": "View Session"
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Supports `{session}` and `{issue}` placeholders.
|
|
100
|
+
|
|
101
|
+
## How It Works
|
|
102
|
+
|
|
103
|
+
1. **Webhook Reception**: Linear sends an AgentSessionEvent when an issue is delegated to your app
|
|
104
|
+
2. **Initial Response**: Plugin posts a "thinking" activity within 5 seconds
|
|
105
|
+
3. **Agent Execution**: OpenClaw agent runs with the issue context
|
|
106
|
+
4. **Response Posting**: Agent's reply is posted back to Linear as a response activity
|
|
107
|
+
|
|
108
|
+
### Webhook Endpoint
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
POST /plugins/linear/linear
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The plugin verifies the `Linear-Signature` header when `linearWebhookSecret` is configured.
|
|
115
|
+
|
|
116
|
+
## Troubleshooting
|
|
117
|
+
|
|
118
|
+
### "Did not respond" in Linear
|
|
119
|
+
|
|
120
|
+
- Check that your webhook URL is publicly accessible
|
|
121
|
+
- Verify `linearApiKey` has correct OAuth scopes
|
|
122
|
+
- Check OpenClaw logs for errors
|
|
123
|
+
|
|
124
|
+
### Webhook signature failures
|
|
125
|
+
|
|
126
|
+
- Ensure `linearWebhookSecret` matches Linear's signing secret
|
|
127
|
+
- Check for clock skew (webhooks older than 60s are rejected)
|
|
128
|
+
|
|
129
|
+
### Agent not running
|
|
130
|
+
|
|
131
|
+
- Verify `devAgentId` matches an agent in your OpenClaw config
|
|
132
|
+
- Check that the agent has necessary tool permissions
|
|
133
|
+
|
|
134
|
+
## Example Webhook Payload
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"action": "created",
|
|
139
|
+
"agentSession": {
|
|
140
|
+
"id": "session_abc123",
|
|
141
|
+
"issue": {
|
|
142
|
+
"id": "issue_xyz789",
|
|
143
|
+
"identifier": "ENG-123",
|
|
144
|
+
"title": "Fix login bug",
|
|
145
|
+
"url": "https://linear.app/team/issue/ENG-123"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"promptContext": "<issue>...</issue>",
|
|
149
|
+
"guidance": "Follow coding standards"
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
MIT © stumct
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "linear",
|
|
3
|
+
"name": "Linear",
|
|
4
|
+
"description": "Linear agent webhook bridge for OpenClaw dev runs",
|
|
5
|
+
"configSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"devAgentId": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "Agent ID to handle Linear issues (default: 'dev')"
|
|
12
|
+
},
|
|
13
|
+
"linearWebhookSecret": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "Linear webhook signing secret for signature verification"
|
|
16
|
+
},
|
|
17
|
+
"linearApiKey": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "Linear OAuth token for posting activities and updating issues"
|
|
20
|
+
},
|
|
21
|
+
"notifyChannel": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Optional channel to deliver agent responses (e.g., 'discord')"
|
|
24
|
+
},
|
|
25
|
+
"notifyTo": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "Optional target for notifications (e.g., 'channel:123456')"
|
|
28
|
+
},
|
|
29
|
+
"notifyAccountId": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "Optional account ID for notifications"
|
|
32
|
+
},
|
|
33
|
+
"repoByTeam": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"additionalProperties": { "type": "string" },
|
|
36
|
+
"description": "Map Linear team keys to repository directories"
|
|
37
|
+
},
|
|
38
|
+
"repoByProject": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"additionalProperties": { "type": "string" },
|
|
41
|
+
"description": "Map Linear project keys to repository directories"
|
|
42
|
+
},
|
|
43
|
+
"defaultDir": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "Default repository directory when no team/project mapping matches"
|
|
46
|
+
},
|
|
47
|
+
"delegateOnCreate": {
|
|
48
|
+
"type": "boolean",
|
|
49
|
+
"description": "Auto-delegate issues to the app user on session create (default: true)"
|
|
50
|
+
},
|
|
51
|
+
"startOnCreate": {
|
|
52
|
+
"type": "boolean",
|
|
53
|
+
"description": "Move issues to 'started' state on session create (default: true)"
|
|
54
|
+
},
|
|
55
|
+
"externalUrlBase": {
|
|
56
|
+
"type": "string",
|
|
57
|
+
"description": "Base URL for external session links (supports {session} and {issue} placeholders)"
|
|
58
|
+
},
|
|
59
|
+
"externalUrlLabel": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"description": "Label for external session links (default: 'OpenClaw session')"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"uiHints": {
|
|
66
|
+
"linearWebhookSecret": { "label": "Webhook secret", "sensitive": true },
|
|
67
|
+
"linearApiKey": { "label": "API key / OAuth token", "sensitive": true },
|
|
68
|
+
"delegateOnCreate": { "label": "Auto delegate" },
|
|
69
|
+
"startOnCreate": { "label": "Move to started" },
|
|
70
|
+
"externalUrlBase": {
|
|
71
|
+
"label": "External session URL",
|
|
72
|
+
"placeholder": "https://your-gateway/sessions/{session}"
|
|
73
|
+
},
|
|
74
|
+
"externalUrlLabel": {
|
|
75
|
+
"label": "External URL label",
|
|
76
|
+
"placeholder": "OpenClaw session"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openclaw-linear-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Linear agent webhook integration for OpenClaw",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"openclaw.plugin.json",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"openclaw",
|
|
19
|
+
"linear",
|
|
20
|
+
"agent",
|
|
21
|
+
"webhook",
|
|
22
|
+
"plugin"
|
|
23
|
+
],
|
|
24
|
+
"author": "stumct",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/stumct/openclaw-linear-plugin"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/stumct/openclaw-linear-plugin/issues"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/stumct/openclaw-linear-plugin#readme",
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"openclaw": ">=0.1.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"openclaw": "^0.1.0",
|
|
39
|
+
"typescript": "^5.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|