@wwkit/harness 1.0.27 → 1.0.29

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.
Files changed (38) hide show
  1. package/bin/index.js +10 -0
  2. package/package.json +3 -2
  3. package/skills/extract/SKILL.md +43 -68
  4. package/skills/extract/references/detail.md +1 -1
  5. package/skills/extract/references/list.md +3 -3
  6. package/skills/extract/references/navi.md +1 -1
  7. package/skills/jstest/SKILL.md +561 -0
  8. package/skills/jstest/references/case-create.md +327 -0
  9. package/skills/jstest/references/case-fix.md +273 -0
  10. package/skills/jstest/references/config.md +148 -0
  11. package/skills/jstest/references/coverage-analyze.md +247 -0
  12. package/skills/jstest/references/env-ensure.md +210 -0
  13. package/skills/jstest/references/execute.md +168 -0
  14. package/skills/jstest/references/sample.md +166 -0
  15. package/skills/jstest/references/scoring-rules.md +75 -0
  16. package/skills/jstest/references/src/jstest-sample/Calculator.js +80 -0
  17. package/skills/jstest/references/src/jstest-sample/ConfigManager.js +72 -0
  18. package/skills/jstest/references/src/jstest-sample/FileProcessor.js +57 -0
  19. package/skills/jstest/references/src/jstest-sample/OrderService.js +98 -0
  20. package/skills/jstest/references/src/jstest-sample/TokenGenerator.js +60 -0
  21. package/skills/jstest/references/src/jstest-sample/UserService.js +56 -0
  22. package/skills/jstest/references/src/jstest-sample/index.js +6 -0
  23. package/skills/jstest/references/suitability-check.md +232 -0
  24. package/skills/jstest/references/test-standards.md +288 -0
  25. package/skills/pytest/SKILL.md +38 -30
  26. package/skills/query/SKILL.md +16 -47
  27. package/skills/revise/SKILL.md +52 -96
  28. package/skills/revise/references/article.md +12 -15
  29. package/skills/revise/references/gallery.md +11 -15
  30. package/skills/revise/references/question.md +11 -15
  31. package/skills/revise/references/status.md +10 -14
  32. package/src/config.js +29 -0
  33. package/src/config.json5 +19 -0
  34. package/skills/extract/references/format-aliases.json5 +0 -22
  35. package/skills/extract/references/input.schema.json5 +0 -23
  36. package/skills/query/references/input.schema.json5 +0 -25
  37. package/skills/revise/references/format-aliases.json5 +0 -22
  38. package/skills/revise/references/input.schema.json5 +0 -28
