Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions packages/skills/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

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

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

## Egg Skills 架构

Skills 采用分层路由模式:

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

## Egg Skill Frontmatter 约定

Expand All @@ -25,7 +25,7 @@ Skills 采用分层路由模式:

**入口 Skill(如 `egg/`)编写要点:**

对应 ant-skill-creator 的 **Workflow-Based** 模式。
对应 /skill-creator 的 **Workflow-Based** 模式。

1. 决策框架包含明确步骤:识别意图 → 检查模糊意图 → 协议/用例特定指示
2. 为每个专业 skill 列出中英文触发关键词
Expand All @@ -36,10 +36,10 @@ Skills 采用分层路由模式:

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

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

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

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

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

## 添加新 Reference 文档

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

**评测文件结构:**

```
```text
packages/skills/eval/
├── evals-egg-core.json # egg-core skill 评测用例
├── evals-egg-controller.json # egg-controller skill 评测用例
Expand Down Expand Up @@ -169,7 +169,7 @@ packages/skills/eval/

with-skill 环境:

```
```text
你是 EGG 框架开发专家。你只能通过 Read 工具读取 packages/skills/ 目录下的文件,不能访问 site/docs/ 或项目源码。

{egg/SKILL.md 的完整内容}
Expand All @@ -180,7 +180,7 @@ with-skill 环境:

site-docs 环境:

```
```text
你是 EGG 框架开发专家。你只能通过 Read 工具读取 site/docs/ 目录下的文件,不能访问 packages/skills/ 或项目源码。项目文档目录如下:

{完整的 site/docs/ 文件列表,通过 find site/docs -name '*.md' | sort 生成}
Expand Down
2 changes: 1 addition & 1 deletion packages/skills/egg-controller/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: egg-controller
description: Use when creating API endpoints, implementing protocol handlers, or exposing interfaces for specific clients. Covers HTTP, MCP and Schedule controllers for EGG framework applications.
description: Use when creating API endpoints, implementing protocol handlers, exposing interfaces for specific clients, or adding parameter validation. Covers HTTP, MCP and Schedule controllers, and Ajv/TypeBox parameter validation for EGG framework applications.
allowed-tools: Read
---

Expand Down
6 changes: 3 additions & 3 deletions packages/skills/egg-controller/references/ajv-validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { Ajv, Type, Static, TransformEnum } from 'egg/ajv';
### 完整示例

```typescript
// app/modules/demo/FooController.ts
// app/userModule/UserController.ts
import {
HTTPController,
HTTPMethod,
Expand Down Expand Up @@ -66,7 +66,7 @@ export class UserController {
path: '/api/users',
})
async create(@HTTPBody() body: CreateUserParams) {
// 校验失败自动抛出 AjvInvalidParamError(422)
// 校验失败自动抛出 AjvInvalidParamError
this.ajv.validate(CreateUserSchema, body);

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

- **Schema 与 Controller 同文件** — Schema 定义放在使用它的 Controller 文件中,保持就近原则
- **校验在 Controller 层** — 不要在 Service 层做入参校验,Service 信任上层传入的数据
- **善用 Optional** — 非必填字段用 `Type.Optional()` 包装,避免前端遗漏字段导致 422
- **善用 Optional** — 非必填字段用 `Type.Optional()` 包装,避免前端遗漏字段导致校验失败
- **善用 transform** — 对用户输入做 trim 预处理,减少脏数据
73 changes: 48 additions & 25 deletions packages/skills/egg-core/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
---
name: egg-core
description: 本技能用于处理 EGG 基础核心概念,包括模块架构、@SingletonProto、@ContextProto、@Inject 装饰器和动态注入。用于理解 EGG 的基础构建块、依赖注入、对象生命周期管理和运行时多实现动态选择
description: 本技能用于处理 EGG 基础核心概念,包括模块架构、@SingletonProto、@ContextProto、@Inject 装饰器、动态注入、BackgroundTaskHelper 后台任务、EventBus 事件总线和 AOP 切面编程。用于理解 EGG 的基础构建块、依赖注入、对象生命周期管理、运行时多实现动态选择、请求返回后的异步任务处理、事件驱动架构和横切关注点
allowed-tools: Read
---

# egg 核心概念

## Step 1: 代码写在 module 中
## 代码组织与依赖注入

### 什么是模块?
### Step 1: 代码写在 module 中

#### 什么是模块?

模块是 EGG 中基础的代码组织单元。只有模块内的代码会被框架扫描和加载。模块之间相互独立,但可以通过 `@Inject` 装饰器访问其他模块的对象。

### 定义 module
#### 定义 module

在目录中添加包含 `eggModule.name` 字段的 `package.json` 文件来声明该目录为模块:

Expand Down Expand Up @@ -97,9 +99,9 @@ import { SingletonProto } from '@eggjs/tegg';

---

## Step 2: 用 Proto 实现 Service
### Step 2: 用 Proto 实现 Service

### SingletonProto
#### SingletonProto

应用启动时立即创建,整个应用生命周期内只有一个实例,性能更好,应该作为默认选择。

Expand All @@ -114,7 +116,7 @@ export class HelloService {
}
```

