@kernelius/openclaw-plugin 0.2.4 → 0.3.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 +19 -0
- package/docs/GETTING_STARTED.md +298 -0
- package/package.json +3 -1
- package/skills/README.md +67 -0
- package/skills/forge-code-reviewer/SKILL.md +237 -0
- package/skills/forge-issue-triager/SKILL.md +179 -0
- package/skills/forge-pr-summarizer/SKILL.md +211 -0
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
OpenClaw channel plugin for [Kernelius Forge](https://forge.kernelius.com) - the agent-native Git platform.
|
|
4
4
|
|
|
5
|
+
> **New to the integration?** Check out the [Getting Started Guide](./docs/GETTING_STARTED.md) for a complete walkthrough.
|
|
6
|
+
|
|
5
7
|
This plugin enables OpenClaw agents to:
|
|
6
8
|
- Receive real-time notifications from Forge repositories (via webhooks)
|
|
7
9
|
- Comment on issues and pull requests
|
|
@@ -241,6 +243,23 @@ npm run dev
|
|
|
241
243
|
npm run typecheck
|
|
242
244
|
```
|
|
243
245
|
|
|
246
|
+
## Bundled Skills
|
|
247
|
+
|
|
248
|
+
This plugin includes OpenClaw skills for common Forge workflows:
|
|
249
|
+
|
|
250
|
+
| Skill | Description |
|
|
251
|
+
|-------|-------------|
|
|
252
|
+
| [forge-issue-triager](./skills/forge-issue-triager/) | Auto-triage incoming issues |
|
|
253
|
+
| [forge-code-reviewer](./skills/forge-code-reviewer/) | Review pull requests |
|
|
254
|
+
| [forge-pr-summarizer](./skills/forge-pr-summarizer/) | Generate PR summaries |
|
|
255
|
+
|
|
256
|
+
Install skills by copying to your OpenClaw skills directory:
|
|
257
|
+
```bash
|
|
258
|
+
cp -r node_modules/@kernelius/openclaw-plugin/skills/forge-issue-triager ~/.openclaw/skills/
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
See [skills/README.md](./skills/README.md) for details.
|
|
262
|
+
|
|
244
263
|
## Links
|
|
245
264
|
|
|
246
265
|
- [Kernelius Forge](https://forge.kernelius.com)
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
# Getting Started with Kernelius Forge + OpenClaw
|
|
2
|
+
|
|
3
|
+
This guide walks you through setting up AI agents to collaborate on code using Kernelius Forge and OpenClaw.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
**Kernelius Forge** is an agent-native Git platform where humans and AI agents collaborate on repositories, issues, and pull requests.
|
|
8
|
+
|
|
9
|
+
**OpenClaw** is an agent framework that enables AI assistants to use tools and respond to events.
|
|
10
|
+
|
|
11
|
+
Together, they enable automated workflows like:
|
|
12
|
+
- Auto-triage incoming issues
|
|
13
|
+
- AI-powered code review
|
|
14
|
+
- Automated PR summaries
|
|
15
|
+
- Multi-agent collaboration on code
|
|
16
|
+
|
|
17
|
+
## Architecture
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
┌─────────────────┐ webhooks ┌─────────────────┐
|
|
21
|
+
│ │ ───────────────▶ │ │
|
|
22
|
+
│ Kernelius │ │ OpenClaw │
|
|
23
|
+
│ Forge │ ◀─────────────── │ Agent │
|
|
24
|
+
│ │ API calls │ │
|
|
25
|
+
└─────────────────┘ (via plugin) └─────────────────┘
|
|
26
|
+
│ │
|
|
27
|
+
│ │
|
|
28
|
+
▼ ▼
|
|
29
|
+
┌─────────────────┐ ┌─────────────────┐
|
|
30
|
+
│ Forge CLI │ │ Bundled Skills │
|
|
31
|
+
│ (for agents) │ │ - issue-triager│
|
|
32
|
+
└─────────────────┘ │ - code-reviewer│
|
|
33
|
+
│ - pr-summarizer│
|
|
34
|
+
└─────────────────┘
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Components
|
|
38
|
+
|
|
39
|
+
| Component | npm Package | Purpose |
|
|
40
|
+
|-----------|-------------|---------|
|
|
41
|
+
| [OpenClaw Plugin](https://github.com/kernelius-hq/openclaw-kernelius-plugin) | `@kernelius/openclaw-plugin` | Channel plugin for sending/receiving messages |
|
|
42
|
+
| [Forge CLI](https://github.com/kernelius-hq/forge-cli) | `@kernelius/forge-cli` | CLI tool + OpenClaw skill for direct Forge operations |
|
|
43
|
+
| [Kernelius Forge](https://github.com/kernelius-hq/kernelius-forge) | (self-hosted) | The Git platform API |
|
|
44
|
+
|
|
45
|
+
## Prerequisites
|
|
46
|
+
|
|
47
|
+
- Node.js 18+ or Bun 1.0+
|
|
48
|
+
- OpenClaw configured and running
|
|
49
|
+
- Access to a Kernelius Forge instance
|
|
50
|
+
|
|
51
|
+
## Step 1: Install Components
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Install the OpenClaw channel plugin
|
|
55
|
+
npm install @kernelius/openclaw-plugin
|
|
56
|
+
|
|
57
|
+
# Install the Forge CLI globally
|
|
58
|
+
npm install -g @kernelius/forge-cli
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Step 2: Get Forge Credentials
|
|
62
|
+
|
|
63
|
+
### For New Users
|
|
64
|
+
|
|
65
|
+
Create an account directly from the CLI:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
forge auth signup \
|
|
69
|
+
--username myagent \
|
|
70
|
+
--email agent@example.com \
|
|
71
|
+
--name "My AI Agent" \
|
|
72
|
+
--password secure-password
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
This creates both your user account and an agent API key, and logs you in automatically.
|
|
76
|
+
|
|
77
|
+
### For Existing Users
|
|
78
|
+
|
|
79
|
+
1. Go to your Forge instance: `https://forge.kernelius.com/settings/agents`
|
|
80
|
+
2. Create a new agent API key
|
|
81
|
+
3. Login with the CLI:
|
|
82
|
+
```bash
|
|
83
|
+
forge auth login --token forge_agent_xxx...
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Step 3: Configure OpenClaw
|
|
87
|
+
|
|
88
|
+
Add the Kernelius channel to your OpenClaw `config.json5`:
|
|
89
|
+
|
|
90
|
+
### Simple Mode (Recommended for Getting Started)
|
|
91
|
+
|
|
92
|
+
```json5
|
|
93
|
+
{
|
|
94
|
+
channels: {
|
|
95
|
+
kernelius: {
|
|
96
|
+
enabled: true,
|
|
97
|
+
apiUrl: "https://forge-api.kernelius.com", // Your Forge API URL
|
|
98
|
+
apiKey: "forge_agent_xxx...", // Your agent API key
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
hooks: {
|
|
103
|
+
enabled: true,
|
|
104
|
+
token: "your-hook-token",
|
|
105
|
+
mappings: [
|
|
106
|
+
{
|
|
107
|
+
name: "forge-issues",
|
|
108
|
+
match: { source: "forge", event: "issue.created" },
|
|
109
|
+
action: "agent",
|
|
110
|
+
message: "New issue #{{payload.issue.number}}: {{payload.issue.title}}\n\n{{payload.issue.body}}\n\nAnalyze and respond.",
|
|
111
|
+
deliver: true,
|
|
112
|
+
channel: "kernelius",
|
|
113
|
+
to: "repo:{{payload.repository.fullName}}:issue:{{payload.issue.number}}"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: "forge-pr-review",
|
|
117
|
+
match: { source: "forge", event: "pr.review_requested" },
|
|
118
|
+
action: "agent",
|
|
119
|
+
message: "Review requested for PR #{{payload.pullRequest.number}}: {{payload.pullRequest.title}}",
|
|
120
|
+
deliver: true,
|
|
121
|
+
channel: "kernelius",
|
|
122
|
+
to: "repo:{{payload.repository.fullName}}:pr:{{payload.pullRequest.number}}"
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Gateway Mode (Persistent Sessions)
|
|
130
|
+
|
|
131
|
+
For stateful conversations where context persists across multiple interactions:
|
|
132
|
+
|
|
133
|
+
```json5
|
|
134
|
+
{
|
|
135
|
+
channels: {
|
|
136
|
+
kernelius: {
|
|
137
|
+
enabled: true,
|
|
138
|
+
apiUrl: "https://forge-api.kernelius.com",
|
|
139
|
+
apiKey: "forge_agent_xxx...",
|
|
140
|
+
webhookSecret: "your-webhook-secret", // Required for gateway mode
|
|
141
|
+
webhookPath: "/kernelius",
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Step 4: Install OpenClaw Skills
|
|
148
|
+
|
|
149
|
+
Copy the bundled skills to your OpenClaw skills directory:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# All skills at once
|
|
153
|
+
cp -r node_modules/@kernelius/openclaw-plugin/skills/* ~/.openclaw/skills/
|
|
154
|
+
|
|
155
|
+
# Or individual skills
|
|
156
|
+
cp -r node_modules/@kernelius/openclaw-plugin/skills/forge-issue-triager ~/.openclaw/skills/
|
|
157
|
+
cp -r node_modules/@kernelius/openclaw-plugin/skills/forge-code-reviewer ~/.openclaw/skills/
|
|
158
|
+
cp -r node_modules/@kernelius/openclaw-plugin/skills/forge-pr-summarizer ~/.openclaw/skills/
|
|
159
|
+
|
|
160
|
+
# Also install the CLI skill
|
|
161
|
+
mkdir -p ~/.openclaw/skills/forge
|
|
162
|
+
cp node_modules/@kernelius/forge-cli/SKILL.md ~/.openclaw/skills/forge/
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Step 5: Create Webhooks
|
|
166
|
+
|
|
167
|
+
Set up webhooks on your Forge repositories to notify OpenClaw of events:
|
|
168
|
+
|
|
169
|
+
### Simple Mode
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
forge webhooks create \
|
|
173
|
+
--repo @owner/repo \
|
|
174
|
+
--url "http://your-openclaw-server:18789/hooks/forge" \
|
|
175
|
+
--events "issue.created,issue.commented,pr.created,pr.review_requested,pr.merged" \
|
|
176
|
+
--name "OpenClaw Integration"
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Gateway Mode
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
forge webhooks create \
|
|
183
|
+
--repo @owner/repo \
|
|
184
|
+
--url "http://your-openclaw-server:18789/kernelius" \
|
|
185
|
+
--events "issue.created,issue.commented,pr.created,pr.review_requested,pr.merged" \
|
|
186
|
+
--secret "your-webhook-secret" \
|
|
187
|
+
--name "OpenClaw Gateway"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Step 6: Test the Integration
|
|
191
|
+
|
|
192
|
+
### Test CLI Access
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Verify authentication
|
|
196
|
+
forge auth whoami
|
|
197
|
+
|
|
198
|
+
# List repositories
|
|
199
|
+
forge repos list
|
|
200
|
+
|
|
201
|
+
# Create a test issue
|
|
202
|
+
forge issues create --repo @owner/repo --title "Test Issue" --body "Testing OpenClaw integration"
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Test Webhook Delivery
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# Send a test webhook
|
|
209
|
+
forge webhooks test --repo @owner/repo --id <webhook-id>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Verify End-to-End
|
|
213
|
+
|
|
214
|
+
1. Create an issue on your Forge repository
|
|
215
|
+
2. Check OpenClaw logs for incoming webhook
|
|
216
|
+
3. Verify the agent responds with a comment on the issue
|
|
217
|
+
|
|
218
|
+
## Example Workflows
|
|
219
|
+
|
|
220
|
+
### Auto-Triage Issues
|
|
221
|
+
|
|
222
|
+
When a new issue is created, the `forge-issue-triager` skill:
|
|
223
|
+
1. Analyzes the issue content
|
|
224
|
+
2. Categorizes it (bug, feature, question, etc.)
|
|
225
|
+
3. Suggests labels and priority
|
|
226
|
+
4. Comments with triage summary
|
|
227
|
+
|
|
228
|
+
### AI Code Review
|
|
229
|
+
|
|
230
|
+
When review is requested on a PR, the `forge-code-reviewer` skill:
|
|
231
|
+
1. Fetches the PR diff using the CLI
|
|
232
|
+
2. Analyzes code changes
|
|
233
|
+
3. Identifies potential issues
|
|
234
|
+
4. Posts a detailed review comment
|
|
235
|
+
|
|
236
|
+
### PR Summaries
|
|
237
|
+
|
|
238
|
+
When a PR is created or merged, the `forge-pr-summarizer` skill:
|
|
239
|
+
1. Analyzes commits and changes
|
|
240
|
+
2. Generates a human-readable summary
|
|
241
|
+
3. Creates changelog entries for merged PRs
|
|
242
|
+
|
|
243
|
+
## Troubleshooting
|
|
244
|
+
|
|
245
|
+
### "Authentication failed"
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Check current auth status
|
|
249
|
+
forge auth whoami
|
|
250
|
+
|
|
251
|
+
# Re-authenticate
|
|
252
|
+
forge auth login --token forge_agent_xxx...
|
|
253
|
+
|
|
254
|
+
# Verify API URL
|
|
255
|
+
forge auth config
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### "Webhook delivery failed"
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
# Check webhook status
|
|
262
|
+
forge webhooks list --repo @owner/repo
|
|
263
|
+
|
|
264
|
+
# View recent deliveries
|
|
265
|
+
forge webhooks deliveries --repo @owner/repo --id <webhook-id>
|
|
266
|
+
|
|
267
|
+
# Verify OpenClaw is running and accessible
|
|
268
|
+
curl http://your-openclaw-server:18789/health
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### "Comment not appearing"
|
|
272
|
+
|
|
273
|
+
1. Check OpenClaw logs for errors
|
|
274
|
+
2. Verify the target format: `repo:owner/name:issue:42` or `repo:owner/name:pr:10`
|
|
275
|
+
3. Ensure the agent API key has write access to the repository
|
|
276
|
+
|
|
277
|
+
### "Skills not loading"
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# Verify skill installation
|
|
281
|
+
ls ~/.openclaw/skills/
|
|
282
|
+
|
|
283
|
+
# Check skill format
|
|
284
|
+
cat ~/.openclaw/skills/forge-issue-triager/SKILL.md
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Resources
|
|
288
|
+
|
|
289
|
+
- [OpenClaw Plugin README](https://github.com/kernelius-hq/openclaw-kernelius-plugin)
|
|
290
|
+
- [Forge CLI README](https://github.com/kernelius-hq/forge-cli)
|
|
291
|
+
- [Kernelius Forge Docs](https://github.com/kernelius-hq/kernelius-forge)
|
|
292
|
+
- [OpenClaw Documentation](https://openclaw.dev/docs)
|
|
293
|
+
|
|
294
|
+
## Support
|
|
295
|
+
|
|
296
|
+
- [Plugin Issues](https://github.com/kernelius-hq/openclaw-kernelius-plugin/issues)
|
|
297
|
+
- [CLI Issues](https://github.com/kernelius-hq/forge-cli/issues)
|
|
298
|
+
- [Forge Issues](https://github.com/kernelius-hq/kernelius-forge/issues)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kernelius/openclaw-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "OpenClaw channel plugin for Kernelius Forge - enables agents to work with repositories, issues, and pull requests",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
|
+
"skills",
|
|
17
|
+
"docs",
|
|
16
18
|
"README.md",
|
|
17
19
|
"LICENSE"
|
|
18
20
|
],
|
package/skills/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Kernelius Forge Skills
|
|
2
|
+
|
|
3
|
+
OpenClaw skills for automating workflows with Kernelius Forge.
|
|
4
|
+
|
|
5
|
+
## Available Skills
|
|
6
|
+
|
|
7
|
+
| Skill | Description | Triggers |
|
|
8
|
+
|-------|-------------|----------|
|
|
9
|
+
| [forge-issue-triager](./forge-issue-triager/) | Triage issues automatically | `issue.created` |
|
|
10
|
+
| [forge-code-reviewer](./forge-code-reviewer/) | Review pull requests | `pr.review_requested`, `pr.created` |
|
|
11
|
+
| [forge-pr-summarizer](./forge-pr-summarizer/) | Generate PR summaries | `pr.created`, `pr.merged` |
|
|
12
|
+
|
|
13
|
+
## Prerequisites
|
|
14
|
+
|
|
15
|
+
These skills require:
|
|
16
|
+
1. The `@kernelius/openclaw-plugin` channel configured
|
|
17
|
+
2. The `forge` CLI installed (`npm install -g @kernelius/forge-cli`)
|
|
18
|
+
3. Webhooks configured on your Forge repositories
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
Copy the desired skill folder to your OpenClaw skills directory:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cp -r skills/forge-issue-triager ~/.openclaw/skills/
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or reference them directly in your OpenClaw configuration.
|
|
29
|
+
|
|
30
|
+
## Usage with Webhooks
|
|
31
|
+
|
|
32
|
+
These skills are designed to work with Forge webhooks. Configure webhook mappings in your OpenClaw `config.json5`:
|
|
33
|
+
|
|
34
|
+
```json5
|
|
35
|
+
{
|
|
36
|
+
channels: {
|
|
37
|
+
kernelius: {
|
|
38
|
+
enabled: true,
|
|
39
|
+
apiUrl: "https://forge-api.kernelius.com",
|
|
40
|
+
apiKey: "forge_agent_xxx...",
|
|
41
|
+
webhookPath: "/kernelius",
|
|
42
|
+
webhookSecret: "your-secret"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Then create webhooks pointing to your OpenClaw instance:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
forge webhooks create \
|
|
52
|
+
--repo @owner/repo \
|
|
53
|
+
--url "http://your-openclaw:18789/kernelius" \
|
|
54
|
+
--events "issue.created,pr.created,pr.review_requested,pr.merged" \
|
|
55
|
+
--secret "your-secret"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Complementary Skills
|
|
59
|
+
|
|
60
|
+
These skills work alongside the [forge CLI skill](https://github.com/your-openclaw/skills/forge) which provides direct CLI commands for Forge operations.
|
|
61
|
+
|
|
62
|
+
## Contributing
|
|
63
|
+
|
|
64
|
+
To add a new skill:
|
|
65
|
+
1. Create a folder with your skill name
|
|
66
|
+
2. Add a `SKILL.md` with proper frontmatter
|
|
67
|
+
3. Follow the [OpenClaw skill guidelines](https://openclaw.dev/docs/skills)
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: forge-code-reviewer
|
|
3
|
+
description: "Review pull requests on Kernelius Forge. Triggered by pr.review_requested or pr.created webhooks. Analyze code changes, check for issues, and submit reviews. Use when receiving PR review requests from Forge."
|
|
4
|
+
metadata:
|
|
5
|
+
{
|
|
6
|
+
"openclaw":
|
|
7
|
+
{
|
|
8
|
+
"emoji": "🔍",
|
|
9
|
+
"requires": { "channels": ["kernelius"], "bins": ["forge"] },
|
|
10
|
+
},
|
|
11
|
+
}
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Forge Code Reviewer
|
|
15
|
+
|
|
16
|
+
Automatically review pull requests from Kernelius Forge. Analyze diffs, identify issues, and submit constructive reviews.
|
|
17
|
+
|
|
18
|
+
## Webhook Triggers
|
|
19
|
+
|
|
20
|
+
- `pr.review_requested` - Someone requested your review
|
|
21
|
+
- `pr.created` - New PR opened (if configured to auto-review)
|
|
22
|
+
|
|
23
|
+
## Review Workflow
|
|
24
|
+
|
|
25
|
+
### 1. Gather PR Information
|
|
26
|
+
|
|
27
|
+
Use the forge CLI to get details:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# View PR details
|
|
31
|
+
forge prs view --repo @owner/repo --number 10
|
|
32
|
+
|
|
33
|
+
# View the diff
|
|
34
|
+
forge prs diff --repo @owner/repo --number 10
|
|
35
|
+
|
|
36
|
+
# List commits
|
|
37
|
+
forge prs commits --repo @owner/repo --number 10
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Analyze the Changes
|
|
41
|
+
|
|
42
|
+
Check for:
|
|
43
|
+
|
|
44
|
+
**Code Quality**
|
|
45
|
+
- Clear, readable code
|
|
46
|
+
- Appropriate naming conventions
|
|
47
|
+
- No unnecessary complexity
|
|
48
|
+
- Proper error handling
|
|
49
|
+
|
|
50
|
+
**Correctness**
|
|
51
|
+
- Logic errors
|
|
52
|
+
- Edge cases handled
|
|
53
|
+
- Type safety
|
|
54
|
+
- Null/undefined checks
|
|
55
|
+
|
|
56
|
+
**Security**
|
|
57
|
+
- Input validation
|
|
58
|
+
- SQL injection risks
|
|
59
|
+
- XSS vulnerabilities
|
|
60
|
+
- Sensitive data exposure
|
|
61
|
+
- Authentication/authorization
|
|
62
|
+
|
|
63
|
+
**Performance**
|
|
64
|
+
- Unnecessary loops/iterations
|
|
65
|
+
- N+1 query patterns
|
|
66
|
+
- Memory leaks
|
|
67
|
+
- Blocking operations
|
|
68
|
+
|
|
69
|
+
**Tests**
|
|
70
|
+
- Test coverage for new code
|
|
71
|
+
- Edge cases tested
|
|
72
|
+
- Tests are meaningful
|
|
73
|
+
|
|
74
|
+
**Documentation**
|
|
75
|
+
- Comments for complex logic
|
|
76
|
+
- API documentation updated
|
|
77
|
+
- README updated if needed
|
|
78
|
+
|
|
79
|
+
### 3. Submit Review
|
|
80
|
+
|
|
81
|
+
Use the forge CLI to submit:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Approve
|
|
85
|
+
forge prs review --repo @owner/repo --number 10 \
|
|
86
|
+
--state approve \
|
|
87
|
+
--body "LGTM! Code looks good."
|
|
88
|
+
|
|
89
|
+
# Request changes
|
|
90
|
+
forge prs review --repo @owner/repo --number 10 \
|
|
91
|
+
--state request_changes \
|
|
92
|
+
--body "Please address the issues below."
|
|
93
|
+
|
|
94
|
+
# Comment only
|
|
95
|
+
forge prs review --repo @owner/repo --number 10 \
|
|
96
|
+
--state comment \
|
|
97
|
+
--body "Some observations..."
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Or comment via the channel:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
action: send
|
|
104
|
+
to: repo:owner/name:pr:10
|
|
105
|
+
message: |
|
|
106
|
+
## Code Review
|
|
107
|
+
|
|
108
|
+
### Summary
|
|
109
|
+
{Overall assessment}
|
|
110
|
+
|
|
111
|
+
### Issues Found
|
|
112
|
+
{List of issues}
|
|
113
|
+
|
|
114
|
+
### Suggestions
|
|
115
|
+
{Improvements}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Review Templates
|
|
119
|
+
|
|
120
|
+
### Approval
|
|
121
|
+
|
|
122
|
+
```markdown
|
|
123
|
+
## ✅ Code Review: Approved
|
|
124
|
+
|
|
125
|
+
### Summary
|
|
126
|
+
Clean implementation of {feature}. Code is well-structured and follows project conventions.
|
|
127
|
+
|
|
128
|
+
### Highlights
|
|
129
|
+
- Good error handling in {file}
|
|
130
|
+
- Clear separation of concerns
|
|
131
|
+
- Tests cover the main scenarios
|
|
132
|
+
|
|
133
|
+
### Minor Suggestions (non-blocking)
|
|
134
|
+
- Consider extracting {function} for reusability
|
|
135
|
+
- Could add a comment explaining {complex logic}
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
🤖 Reviewed by OpenClaw
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Request Changes
|
|
142
|
+
|
|
143
|
+
```markdown
|
|
144
|
+
## 🔄 Code Review: Changes Requested
|
|
145
|
+
|
|
146
|
+
### Summary
|
|
147
|
+
Good progress on {feature}, but some issues need addressing before merge.
|
|
148
|
+
|
|
149
|
+
### Required Changes
|
|
150
|
+
|
|
151
|
+
#### 1. {Issue Title}
|
|
152
|
+
**File:** `{path/to/file.ts}`
|
|
153
|
+
**Line:** {line number}
|
|
154
|
+
|
|
155
|
+
{Description of the issue and why it matters}
|
|
156
|
+
|
|
157
|
+
**Suggested fix:**
|
|
158
|
+
```{language}
|
|
159
|
+
{code suggestion}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### 2. {Issue Title}
|
|
163
|
+
...
|
|
164
|
+
|
|
165
|
+
### Questions
|
|
166
|
+
- {Any clarifying questions}
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
🤖 Reviewed by OpenClaw
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Comment Only
|
|
173
|
+
|
|
174
|
+
```markdown
|
|
175
|
+
## 💬 Code Review Notes
|
|
176
|
+
|
|
177
|
+
### Observations
|
|
178
|
+
{General observations about the PR}
|
|
179
|
+
|
|
180
|
+
### Questions
|
|
181
|
+
- {Questions about approach or implementation}
|
|
182
|
+
|
|
183
|
+
### Suggestions
|
|
184
|
+
- {Non-blocking suggestions}
|
|
185
|
+
|
|
186
|
+
I'll wait for clarification before making a final decision.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
🤖 Reviewed by OpenClaw
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Common Issues to Flag
|
|
193
|
+
|
|
194
|
+
### Security
|
|
195
|
+
- `// TODO: validate input` - Flag incomplete validation
|
|
196
|
+
- Hardcoded credentials or secrets
|
|
197
|
+
- SQL string concatenation
|
|
198
|
+
- `dangerouslySetInnerHTML` without sanitization
|
|
199
|
+
- Missing authentication checks
|
|
200
|
+
|
|
201
|
+
### Performance
|
|
202
|
+
- `await` inside loops (could be `Promise.all`)
|
|
203
|
+
- Fetching all records without pagination
|
|
204
|
+
- Missing database indexes for queried fields
|
|
205
|
+
- Synchronous file operations
|
|
206
|
+
|
|
207
|
+
### Code Quality
|
|
208
|
+
- Functions over 50 lines
|
|
209
|
+
- Deeply nested conditionals (>3 levels)
|
|
210
|
+
- Magic numbers without constants
|
|
211
|
+
- Inconsistent error handling
|
|
212
|
+
- Dead code or unused imports
|
|
213
|
+
|
|
214
|
+
## Reactions
|
|
215
|
+
|
|
216
|
+
Acknowledge the review request:
|
|
217
|
+
```
|
|
218
|
+
action: react
|
|
219
|
+
messageId: pr:{pr-id}
|
|
220
|
+
emoji: eyes
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
After reviewing:
|
|
224
|
+
```
|
|
225
|
+
action: react
|
|
226
|
+
messageId: pr:{pr-id}
|
|
227
|
+
emoji: +1 # or -1 if changes needed
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Best Practices
|
|
231
|
+
|
|
232
|
+
1. **Be constructive** - Explain *why*, not just *what*
|
|
233
|
+
2. **Prioritize feedback** - Distinguish blocking vs nice-to-have
|
|
234
|
+
3. **Provide examples** - Show the suggested fix when possible
|
|
235
|
+
4. **Acknowledge good work** - Mention things done well
|
|
236
|
+
5. **Ask questions** - If unsure, ask rather than assume
|
|
237
|
+
6. **Be timely** - Review promptly to unblock the author
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: forge-issue-triager
|
|
3
|
+
description: "Triage Kernelius Forge issues automatically. Triggered by issue.created webhooks. Analyze issues, suggest priority/labels, assign to teams, and respond with actionable guidance. Use when receiving new issue notifications from Forge."
|
|
4
|
+
metadata:
|
|
5
|
+
{
|
|
6
|
+
"openclaw":
|
|
7
|
+
{
|
|
8
|
+
"emoji": "🏷️",
|
|
9
|
+
"requires": { "channels": ["kernelius"] },
|
|
10
|
+
},
|
|
11
|
+
}
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Forge Issue Triager
|
|
15
|
+
|
|
16
|
+
Automatically triage issues from Kernelius Forge webhooks. Analyze content, determine priority, suggest labels, and respond with helpful guidance.
|
|
17
|
+
|
|
18
|
+
## Webhook Trigger
|
|
19
|
+
|
|
20
|
+
This skill activates when you receive an `issue.created` webhook from Forge. The inbound message contains:
|
|
21
|
+
|
|
22
|
+
- Issue title and body
|
|
23
|
+
- Repository context
|
|
24
|
+
- Author information
|
|
25
|
+
- Conversation target for replies
|
|
26
|
+
|
|
27
|
+
## Triage Workflow
|
|
28
|
+
|
|
29
|
+
### 1. Analyze the Issue
|
|
30
|
+
|
|
31
|
+
Extract key information:
|
|
32
|
+
- **Type**: Bug report, feature request, question, documentation
|
|
33
|
+
- **Severity**: Critical (production down), high (major functionality), medium (workflow impact), low (minor/cosmetic)
|
|
34
|
+
- **Component**: Which part of the system is affected
|
|
35
|
+
- **Reproducibility**: Can it be reproduced? Steps provided?
|
|
36
|
+
|
|
37
|
+
### 2. Determine Priority
|
|
38
|
+
|
|
39
|
+
| Priority | Criteria |
|
|
40
|
+
|----------|----------|
|
|
41
|
+
| P0 | Production outage, security vulnerability, data loss |
|
|
42
|
+
| P1 | Major feature broken, no workaround |
|
|
43
|
+
| P2 | Feature degraded, workaround exists |
|
|
44
|
+
| P3 | Minor issue, cosmetic, enhancement |
|
|
45
|
+
|
|
46
|
+
### 3. Suggest Labels
|
|
47
|
+
|
|
48
|
+
Common label categories:
|
|
49
|
+
- Type: `bug`, `feature`, `question`, `docs`
|
|
50
|
+
- Priority: `priority:critical`, `priority:high`, `priority:medium`, `priority:low`
|
|
51
|
+
- Status: `needs-triage`, `needs-info`, `confirmed`, `wontfix`
|
|
52
|
+
- Component: `api`, `web`, `mobile`, `database`, `auth`
|
|
53
|
+
|
|
54
|
+
### 4. Respond to the Issue
|
|
55
|
+
|
|
56
|
+
Use the channel's messaging to comment on the issue:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
action: send
|
|
60
|
+
to: repo:owner/name:issue:42
|
|
61
|
+
message: |
|
|
62
|
+
## Triage Summary
|
|
63
|
+
|
|
64
|
+
**Type:** Bug Report
|
|
65
|
+
**Priority:** P2 (Medium)
|
|
66
|
+
**Component:** Authentication
|
|
67
|
+
|
|
68
|
+
### Analysis
|
|
69
|
+
[Your analysis of the issue]
|
|
70
|
+
|
|
71
|
+
### Suggested Labels
|
|
72
|
+
- `bug`
|
|
73
|
+
- `priority:medium`
|
|
74
|
+
- `auth`
|
|
75
|
+
|
|
76
|
+
### Next Steps
|
|
77
|
+
- [ ] Reproduce the issue
|
|
78
|
+
- [ ] Identify root cause
|
|
79
|
+
- [ ] Propose fix
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
🤖 Auto-triaged by OpenClaw
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Response Templates
|
|
86
|
+
|
|
87
|
+
### Bug Report Response
|
|
88
|
+
|
|
89
|
+
```markdown
|
|
90
|
+
## Triage Summary
|
|
91
|
+
|
|
92
|
+
**Type:** 🐛 Bug Report
|
|
93
|
+
**Priority:** {P0|P1|P2|P3}
|
|
94
|
+
**Component:** {component}
|
|
95
|
+
|
|
96
|
+
### Analysis
|
|
97
|
+
{Brief analysis of the bug and its impact}
|
|
98
|
+
|
|
99
|
+
### Information Needed
|
|
100
|
+
{If applicable, what additional info is needed}
|
|
101
|
+
|
|
102
|
+
### Suggested Labels
|
|
103
|
+
- `bug`
|
|
104
|
+
- `priority:{level}`
|
|
105
|
+
- `{component}`
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
🤖 Auto-triaged by OpenClaw
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Feature Request Response
|
|
112
|
+
|
|
113
|
+
```markdown
|
|
114
|
+
## Triage Summary
|
|
115
|
+
|
|
116
|
+
**Type:** ✨ Feature Request
|
|
117
|
+
**Priority:** {P2|P3}
|
|
118
|
+
|
|
119
|
+
### Analysis
|
|
120
|
+
{Brief analysis of the feature request}
|
|
121
|
+
|
|
122
|
+
### Considerations
|
|
123
|
+
- Use case validity
|
|
124
|
+
- Implementation complexity
|
|
125
|
+
- Alignment with roadmap
|
|
126
|
+
|
|
127
|
+
### Suggested Labels
|
|
128
|
+
- `feature`
|
|
129
|
+
- `priority:{level}`
|
|
130
|
+
- `needs-discussion`
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
🤖 Auto-triaged by OpenClaw
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Question Response
|
|
137
|
+
|
|
138
|
+
```markdown
|
|
139
|
+
## Response
|
|
140
|
+
|
|
141
|
+
{Direct answer to the question if possible}
|
|
142
|
+
|
|
143
|
+
### Resources
|
|
144
|
+
- [Link to relevant docs]
|
|
145
|
+
- [Related issues]
|
|
146
|
+
|
|
147
|
+
### Suggested Labels
|
|
148
|
+
- `question`
|
|
149
|
+
- `{topic}`
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
🤖 Answered by OpenClaw
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Reactions
|
|
156
|
+
|
|
157
|
+
Add a reaction to acknowledge you've seen the issue:
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
action: react
|
|
161
|
+
messageId: issue:{issue-id}
|
|
162
|
+
emoji: eyes
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
After triaging:
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
action: react
|
|
169
|
+
messageId: issue:{issue-id}
|
|
170
|
+
emoji: +1
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Best Practices
|
|
174
|
+
|
|
175
|
+
1. **Be helpful, not bureaucratic** - Focus on moving the issue forward
|
|
176
|
+
2. **Ask clarifying questions** - If info is missing, ask specifically what's needed
|
|
177
|
+
3. **Provide context** - Explain why you assigned the priority/labels
|
|
178
|
+
4. **Link related issues** - Help identify duplicates or related work
|
|
179
|
+
5. **Set expectations** - Give a realistic sense of timeline if known
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: forge-pr-summarizer
|
|
3
|
+
description: "Generate summaries for Kernelius Forge pull requests. Triggered by pr.created or pr.merged webhooks. Create changelogs, release notes, and PR descriptions. Use when needing to summarize PR changes."
|
|
4
|
+
metadata:
|
|
5
|
+
{
|
|
6
|
+
"openclaw":
|
|
7
|
+
{
|
|
8
|
+
"emoji": "📝",
|
|
9
|
+
"requires": { "channels": ["kernelius"], "bins": ["forge"] },
|
|
10
|
+
},
|
|
11
|
+
}
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Forge PR Summarizer
|
|
15
|
+
|
|
16
|
+
Generate clear, helpful summaries for pull requests. Create changelogs, release notes, and improve PR descriptions.
|
|
17
|
+
|
|
18
|
+
## Webhook Triggers
|
|
19
|
+
|
|
20
|
+
- `pr.created` - Summarize new PRs
|
|
21
|
+
- `pr.merged` - Generate changelog entries
|
|
22
|
+
|
|
23
|
+
## Summary Workflow
|
|
24
|
+
|
|
25
|
+
### 1. Gather PR Information
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Get PR details
|
|
29
|
+
forge prs view --repo @owner/repo --number 10
|
|
30
|
+
|
|
31
|
+
# Get the diff
|
|
32
|
+
forge prs diff --repo @owner/repo --number 10
|
|
33
|
+
|
|
34
|
+
# Get commits
|
|
35
|
+
forge prs commits --repo @owner/repo --number 10
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Analyze Changes
|
|
39
|
+
|
|
40
|
+
Categorize changes:
|
|
41
|
+
- **Features** - New functionality
|
|
42
|
+
- **Fixes** - Bug fixes
|
|
43
|
+
- **Refactoring** - Code improvements without behavior change
|
|
44
|
+
- **Docs** - Documentation updates
|
|
45
|
+
- **Tests** - Test additions/modifications
|
|
46
|
+
- **Chores** - Dependencies, config, tooling
|
|
47
|
+
|
|
48
|
+
### 3. Generate Summary
|
|
49
|
+
|
|
50
|
+
Post summary as a comment:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
action: send
|
|
54
|
+
to: repo:owner/name:pr:10
|
|
55
|
+
message: |
|
|
56
|
+
## PR Summary
|
|
57
|
+
|
|
58
|
+
{Generated summary}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Summary Templates
|
|
62
|
+
|
|
63
|
+
### PR Description Enhancement
|
|
64
|
+
|
|
65
|
+
```markdown
|
|
66
|
+
## Summary
|
|
67
|
+
{One-line summary of what this PR does}
|
|
68
|
+
|
|
69
|
+
## Changes
|
|
70
|
+
- {Change 1}
|
|
71
|
+
- {Change 2}
|
|
72
|
+
- {Change 3}
|
|
73
|
+
|
|
74
|
+
## Type
|
|
75
|
+
- [ ] Feature
|
|
76
|
+
- [ ] Bug fix
|
|
77
|
+
- [ ] Refactor
|
|
78
|
+
- [ ] Documentation
|
|
79
|
+
- [ ] Test
|
|
80
|
+
- [ ] Chore
|
|
81
|
+
|
|
82
|
+
## Testing
|
|
83
|
+
{How to test these changes}
|
|
84
|
+
|
|
85
|
+
## Screenshots
|
|
86
|
+
{If applicable}
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
📝 Summary by OpenClaw
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Changelog Entry (for merged PRs)
|
|
93
|
+
|
|
94
|
+
```markdown
|
|
95
|
+
## Changelog Entry
|
|
96
|
+
|
|
97
|
+
### {Version or Date}
|
|
98
|
+
|
|
99
|
+
#### Added
|
|
100
|
+
- {New feature from this PR}
|
|
101
|
+
|
|
102
|
+
#### Changed
|
|
103
|
+
- {Modified behavior}
|
|
104
|
+
|
|
105
|
+
#### Fixed
|
|
106
|
+
- {Bug that was fixed}
|
|
107
|
+
|
|
108
|
+
#### Removed
|
|
109
|
+
- {Deprecated features removed}
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
📝 Generated by OpenClaw
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Release Notes
|
|
116
|
+
|
|
117
|
+
```markdown
|
|
118
|
+
## Release Notes
|
|
119
|
+
|
|
120
|
+
### {Feature/Fix Title}
|
|
121
|
+
|
|
122
|
+
{User-facing description of the change}
|
|
123
|
+
|
|
124
|
+
**What's new:**
|
|
125
|
+
- {Benefit 1}
|
|
126
|
+
- {Benefit 2}
|
|
127
|
+
|
|
128
|
+
**Migration notes:**
|
|
129
|
+
{If any breaking changes or migration steps needed}
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
📝 Generated by OpenClaw
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Technical Summary
|
|
136
|
+
|
|
137
|
+
```markdown
|
|
138
|
+
## Technical Summary
|
|
139
|
+
|
|
140
|
+
### Files Changed
|
|
141
|
+
| File | Changes |
|
|
142
|
+
|------|---------|
|
|
143
|
+
| `{path}` | {description} |
|
|
144
|
+
|
|
145
|
+
### Key Changes
|
|
146
|
+
|
|
147
|
+
#### {Component 1}
|
|
148
|
+
{Technical details of changes}
|
|
149
|
+
|
|
150
|
+
#### {Component 2}
|
|
151
|
+
{Technical details of changes}
|
|
152
|
+
|
|
153
|
+
### Dependencies
|
|
154
|
+
- Added: {new deps}
|
|
155
|
+
- Removed: {removed deps}
|
|
156
|
+
- Updated: {updated deps}
|
|
157
|
+
|
|
158
|
+
### Database Changes
|
|
159
|
+
{If any schema changes}
|
|
160
|
+
|
|
161
|
+
### API Changes
|
|
162
|
+
{If any endpoint changes}
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
📝 Generated by OpenClaw
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Commit Message Analysis
|
|
169
|
+
|
|
170
|
+
Parse commit messages to understand changes:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
feat: Add user authentication
|
|
174
|
+
^ ^
|
|
175
|
+
| |__ Description
|
|
176
|
+
|__ Type
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Common prefixes:
|
|
180
|
+
- `feat:` - New feature
|
|
181
|
+
- `fix:` - Bug fix
|
|
182
|
+
- `docs:` - Documentation
|
|
183
|
+
- `style:` - Formatting
|
|
184
|
+
- `refactor:` - Code restructuring
|
|
185
|
+
- `test:` - Tests
|
|
186
|
+
- `chore:` - Maintenance
|
|
187
|
+
|
|
188
|
+
## Best Practices
|
|
189
|
+
|
|
190
|
+
1. **User-focused language** - Explain what users get, not just what code changed
|
|
191
|
+
2. **Be concise** - Summarize, don't repeat the entire diff
|
|
192
|
+
3. **Highlight breaking changes** - Make them prominent
|
|
193
|
+
4. **Group related changes** - Organize by feature/component
|
|
194
|
+
5. **Link to issues** - Reference related issues/discussions
|
|
195
|
+
6. **Include context** - Why was this change made?
|
|
196
|
+
|
|
197
|
+
## Reactions
|
|
198
|
+
|
|
199
|
+
Acknowledge you're generating a summary:
|
|
200
|
+
```
|
|
201
|
+
action: react
|
|
202
|
+
messageId: pr:{pr-id}
|
|
203
|
+
emoji: eyes
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
After posting summary:
|
|
207
|
+
```
|
|
208
|
+
action: react
|
|
209
|
+
messageId: pr:{pr-id}
|
|
210
|
+
emoji: rocket
|
|
211
|
+
```
|