@@ -0,0 +1,288 @@
1
+ # 测试用例创建规范
2
+
3
+ > 本规范适用于 JS/TS Jest 测试框架,包含通用规范、JS/jest 特定规范、以及单元/集成测试专属规范。
4
+
5
+ ## 一、通用规范
6
+
7
+ ### AAA 模式(Arrange-Act-Assert)
8
+
9
+ 每个测试用例分为三段:
10
+
11
+ ```javascript
12
+ describe('MyService', () => {
13
+ test('should create with valid data', () => {
14
+ // Arrange — 准备
15
+ const service = new MyService();
16
+ const data = { name: 'test', age: 18 };
17
+
18
+ // Act — 执行
19
+ const result = service.create(data);
20
+
21
+ // Assert — 断言
22
+ expect(result.id).toBeDefined();
23
+ expect(result.name).toBe('test');
24
+ });
25
+ });
26
+ ```
27
+
28
+ ### FIRST 原则
29
+
30
+ | 原则 | 说明 |
31
+ |------|------|
32
+ | Fast | 快速执行(单元测试秒级,集成测试分钟级) |
33
+ | Isolated | 测试间相互独立,不依赖执行顺序 |
34
+ | Repeatable | 可重复运行,结果稳定 |
35
+ | Self-Validating | 自动断言,无需人工判断 |
36
+ | Timely | 与开发同步编写 |
37
+
38
+ ### 命名规范
39
+
40
+ | 元素 | 规则 | 示例 |
41
+ |------|------|------|
42
+ | 文件名 | `{ModuleName}.test.js` | `MyService.test.js` |
43
+ | describe 名 | `'ModuleName'` | `describe('MyService', ...)` |
44
+ | test/it 名 | `'should {action} {expected}'` | `test('should create with valid data', ...)` |
45
+
46
+ 用例命名要素:
47
+ - **action**:被测方法名或核心行为(create, send, parse)
48
+ - **expected**:输入条件或预期结果(with valid data, throw on timeout)
49
+
50
+ ### 一个用例一个行为
51
+
52
+ 每个 test/it 只验证一个行为,不混合多个断言逻辑。
53
+
54
+ ## 二、JS/jest 特定规范
55
+
56
+ ### describe/test/it 结构
57
+
58
+ 遵循 AGENTS.md 规则:
59
+ - 2 空格缩进
60
+ - describe/test/it 函数式(非类风格)
61
+ - 一个文件内只定义一个顶层 describe
62
+ - ESM 项目使用 `import`/`export`
63
+
64
+ ```javascript
65
+ import { MyService } from '../../../src/mypackage/MyService.js';
66
+
67
+ describe('MyService', () => {
68
+
69
+ test('should create with valid data', () => {
70
+ // Arrange
71
+ const service = new MyService();
72
+ // Act
73
+ const result = service.create({ name: 'test' });
74
+ // Assert
75
+ expect(result.id).toBeDefined();
76
+ });
77
+ });
78
+ ```
79
+
80
+ ### setup/teardown 使用
81
+
82
+ ```javascript
83
+ describe('MyService', () => {
84
+
85
+ beforeEach(() => {
86
+ // 每个测试前初始化
87
+ jest.clearAllMocks();
88
+ });
89
+
90
+ afterEach(() => {
91
+ // 每个测试后清理
92
+ process.env.NODE_ENV = 'test';
93
+ });
94
+
95
+ beforeAll(() => {
96
+ // 所有测试前执行一次
97
+ });
98
+
99
+ afterAll(() => {
100
+ // 所有测试后执行一次
101
+ });
102
+
103
+ test('should create with valid data', () => {
104
+ const service = new MyService();
105
+ const result = service.create({ name: 'test' });
106
+ expect(result.id).toBeDefined();
107
+ });
108
+ });
109
+ ```
110
+
111
+ ### Mock/Stub 使用
112
+
113
+ ```javascript
114
+ import { MyService } from '../../../src/mypackage/MyService.js';
115
+
116
+ jest.mock('../../../src/mypackage/MyService.js');
117
+
118
+ describe('MyService', () => {
119
+
120
+ test('should process returns data from remote', () => {
121
+ // Stub — 预设返回值
122
+ const mockFetchRemote = jest.fn().mockResolvedValue({ key: 'value' });
123
+ const service = new MyService({ fetchRemote: mockFetchRemote });
124
+
125
+ // Act
126
+ return service.process().then(result => {
127
+ // Mock — 验证调用行为
128
+ expect(mockFetchRemote).toHaveBeenCalledTimes(1);
129
+ expect(result.key).toBe('value');
130
+ });
131
+ });
132
+ });
133
+ ```
134
+
135
+ ### 参数化测试
136
+
137
+ ```javascript
138
+ describe('MyValidator', () => {
139
+
140
+ test.each([
141
+ [18, true],
142
+ [30, true],
143
+ [60, true],
144
+ [17, false],
145
+ [61, false],
146
+ [-1, false],
147
+ ])('should validate age %i → %s', (age, expected) => {
148
+ expect(MyValidator.validateAge(age)).toBe(expected);
149
+ });
150
+ });
151
+ ```
152
+
153
+ ### 异常断言
154
+
155
+ ```javascript
156
+ describe('MyService', () => {
157
+
158
+ test('should throw on empty name', () => {
159
+ const service = new MyService();
160
+ expect(() => service.create({ name: '' })).toThrow('name不能为空');
161
+ });
162
+
163
+ test('should throw specific error type', () => {
164
+ const service = new MyService();
165
+ expect(() => service.create({ name: '' })).toThrow(TypeError);
166
+ });
167
+ });
168
+ ```
169
+
170
+ ### jest test category
171
+
172
+ ```javascript
173
+ // unit 测试 — 在 package.json jest 配置或 testNamePattern 中区分
174
+ describe('MyService', () => {
175
+ // 单元测试
176
+ });
177
+
178
+ // integration 测试 — 按目录组织(tests/integration/)
179
+ describe('LoginFlow', () => {
180
+ // 集成测试
181
+ });
182
+ ```
183
+
184
+ ## 三、单元测试专属规范(unit)
185
+
186
+ ### Mock 策略:full — 全部 Mock 外部依赖
187
+
188
+ | 依赖类型 | 处理策略 | 示例 |
189
+ |---------|---------|------|
190
+ | HTTP 请求 | Mock:mock 请求方法,预设返回值 | `jest.mock('axios')` / mock fetch |
191
+ | 数据库操作 | Fake:内存数据库 或 mock 模块 | `jest.mock('db-module')` |
192
+ | 文件系统 | Fake:使用 `os.tmpdir()` 或 mock | `jest.mock('fs')` |
193
+ | 时间依赖 | Mock:fake timers | `jest.useFakeTimers()` |
194
+ | 随机值 | Mock:spyOn random | `jest.spyOn(Math, 'random').mockReturnValue(0.5)` |
195
+ | 外部服务 | Mock:mock 发送方法 | `jest.mock('email-module')` |
196
+ | 环境变量 | Stub:直接设置 process.env | `process.env.KEY = 'val'` |
197
+
198
+ ### 用例覆盖要求
199
+
200
+ | 源码特征 | 必须创建的用例 |
201
+ |---------|---------------|
202
+ | 每个公开函数 | 至少 1 个正向用例 |
203
+ | 含 if/else 分支 | 边界值用例(每个分支至少 1 个) |
204
+ | 含 throw/try-catch | 异常路径用例(expect().toThrow()) |
205
+ | 多输入场景 | 参数化用例(test.each / it.each) |
206
+ | 有返回值 | 断言返回值类型和内容 |
207
+
208
+ ### 禁止事项
209
+
210
+ - 禁止真实网络调用
211
+ - 禁止操作真实文件系统
212
+ - 禁止依赖真实时间
213
+ - 禁止依赖随机值
214
+ - 禁止测试间依赖(共享状态)
215
+ - 禁止硬编码路径
216
+
217
+ ## 四、集成测试专属规范(integration)
218
+
219
+ ### Mock 策略:minimal — 最少 Mock,优先真实调用
220
+
221
+ | 依赖类型 | 处理策略 |
222
+ |---------|---------|
223
+ | 内部模块 | 真实调用,不 Mock |
224
+ | 数据库 | 真实连接(测试库)或 Fake 内存数据库 |
225
+ | 文件系统 | 真实文件操作(使用 `os.tmpdir()` 清理) |
226
+ | 外部 API | 仅 Mock 不可控的生产 API,测试环境 API 真实调用 |
227
+ | 时间/随机 | 可接受真实值,或 `jest.spyOn` 固定 |
228
+
229
+ ### 用例组织
230
+
231
+ - 按 **业务场景** 组织用例,不按函数
232
+ - 每个场景覆盖完整流程:输入 → 处理 → 输出
233
+ - 验证端到端数据流完整性
234
+
235
+ ```javascript
236
+ import { OrderService } from '../../../src/mypackage/OrderService.js';
237
+
238
+ describe('OrderFlow', () => {
239
+
240
+ let db;
241
+ let service;
242
+
243
+ beforeAll(() => {
244
+ // 场景级 setup
245
+ db = Database(testUrl);
246
+ service = new OrderService({ db });
247
+ });
248
+
249
+ afterAll(() => {
250
+ // 场景级 teardown
251
+ db.close();
252
+ });
253
+
254
+ test('should create order and send notification', async () => {
255
+ // 场景:创建订单并发送通知
256
+ // Arrange — 数据已在 beforeAll 准备
257
+
258
+ // Act
259
+ const order = await service.createOrder({ userId: 1, item: 'book' });
260
+ const notification = await service.sendNotification(order.id);
261
+
262
+ // Assert — 验证完整数据流
263
+ expect(order.id).toBeDefined();
264
+ expect(order.status).toBe('created');
265
+ expect(notification.orderId).toBe(order.id);
266
+ expect(notification.sent).toBe(true);
267
+ });
268
+ });
269
+ ```
270
+
271
+ ### setup/teardown 使用
272
+
273
+ - 使用 `beforeAll`/`afterAll` 的场景级 setup/teardown
274
+ - teardown 负责清理测试数据
275
+ - 数据准备放在 setup 中,不硬编码在测试用例内
276
+
277
+ ## 五、稳定性保障规则
278
+
279
+ | 规则 | 说明 |
280
+ |------|------|
281
+ | 禁止真实网络 | 单元测试所有 HTTP 必须 Mock |
282
+ | 禁止真实文件 | 文件操作使用 `os.tmpdir()` 或 `jest.mock('fs')` |
283
+ | 禁止真实时间 | 时间依赖必须 `jest.useFakeTimers()` |
284
+ | 禁止真实随机 | 随机值必须 `jest.spyOn` 或固定 |
285
+ | 禁止真实外部服务 | 邮件/消息队列等必须 Mock(单元测试) |
286
+ | 禁止测试间依赖 | 每个测试独立,不依赖执行顺序 |
287
+ | 禁止硬编码路径 | 使用 `os.tmpdir()` 或相对路径 |
288
+ | Mock 清理 | `afterEach` 中 `jest.clearAllMocks()` 或 `jest.restoreAllMocks()` |
@@ -11,23 +11,26 @@ metadata:
11
11
  workflow: sequential
