feat: 添加 cnb-board 路由及相关功能,获取 live 的 repo、构建、PR、NPC 和评论信息,并更新文档
fix: 更新 SKILL.md 文件格式,调整 metadata 标签位置
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
---
|
||||
name: kill-opencode
|
||||
description: 自动查找并杀死所有opencode相关的进程,确保系统资源释放。
|
||||
tags:
|
||||
- opencode
|
||||
- process-management
|
||||
- automation
|
||||
metadata:
|
||||
tags:
|
||||
- opencode
|
||||
- process-management
|
||||
- automation
|
||||
---
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
77
assistant/.opencode/skills/opencode-skill-creator/SKILL.md
Normal file
77
assistant/.opencode/skills/opencode-skill-creator/SKILL.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
name: opencode-skill-creator
|
||||
description: 教你如何在opencode中创建自定义skill
|
||||
---
|
||||
|
||||
## Skill 创建指南
|
||||
|
||||
### 目录结构
|
||||
|
||||
每个skill都是一个文件夹,包含以下文件:
|
||||
```
|
||||
skills/
|
||||
└── your-skill-name/
|
||||
└── SKILL.md
|
||||
```
|
||||
|
||||
### SKILL.md 文件格式
|
||||
|
||||
使用 YAML frontmatter 定义元数据:
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: 技能名称
|
||||
description: 技能描述
|
||||
---
|
||||
```
|
||||
|
||||
### Frontmatter 字段说明
|
||||
|
||||
| 字段 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `name` | 是 | 技能名称,用于显示在技能列表中 |
|
||||
| `description` | 是 | 技能简短描述 |
|
||||
|
||||
### 技能内容规范
|
||||
|
||||
1. **描述要详细**:清楚地说明这个skill能做什么
|
||||
2. **提供示例**:包含实际使用的代码示例
|
||||
3. **说明参数**:列出所有可用参数及其作用
|
||||
4. **保持简洁**:避免冗长的说明
|
||||
|
||||
### 创建步骤
|
||||
|
||||
1. 在 `/workspace/.opencode/skills/` 目录下创建新文件夹
|
||||
2. 在文件夹中创建 `SKILL.md` 文件
|
||||
3. 编写frontmatter和内容
|
||||
4. 技能将自动被系统识别
|
||||
|
||||
### 示例
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: 示例技能
|
||||
description: 这是一个示例技能的描述
|
||||
---
|
||||
|
||||
这是一个详细的技能说明文档。
|
||||
|
||||
## 使用方法
|
||||
|
||||
```bash
|
||||
# 示例命令
|
||||
echo "Hello World"
|
||||
```
|
||||
|
||||
## 参数说明
|
||||
|
||||
- `param1`: 参数1说明
|
||||
- `param2`: 参数2说明
|
||||
```
|
||||
|
||||
### 注意事项
|
||||
|
||||
- 文件名必须是 `SKILL.md`(大写)
|
||||
- frontmatter 必须使用 `---` 包裹
|
||||
- 内容支持 Markdown 语法
|
||||
- 可以包含代码块、表格、列表等
|
||||
213
assistant/.opencode/skills/router-creator/SKILL.md
Normal file
213
assistant/.opencode/skills/router-creator/SKILL.md
Normal file
@@ -0,0 +1,213 @@
|
||||
---
|
||||
name: router-creator
|
||||
description: 教你如何使用 @kevisual/router 创建和管理路由
|
||||
metadata:
|
||||
tags:
|
||||
- router
|
||||
- api
|
||||
- routes
|
||||
---
|
||||
|
||||
# router
|
||||
|
||||
一个轻量级的路由框架,支持链式调用、中间件、嵌套路由等功能。
|
||||
|
||||
## 快速开始
|
||||
|
||||
```ts
|
||||
import { App } from '@kevisual/router';
|
||||
|
||||
const app = new App();
|
||||
app.listen(4002);
|
||||
|
||||
app
|
||||
.route({ path: 'demo', key: '02' })
|
||||
.define(async (ctx) => {
|
||||
ctx.body = '02';
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({ path: 'demo', key: '03' })
|
||||
.define(async (ctx) => {
|
||||
ctx.body = '03';
|
||||
})
|
||||
.addTo(app);
|
||||
```
|
||||
|
||||
## 核心概念
|
||||
|
||||
### RouteContext 属性说明
|
||||
|
||||
在 route handler 中,你可以通过 `ctx` 访问以下属性:
|
||||
|
||||
| 属性 | 类型 | 说明 |
|
||||
| --------------- | ---------------------------- | ---------------------------- |
|
||||
| `query` | `object` | 请求参数,会自动合并 payload |
|
||||
| `body` | `number \| string \| Object` | 响应内容 |
|
||||
| `code` | `number` | 响应状态码,默认为 200 |
|
||||
| `message` | `string` | 响应消息 |
|
||||
| `state` | `any` | 状态数据,可在路由间传递 |
|
||||
| `appId` | `string` | 应用标识 |
|
||||
| `currentId` | `string` | 当前路由ID |
|
||||
| `currentPath` | `string` | 当前路由路径 |
|
||||
| `currentKey` | `string` | 当前路由 key |
|
||||
| `currentRoute` | `Route` | 当前 Route 实例 |
|
||||
| `progress` | `[string, string][]` | 路由执行路径记录 |
|
||||
| `nextQuery` | `object` | 传递给下一个路由的参数 |
|
||||
| `end` | `boolean` | 是否提前结束路由执行 |
|
||||
| `app` | `QueryRouter` | 路由实例引用 |
|
||||
| `error` | `any` | 错误信息 |
|
||||
| `index` | `number` | 当前路由执行深度 |
|
||||
| `needSerialize` | `boolean` | 是否需要序列化响应数据 |
|
||||
|
||||
### 上下文方法
|
||||
|
||||
| 方法 | 参数 | 说明 |
|
||||
| ----------------------------------- | ----------------------------------------- | -------------------------------------------- |
|
||||
| `ctx.call(msg, ctx?)` | `{ path, key?, payload?, ... } \| { id }` | 调用其他路由,返回完整 context |
|
||||
| `ctx.run(msg, ctx?)` | `{ path, key?, payload? }` | 调用其他路由,返回 `{ code, data, message }` |
|
||||
| `ctx.forward(res)` | `{ code, data?, message? }` | 设置响应结果 |
|
||||
| `ctx.throw(code?, message?, tips?)` | - | 抛出自定义错误 |
|
||||
|
||||
## 完整示例
|
||||
|
||||
```ts
|
||||
import { App } from '@kevisual/router';
|
||||
import z from 'zod';
|
||||
const app = new App();
|
||||
app.listen(4002);
|
||||
|
||||
// 基本路由
|
||||
app
|
||||
.route({ path: 'user', key: 'info', id: 'user-info' })
|
||||
.define(async (ctx) => {
|
||||
// ctx.query 包含请求参数
|
||||
const { id } = ctx.query;
|
||||
// 使用 state 在路由间传递数据
|
||||
ctx.state.orderId = '12345';
|
||||
ctx.body = { id, name: '张三' };
|
||||
ctx.code = 200;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({ path: 'order', key: 'pay', middleware: ['user-info'] })
|
||||
.define(async (ctx) => {
|
||||
// 可以获取前一个路由设置的 state
|
||||
const { orderId } = ctx.state;
|
||||
ctx.body = { orderId, status: 'paid' };
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
// 调用其他路由
|
||||
app
|
||||
.route({ path: 'dashboard', key: 'stats' })
|
||||
.define(async (ctx) => {
|
||||
// 调用 user/info 路由
|
||||
const userRes = await ctx.run({ path: 'user', key: 'info', payload: { id: 1 } });
|
||||
// 调用 product/list 路由
|
||||
const productRes = await ctx.run({ path: 'product', key: 'list' });
|
||||
|
||||
ctx.body = {
|
||||
user: userRes.data,
|
||||
products: productRes.data,
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
// 使用 throw 抛出错误
|
||||
app
|
||||
.route({ path: 'admin', key: 'delete' })
|
||||
.define(async (ctx) => {
|
||||
const { id } = ctx.query;
|
||||
if (!id) {
|
||||
ctx.throw(400, '缺少参数', 'id is required');
|
||||
}
|
||||
ctx.body = { success: true };
|
||||
})
|
||||
.addTo(app);
|
||||
```
|
||||
|
||||
## 中间件
|
||||
|
||||
```ts
|
||||
import { App, Route } from '@kevisual/router';
|
||||
|
||||
const app = new App();
|
||||
|
||||
// 定义中间件
|
||||
app
|
||||
.route({
|
||||
id: 'auth-example',
|
||||
description: '权限校验中间件',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const token = ctx.query.token;
|
||||
if (!token) {
|
||||
ctx.throw(401, '未登录', '需要 token');
|
||||
}
|
||||
// 验证通过,设置用户信息到 state
|
||||
ctx.state.tokenUser = { id: 1, name: '用户A' };
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
// 使用中间件(通过 id 引用)
|
||||
app
|
||||
.route({ path: 'admin', key: 'panel', middleware: ['auth-example'] })
|
||||
.define(async (ctx) => {
|
||||
// 可以访问中间件设置的 state
|
||||
const { tokenUser } = ctx.state;
|
||||
ctx.body = { tokenUser };
|
||||
})
|
||||
.addTo(app);
|
||||
```
|
||||
|
||||
## 一个丰富的router示例
|
||||
|
||||
```ts
|
||||
import { App } from '@kevisual/router';
|
||||
const app = new App();
|
||||
|
||||
app
|
||||
.router({
|
||||
path: 'dog',
|
||||
key: 'info',
|
||||
description: '获取狗的信息',
|
||||
metedata: {
|
||||
args: {
|
||||
owner: z.string().describe('狗主人姓名'),
|
||||
age: z.number().describe('狗的年龄'),
|
||||
},
|
||||
},
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const { owner, age } = ctx.query;
|
||||
ctx.body = {
|
||||
content: `这是一只${age}岁的狗,主人是${owner}`,
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **path 和 key 的组合是路由的唯一标识**,同一个 path+key 只能添加一个路由,后添加的会覆盖之前的。
|
||||
|
||||
2. **ctx.call vs ctx.run**:
|
||||
- `call` 返回完整 context,包含所有属性
|
||||
- `run` 返回 `{ code, data, message }` 格式,data 即 body
|
||||
|
||||
3. **ctx.throw 会自动结束执行**,抛出自定义错误。
|
||||
|
||||
4. **payload 会自动合并到 query**,调用 `ctx.run({ path, key, payload })` 时,payload 会合并到 query。
|
||||
|
||||
5. **nextQuery 用于传递给 nextRoute**,在当前路由中设置 `ctx.nextQuery`,会在执行 nextRoute 时合并到 query。
|
||||
|
||||
6. **避免 nextRoute 循环调用**,默认最大深度为 40 次,超过会返回 500 错误。
|
||||
|
||||
7. **needSerialize 默认为 true**,会自动对 body 进行 JSON 序列化和反序列化。
|
||||
|
||||
8. **progress 记录执行路径**,可用于调试和追踪路由调用链。
|
||||
|
||||
9. **中间件找不到会返回 404**,错误信息中会包含找不到的中间件列表。
|
||||
Reference in New Issue
Block a user