Skip to content

Commit b8e8659

Browse files
gxklclaude
andcommitted
fix(skills): address PR #5834 review feedback
- Fix skill directory naming: controller/ → egg-controller/ in CLAUDE.md - Fix /ant-skill-creator → /skill-creator reference - Add language specifiers to fenced code blocks - Update egg-core/egg-controller descriptions with new capabilities - Fix BackgroundTaskHelper.run() execution timing: task starts immediately, framework waits at Context preDestroy - Fix error log format to match implementation (no space after colon) - Fix example file path to match module directory convention - Remove hardcoded 422 status from AjvInvalidParamError description Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 4417c8f commit b8e8659

File tree

3 files changed

+24
-25
lines changed

3 files changed

+24
-25
lines changed

packages/skills/CLAUDE.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
`packages/skills/` 目录包含 AI agent skills — 纯 markdown 文档,指导 AI 助手使用 Egg 框架。以 `@eggjs/skills` npm 包发布,仅含 `.md` 文件。
44

5-
> **Skill 编写基础知识**:SKILL.md 格式、frontmatter 规范、目录结构、progressive disclosure、写作风格等通用知识请使用 `/ant-skill-creator` skill 获取指导。以下仅记录 Egg 项目特有的约定。
5+
> **Skill 编写基础知识**:SKILL.md 格式、frontmatter 规范、目录结构、progressive disclosure、写作风格等通用知识请使用 `/skill-creator` skill 获取指导。以下仅记录 Egg 项目特有的约定。
66
77
## Egg Skills 架构
88

99
Skills 采用分层路由模式:
1010

1111
- **入口 skill** (`egg/`) — 分析用户意图,通过关键词匹配和决策逻辑路由到专业 skill
1212
- **专业 skills** — 提供特定领域的深度指导:
13-
- `egg-core/` — 核心概念:模块、依赖注入、生命周期、AccessLevel
14-
- `controller/` — 实现指导:HTTPController、MCPController、Schedule
13+
- `egg-core/` — 核心概念:模块、依赖注入、生命周期、AccessLevel、后台任务
14+
- `egg-controller/` — 实现指导:HTTPController、MCPController、Schedule、Ajv 校验
1515

1616
## Egg Skill Frontmatter 约定
1717

@@ -36,10 +36,10 @@ Skills 采用分层路由模式:
3636

3737
**专业 Skill 两种组织模式:**
3838