12
12
  ---
13
13
 
14
- # pytest 技能
14
+ # pytest 技能(固定 Sprint 冲刺)
15
15
 
16
- ## 核心约束(最高优先级)
16
+ ## 执行范式
17
17
 
18
- - **MUST**:收到任务消息后,先 todowrite 落单 7 步,再逐步执行。
19
- - **MUST**:每步完成立即 todowrite 勾单。
20
- - **MUST**:test_type 只能是 unit、integration 或 sample,其他值报错退出。
21
- - **禁止**:混合测试类型(unit 不混合 integration,反之亦然)。
22
- - **禁止**:修改 conftest.py(除非直接导致失败)。
23
- - **MUST**:子工作流通过 `read` 加载 `references/xxx.md` 并按其指令执行,**不再调用独立 skill**(原 pytest-* 子 skill 已合并入 references/)。
18
+ 每次调用 = 一个固定 Sprint,三个事件:
19
+
20
+ 1. **Sprint Planning**:解析入参 → 定义 Sprint Goal → todowrite 落固定 7 项 Sprint Backlog(每项带 DoD)
21
+ 2. **Sprint Execution**:7 步 + 双层 loop 逐项执行,每项 = 执行 → 验证 DoD → todowrite 勾单 Done
22
+ 3. **Sprint Review**:对照 Sprint Goal 验证 Increment(测试报告)及输出语义,沉淀 1 条回顾
24
23
 