### ContextProto
#### ContextProto

请求到达时按需创建,每个请求一个实例,请求结束自动销毁。仅在需要隔离不同请求的上下文信息时使用。

Expand All @@ -129,7 +131,7 @@ export class RequestContext {

**重要提示**:大多数服务应该使用 `SingletonProto` 以获得更好的性能。只有当请求上下文必须在服务之间共享以确保请求之间隔离时,才使用 `ContextProto`。

### AccessLevel
#### AccessLevel

proto 对象默认 accessLevel 为 `AccessLevel.PRIVATE`,仅在当前 module 内使用。可以设置为 `AccessLevel.PUBLIC`,进行跨模块访问。

Expand All @@ -143,9 +145,9 @@ export class SharedService {}
export class SharedContextService {}
```

## Step 3: 通过 Inject 使用 Service
### Step 3: 通过 Inject 使用 Service

### 基本用法
#### 基本用法

使用 `@Inject()` 注入其他 Proto 或 Egg 对象:

Expand All @@ -167,43 +169,62 @@ export class HelloService {
}
```

### 动态注入
#### 动态注入

当同一个抽象有多种实现,需要在运行时动态选择时,通过 `EggObjectFactory` 按类型获取实现,无需 if/else。详见 `references/dynamic-inject.md`。

### 重要约束
#### 重要约束

- **不能有循环依赖**:Proto 或模块之间都不能有循环依赖
- **不能有同名对象**:一个模块不能有相同名称和初始化类型的 Proto
- **按需注入**:不要直接注入 `app` 或 `ctx`,按需注入特定对象

## 快速决策指南
### 快速决策指南

| 场景 | 使用方式 |
| -------------------------------- | ------------------------------------------------------ |
| 无状态服务 | `@SingletonProto()` |
| 跨服务共享的请求级状态 | `@ContextProto()` |
| 需要跨模块访问 | `@SingletonProto({ accessLevel: AccessLevel.PUBLIC })` |
| 注入依赖 | `@Inject()` |
| 使用自定义名称注入 | `@Inject({ name: 'customName' })` |
| 同一抽象多种实现,运行时动态选择 | `QualifierImplDecoratorUtil` + `EggObjectFactory` |

| 场景 | 使用装饰器 |
| -------------------------------- | ------------------------------------------------------------------ |
| 无状态服务 | `@SingletonProto()` |
| 跨服务共享的请求级状态 | `@ContextProto()` |
| 需要跨模块访问 | `@SingletonProto({ accessLevel: AccessLevel.PUBLIC })` |
| 注入依赖 | `@Inject()` |
| 使用自定义名称注入 | `@Inject({ name: 'customName' })` |
| 同一抽象多种实现,运行时动态选择 | `QualifierImplDecoratorUtil` + `EggObjectFactory` |
| 请求返回后执行异步任务 | `BackgroundTaskHelper.run()`,详见 `references/background-task.md` |
## 异步任务

### 异步任务选型
| 特性 | BackgroundTaskHelper | EventBus |
| ---------- | ----------------------------- | ----------------------------------------- |
| **耦合** | 高 — 异步逻辑写在触发者代码中 | 低 — handler 独立,新增处理者不修改触发者 |
| **上下文** | 共享触发者的请求上下文 | handler 运行在独立的新上下文中 |
| **扩展** | 需要修改触发者代码 | 新增 `@Event` handler 类即可 |

```
需要在请求之外执行任务?
├─ 请求返回后执行,依赖当前请求上下文
│ └─ → BackgroundTaskHelper(references/background-task.md)
├─ 请求返回后执行,不依赖当前请求上下文
│ └─ → EventBus
├─ 请求返回后执行,不依赖当前请求上下文,需要解耦
│ └─ → EventBus(references/eventbus.md)
└─ 定时或周期执行
└─ → Schedule(参考 egg-controller skill)
```

## AOP 切面编程

AOP 用于将日志、鉴权、缓存、事务等横切关注点从业务代码中分离。AOP 装饰器从 `egg/aop` 导入(不是 `egg`)。

```
需要在方法执行前后添加通用逻辑?
├─ 针对特定方法 → @Pointcut(在目标方法上声明)
└─ 批量切入多个类/方法 → @Crosscut(在 Advice 类上声明匹配规则)
```

详细用法(Advice 生命周期、AdviceContext、Pointcut/Crosscut 选型、参数透传、执行顺序)请参阅 `references/aop.md`。

## 常见问题排查

| 现象 | 原因 | 解决方案 |
Expand All @@ -221,3 +242,5 @@ export class HelloService {
- SingletonProto 和 ContextProto 详情,请参阅:`references/proto.md`
- 动态注入(Qualifier 动态注入),请参阅:`references/dynamic-inject.md`
- 请求后异步任务(BackgroundTaskHelper),请参阅:`references/background-task.md`
- 事件总线(EventBus),请参阅:`references/eventbus.md`
- AOP 切面编程(Advice、Pointcut、Crosscut),请参阅:`references/aop.md`
Loading
Loading