39-
| 模式 | ant-skill-creator 对应 | 适用场景 | SKILL.md 内容 | references/ 用途 |
40-
| ------------------------------ | ---------------------- | ------------------ | ----------------------- | ------------------ |
41-
| **概念型**(如 `egg-core/`| Reference-Based | 概念解释、架构理解 | 自包含的深度内容 | 更深入的专题文档 |
42-
| **索引型**(如 `controller/`| Workflow-Based | 多种实现方式的选择 | 精简的决策树 + 快速参考 | 每种实现的详细指南 |
39+
| 模式 | ant-skill-creator 对应 | 适用场景 | SKILL.md 内容 | references/ 用途 |
40+
| ---------------------------------- | ---------------------- | ------------------ | ----------------------- | ------------------ |
41+
| **概念型**(如 `egg-core/` | Reference-Based | 概念解释、架构理解 | 自包含的深度内容 | 更深入的专题文档 |
42+
| **索引型**(如 `egg-controller/`| Workflow-Based | 多种实现方式的选择 | 精简的决策树 + 快速参考 | 每种实现的详细指南 |
4343

4444
**概念型 Skill 内容结构:**
4545

@@ -92,11 +92,11 @@ Skill 的价值 = 文档 + 实践经验 - 重复内容。如果内容和 `site/d
9292
## 添加新 Skill
9393

9494
1.`packages/skills/` 下创建目录:`packages/skills/<skill-name>/`
95-
2. 创建 `SKILL.md`(格式规范参考 `/ant-skill-creator`,frontmatter 遵循上述 Egg 约定)
95+
2. 创建 `SKILL.md`(格式规范参考 `/skill-creator`,frontmatter 遵循上述 Egg 约定)
9696
3. 创建 `references/` 目录(初始为空时放置 `.gitkeep`
9797
4. 按需在 `references/*.md` 中添加详细参考文档
9898
5. 更新入口 skill(`egg/SKILL.md`)的路由逻辑以包含新 skill
99-
6. 如果 skill 涉及 controller 类型,同时更新 `controller/SKILL.md` 决策树
99+
6. 如果 skill 涉及 controller 类型,同时更新 `egg-controller/SKILL.md` 决策树
100100

101101
## 添加新 Reference 文档
102102

@@ -112,7 +112,7 @@ Skill 的价值 = 文档 + 实践经验 - 重复内容。如果内容和 `site/d
112112

113113
**评测文件结构:**
114114

115-
```
115+
```text
116116
packages/skills/eval/
117117
├── evals-egg-core.json # egg-core skill 评测用例
118118
├── evals-egg-controller.json # egg-controller skill 评测用例
@@ -169,7 +169,7 @@ packages/skills/eval/
169169

170170
with-skill 环境:
171171

172-
```
172+
```text
173173
你是 EGG 框架开发专家。你只能通过 Read 工具读取 packages/skills/ 目录下的文件,不能访问 site/docs/ 或项目源码。
174174
175175
{egg/SKILL.md 的完整内容}
@@ -180,7 +180,7 @@ with-skill 环境:
180180

181181
site-docs 环境:
182182

183-
```
183+
```text
184184
你是 EGG 框架开发专家。你只能通过 Read 工具读取 site/docs/ 目录下的文件,不能访问 packages/skills/ 或项目源码。项目文档目录如下:
185185
186186
{完整的 site/docs/ 文件列表,通过 find site/docs -name '*.md' | sort 生成}

packages/skills/egg-controller/references/ajv-validate.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { Ajv, Type, Static, TransformEnum } from 'egg/ajv';
3131
### 完整示例
3232

3333
```typescript
34-
// app/modules/demo/FooController.ts
34+
// app/userModule/UserController.ts
3535
import {
3636
HTTPController,
3737
HTTPMethod,
@@ -66,7 +66,7 @@ export class UserController {
6666
path: '/api/users',
6767
})
6868
async create(@HTTPBody() body: CreateUserParams) {
69-
// 校验失败自动抛出 AjvInvalidParamError(422)
69+
// 校验失败自动抛出 AjvInvalidParamError
7070
this.ajv.validate(CreateUserSchema, body);
7171

7272
// 校验通过,body 已经有完整类型提示
@@ -142,5 +142,5 @@ Type.String({
142142

143143
- **Schema 与 Controller 同文件** — Schema 定义放在使用它的 Controller 文件中,保持就近原则
144144
- **校验在 Controller 层** — 不要在 Service 层做入参校验,Service 信任上层传入的数据
145-
- **善用 Optional** — 非必填字段用 `Type.Optional()` 包装,避免前端遗漏字段导致 422
145+
- **善用 Optional** — 非必填字段用 `Type.Optional()` 包装,避免前端遗漏字段导致校验失败
146146
- **善用 transform** — 对用户输入做 trim 预处理,减少脏数据

packages/skills/egg-core/references/background-task.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
### 基本用法
1818

19-
通过 `@Inject()` 注入 `BackgroundTaskHelper`,调用 `run()` 方法。`run()` 接受一个异步函数,在请求返回后执行
19+
通过 `@Inject()` 注入 `BackgroundTaskHelper`,调用 `run()` 方法。`run()` 接受一个异步函数,任务会立即开始执行但不阻塞当前流程。框架在请求结束(Context preDestroy)时会等待所有后台任务完成(最多等待 timeout),然后再释放上下文
2020

2121
```typescript
2222
import { BackgroundTaskHelper, Inject, SingletonProto, AccessLevel } from 'egg';
@@ -27,10 +27,9 @@ export class MetricsService {
2727
private backgroundTaskHelper: BackgroundTaskHelper;
2828

2929
async reportAfterResponse(data: Record<string, unknown>) {
30-
// run() 是非阻塞的,调用后立即返回
30+
// run() 是非阻塞的,任务立即开始执行但不会被 await
3131
this.backgroundTaskHelper.run(async () => {
32-
// 这里的代码在 HTTP 响应发送后执行
33-
// 可以安全访问注入的服务和上下文
32+
// 框架会保持上下文存活直到任务完成或超时
3433
await this.sendMetrics(data);
3534
});
3635
}
@@ -86,7 +85,7 @@ BackgroundTaskHelper 内部会捕获所有错误并记录日志,**不会**抛
8685
this.backgroundTaskHelper.run(async () => {
8786
// 即使这里抛出异常,也不会影响其他后台任务或框架
8887
throw new Error('something went wrong');
89-
// 错误会被记录为: [BackgroundTaskHelper] background throw error: something went wrong
88+
// 错误会被记录为: [BackgroundTaskHelper] background throw error:something went wrong
9089
});
9190

9291
// 如果需要自定义错误处理
@@ -108,9 +107,9 @@ this.backgroundTaskHelper.run(async () => {
108107

109108
BackgroundTaskHelper 的作用是:
110109

111-
1. 告诉框架"先不要释放上下文"
112-
2. 排队执行异步任务
113-
3. 等待完成(或超时
114-
4. 然后再释放上下文
110+
1. `run()` 被调用时,任务立即开始执行(不是延后到响应发送后)
111+
2. 任务不会被 await,因此不阻塞当前请求的返回
112+
3. 请求结束时(Context preDestroy),框架等待所有后台任务完成(最多等待 timeout
113+
4. 等待结束后才释放上下文
115114

116-
这就是为什么必须用 `backgroundTaskHelper.run()` 而不是 `setTimeout` — 后者绕过了框架的上下文生命周期管理。
115+
这就是为什么必须用 `backgroundTaskHelper.run()` 而不是 `setTimeout` — 后者绕过了框架的上下文生命周期管理,执行时上下文可能已被释放

0 commit comments

Comments
 (0)