25
- ## 第一步硬指令(自检)
24
+ **Sprint Goal** = `对 {{source}} 执行 {{test_type}} 测试,产出测试质量报告(unit 达标 score≥90,integration 达标 score≥70)`。
26
25
 
27
- 解析入参前,强制自检:
28
- > 我是否已用 todowrite 落单 7 步?
29
- > - 未落单 → 立即 todowrite 创建清单。
30
- > - 已落单 → 继续。
26
+ **铁律(最高优先级):**
27
+
28
+ - **没有 Sprint Backlog 不能开始执行**:收到任务消息后,先做 Sprint Planning(解析入参)再 todowrite 落固定 7 项 Sprint Backlog,然后才进入 Sprint Execution。
29
+ - **每项执行周期** = 进度检查(Daily Scrum 映射)→ 执行 → 验证 DoD → 勾单 Done。
30
+ - **子工作流通过 `read` 加载 `references/xxx.md` 并按其指令执行**,**不再调用独立 skill**(原 pytest-* 子 skill 已合并入 references/)。
31
+ - **禁止**:混合测试类型(unit 不混合 integration,反之亦然)。
32
+ - **禁止**:修改 conftest.py(除非直接导致失败)。
33
+ - **禁止**:使用 WebFetch 或任何网络请求。
31
34
 
32
35
  ## 配置表(按 test_type 分支)
33
36
 
@@ -57,14 +60,7 @@ metadata:
57
60
 
58
61
  ## 输入参数(自包含)
59
62
 
60
- 入参为调用方传入的**原始任务消息**,可能是以下任一形态:
61
-
62
- - **JSON 对象**:`{test_type, source, test_dir}`,直接取字段值。
63
- - **key=value**:`test_type=unit, source=src/mymodule`,按 `,` 和 `=` 拆分为字段。
64
- - **纯文本 prose**:含 "集成/integration" → integration;含 "单元/unit" → unit;默认 unit。`source` 从文本中出现的路径推断。
65
- - **命令风格**:`unit src/mymodule` 或 `integration src/mymodule tests/integration/mymodule`,第一段为 test_type,第二段为 source,第三段(可选)为 test_dir。
66
-
67
- 字段清单:
63
+ 入参为调用方传入的**原始任务消息**,可为 JSON 对象、key=value、自然语言或命令风格等任意形态,agent 依据字段语义自主提取(详见 Step 1)。字段清单:
68
64
 
69
65
  | 字段 | 类型 | 必填 | 说明 |
70
66
  |------|------|------|------|
@@ -72,6 +68,8 @@ metadata:
72
68
  | source | string | 是 | 源码包目录或 .py 文件路径 |
73
69
  | test_dir | string | 否 | 测试目录;未指定时按 `tests/{test_type}/{归一化路径}/` 自动推导 |
74
70
 
71
+ **提取原则**:从消息中自主识别三个字段——命令风格(`unit src/mymodule` 或 `integration src/mymodule tests/integration/mymodule`,第一段为 test_type,第二段为 source,第三段可选为 test_dir)、JSON 对象(`{test_type, source, test_dir}`)、key=value(`test_type=..., source=...`)、或自然语言(含 "集成/integration" → integration;含 "单元/unit" → unit;默认 unit;`source` 从出现的路径推断)。
72
+
75
73
  **必填校验**:若无法解析出 `test_type` 或 `source`,将错误信息输出到 stderr 并结束,**禁止**继续执行。
76
74
 
77
75
  **test_type 校验**:解析后若 `test_type` 不在 `{unit, integration, sample}` 中,输出 "test_type 只能是 unit、integration 或 sample,得到: {value}" 并结束。
@@ -84,17 +82,19 @@ metadata:
84
82
 
85
83
  ## 工作流程
86
84
 
87
- ### 阶段 0:todowrite 落单
85
+ ### 阶段 0:todowrite 落单(Sprint Backlog)
88
86
 
89
- 收到任务消息后,先用 `todowrite` 创建 7 步清单(status=pending):
87
+ 收到任务消息后,先用 `todowrite` 创建固定 7 项 Sprint Backlog(status=pending),每项带 DoD:
90
88
 
91
- 1. 入参校验与目录映射(test_type + source + test_dir)
92
- 2. 模块适用性评估
93
- 3. 环境检查(+ integration 补充检查)
94
- 4. 覆盖率分析(外层 loop)
95
- 5. 用例创建
96
- 6. 测试执行
97
- 7. 用例修复(内层 loop)
89
+ | # | 任务 | 对应 Step | DoD |
90
+ |---|------|----------|-----|
91
+ | 1 | 入参校验与目录映射 | Step 1 | test_type/source/test_dir 已校验,target/test_dir/report_dir/flow_start_time 已确定,7 项清单已建 |
92
+ | 2 | 模块适用性评估 | Step 2 | 得到 testable_classes(或为空已按原因退出) |
93
+ | 3 | 环境检查 | Step 3 | 得到 config(或 env-ensure 失败已退出);integration 补充检查已记录警告 |
94
+ | 4 | 覆盖率分析(外层 loop) | Step 4 | 得到 score/uncovered_areas,按退出条件结束或进入下一轮 |
95
+ | 5 | 用例创建 | Step 5 | 得到 new_cases_count(=0 已跳过 execute+fix 直接轮尾评分) |
96
+ | 6 | 测试执行 | Step 6 | 得到通过/失败结果(有失败已进入 Step 7) |
97
+ | 7 | 用例修复(内层 loop) | Step 7 | 得到修复结果,按内层退出条件回到 Step 6 或 Step 4 轮尾评分 |
98
98
 
99
99
  每步完成立即 todowrite 勾单(status=completed)。
100
100
 
@@ -502,6 +502,14 @@ integration:
502
502
  - 内容:上述完整报告(含源码 Bug 汇总)
503
503
  - 同时在 chat 中输出报告摘要
504
504
 
505
+ ## Sprint Review
506
+
507
+ 所有 Backlog Items 完成后:
508
+
509
+ - **对照 Sprint Goal 验证**:是否对 `{{source}}` 完成 `{{test_type}}` 测试并产出测试质量报告?得分是否达标(unit≥90,integration≥70)?报告是否写入 `report_dir/test_report.md`?
510
+ - **展示 Increment**:测试报告路径 + chat 摘要。
511
+ - **简要回顾(Retrospective)**:沉淀 1 条改进项供下一轮采纳。
512
+
505
513
  ## 规则
506
514
 
507
515
  **共同规则**:
@@ -1,10 +1,8 @@
1
1
  ---
2
2
  name: query
3
3
  description: |
4
- 自包含内容生成 skill:每次调用 = 一个固定 Sprint——Sprint Planning(解析入参、定义 Sprint Goal、todowrite 落固定 Sprint Backlog)→ Sprint Execution(逐项执行并验证 DoD)→ Sprint Review(对照 Sprint Goal 校验交付 + 简要回顾)。
5
- prompt 为任务要求(含输出格式说明),source 为可选素材,language 控制输出语言(默认中文)。
6
- 调用方直接传原始任务消息,skill 自解析自包含。内部用 todowrite 管理固定 3 项 Sprint Backlog(每项带 DoD)。禁止 WebFetch/网络请求。
7
- 适用:通用内容生成(摘要/改写/翻译/结构化提取等任意 prompt 驱动任务)。
4
+ 自包含内容生成 skill(固定 Sprint 范式):每次调用 = 一个固定 Sprint(Planning→Execution→Review),todowrite 落 3 项带 DoD 的 Sprint Backlog 并逐项验证,按输出语义交付生成内容。
5
+ prompt 为任务要求(含输出格式说明),source 为可选素材,language 控制输出语言(默认中文)。调用方直接传原始任务消息即可,无需预处理;禁止 WebFetch/网络请求。
8
6
  license: MIT
9
7
  metadata:
10
8
  workflow: sequential
@@ -18,13 +16,13 @@ metadata:
18
16
 
19
17
  1. **Sprint Planning**:解析入参 → 定义 Sprint Goal → todowrite 落固定 3 项 Sprint Backlog(每项带 DoD)
20
18
  2. **Sprint Execution**:逐项执行,每项 = 执行 → 验证 DoD → todowrite 勾单 Done
21
- 3. **Sprint Review**:对照 Sprint Goal 验证 Increment(生成内容)及输出语义,沉淀 1 条回顾
19
+ 3. **Sprint Review**:对照 Sprint Goal 验证 Increment(生成内容)及输出语义
22
20
 
23
21
  **Sprint Goal** = `按 {{prompt}} 生成内容(语言 {{language}}),并按输出语义交付`。
24
22
 
25
23
  ## 输入参数
26
24
 
27
- 入参为调用方传入的**原始任务消息**,可为 JSON 对象、key=value 或自然语言等任意形态,agent 依据字段语义自主提取(详见 Item 1)。字段清单(字段/类型/必填/默认值)以 `references/input.schema.json5` 为准:
25
+ 入参为调用方传入的**原始任务消息**,可为 JSON 对象、key=value 或自然语言等任意形态,agent 依据字段语义自主提取。字段清单(字段/类型/必填/默认值):
28
26
 
29
27
  | 字段 | 类型 | 必填 | 说明 |
30
28
  |---|---|---|---|
@@ -33,71 +31,42 @@ metadata:
33
31
  | `language` | string | ❌ | 输出内容语言,默认 中文 |
34
32
  | `output` | string | ❌ | 输出文件路径(提供则写文件,否则 stdout) |
35
33
 
36
- 本技能仅使用上表四个字段,忽略所有其他字段(如 `url`),不得读取、写入或据此推断任何行为。
34
+ 本技能仅使用上表四个字段,忽略所有其他字段(如 `url`)。
37
35
 
38
36
  ## 固定 Sprint Backlog(todowrite 落单,覆盖历史 todos)
39
37
 
40
- 1. 解析入参(从任意形态任务消息自主提取 prompt/source/language/output) | DoD: 得到四个字段值(或 prompt 缺失时 stderr 报错结束)
41
- 2. 内容生成(LLM 创作) | DoD: 按 prompt 生成内容,语言 language(默认中文),source 已按需解析为素材
42
- 3. 输出(写 output 文件或 stdout) | DoD: 按输出语义交付(文件路径或 stdout),结果为空/失败时 stderr 报错
38
+ 1. 解析入参 | DoD: 四字段已提取(或 prompt 缺失时 stderr 报错结束)
39
+ 2. 内容生成 | DoD: 按 prompt 生成内容,语言 language(默认中文),source 已按需读取为素材
40
+ 3. 输出 | DoD: 按输出语义交付(文件路径或 stdout)
43
41
 
44
42
  ## Sprint Execution
45
43
 
46
- 按固定 3 项逐项执行,每项周期 = 进度检查(刚完成什么/本项做什么/有无阻塞)→ 执行 → 验证 DoD → 勾单 Done。
44
+ 按固定 3 项逐项执行(勾单机制见执行范式)。
47
45
 
48
46
  ### Item 1:解析入参
49
47
 
50
- 将第 1 项标记 in_progress,从原始任务消息中**自主提取**四个字段。入参可为 JSON 对象、key=value 或自然语言等任意形态,依据字段语义理解提取即可,无需固定解析规则。提取原则:
51
-
52
- - **自然语言推断**:从文本中推断提取参数(如"输出到xxx"→`output`、"素材xxx"→`source`、"用英文"→`language`),剩余内容作为 `prompt`;若无法提取,整段文本作为 `prompt`。
53
-
54
- 解析后得到 `prompt`、`source`、`language`、`output` 四个字段(字段说明见上文输入参数表;`source`/`language`/`output` 缺省时留空由后续 Item 处理)。
55
-
56
- **必填校验**:若 `prompt` 为空、null 或仅含空白字符,将错误信息输出到 stderr 并结束,**禁止**继续执行。
57
-
58
- **验证 DoD**:四个字段值已得到(或 prompt 缺失已报错结束)。通过后标记 Done。
48
+ 从原始任务消息中自主提取 `prompt`/`source`/`language`/`output` 四个字段。`prompt` 为空、null 或仅含空白 → 将错误信息输出到 stderr 并结束,**禁止**继续执行。
59
49
 
60
50
  ### Item 2:内容生成
61
51
 
62
- 将第 2 项标记 in_progress,先判断 `source` 是否提供:
63
-
64
- - `source` 非空时,若值为现有文件路径则用 `read` 读取文件内容作为素材;否则直接以值作为素材。
65
- - `source` 为空时,仅依据 `prompt` 生成内容。
66
-
67
- 利用自身能力按 `prompt` 要求生成内容,输出语言使用 `language`(默认中文)。**禁止用 bash 解析 JSON**,直接依据内容理解处理。
68
-
69
- **验证 DoD**:已按 prompt 生成内容,语言 language(默认中文),source 已按需解析为素材。通过后标记 Done。
52
+ `source` 为文件路径时用 `read` 读取其内容作为素材。按 `prompt` 要求生成内容,输出语言使用 `language`(缺省按参数表默认值)。
70
53
 
71
54
  ### Item 3:输出
72
55
 
73
- 将第 3 项标记 in_progress:
74
-
75
- - 提供 `output` 参数:用 `write` 工具将生成内容写入 `output` 指定文件(**禁止创建其他文件**),stdout 输出该文件路径。
76
- - 未提供 `output` 参数:将生成内容直接输出到 stdout,**不写任何文件**。
77
-
78
- 若结果为空或生成失败,将错误信息输出到 stderr 并结束,**不写任何文件**。
56
+ - 提供 `output` → 用 `write` 将生成内容写入该文件(**禁止创建其他文件**),stdout 输出文件路径
57
+ - 未提供 `output` → 将生成内容直接输出到 stdout,**不写任何文件**
79
58
 
80
- **验证 DoD**:按输出语义交付(文件路径或 stdout 数组),或结果为空/失败时 stderr 已报错。通过后标记 Done。
59
+ 结果为空或生成失败 → stderr 报错并结束,**不写任何文件**。
81
60
 
82
61
  ## Sprint Review
83
62
 
84
- 所有 Backlog Items 完成后:
63
+ 本 skill 每次调用 = 无状态独立 Sprint,无跨轮次状态,故不进行 Retrospective。所有 Backlog Items 完成后:
85
64
 
86
65
  - **对照 Sprint Goal 验证**:生成内容是否符合 `{{prompt}}` 要求、语言 `{{language}}`?输出语义是否正确(写文件输出路径 / stdout 输出内容)?
87
66
  - **展示 Increment**:输出文件路径或 stdout 的生成内容。
88
- - **简要回顾(Retrospective)**:沉淀 1 条改进项供下一轮采纳。
89
67
 
90
68
  ## 约束
91
69
 
92
70
  - 只处理已声明字段(prompt/source/language/output),忽略所有其他传入参数(如 `url`),**禁止**以任何形式使用它们。
93
71
  - **禁止使用 WebFetch 或任何网络请求、禁止访问外部网络**;`source` 仅为素材透传,绝不自行获取内容。
94
- - 写文件一律用 `write` 工具;读文件用 `read` 工具;需要中间数据时写入临时文件,以 stdin 重定向传给 node。
95
- - 禁止使用未授权的 `cp`/`rm`/`mv` 等命令;需要复制、移动或删除临时文件时,一律用允许的 `node -e` 的 fs 模块完成。
96
- - 中间产物用临时文件,完成后清理,禁止写入 output 以外的任何持久文件。
97
-
98
- ## references/ 目录结构
99
-
100
- ```
101
- references/
102
- └── input.schema.json5 # 入参字段清单(纯文档)
103
- ```
72
+ - 写文件一律用 `write` 工具;读文件用 `read` 工具。