specline 1.3.0 → 1.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 +15 -7
- package/cli.mjs +21 -19
- package/package.json +1 -1
- package/templates/.cursor/skills/specline-pipeline/SKILL.md +58 -600
- package/templates/.cursor/skills/specline-pipeline/references/error-recovery-details.md +49 -0
- package/templates/.cursor/skills/specline-pipeline/references/event-log-spec.md +59 -0
- package/templates/.cursor/skills/specline-pipeline/references/pipeline-state-schema.md +87 -0
- package/templates/.cursor/skills/specline-pipeline/templates/subagent-prompts.md +221 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Hook 约束与速查表参考
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
本文档提供 Specline Pipeline 的 Hook 约束体系说明和关键约束速查表,供编排者在遇到 Hook 阻断、阶段不匹配等场景时查阅。内容对应原 SKILL.md 的附录 D(Hook 约束体系)和附录 E(关键约束速查表)。
|
|
6
|
+
|
|
7
|
+
## Hook 约束体系
|
|
8
|
+
|
|
9
|
+
Specline 通过 Cursor Hooks 提供了三层自动约束,确保在长对话中 Agent 不偏离流水线逻辑:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
sessionStart → specline-session-start.sh
|
|
13
|
+
新会话启动时检测活跃 pipeline,自动注入阶段上下文到 Agent 系统提示
|
|
14
|
+
|
|
15
|
+
preToolUse → specline-phase-guard.sh
|
|
16
|
+
操作前检查:SPEC 阶段拦截代码编辑、阶段不匹配的子Agent 启动
|
|
17
|
+
|
|
18
|
+
postToolUse → specline-reminder.sh
|
|
19
|
+
关键操作后注入提醒:更新 tasks.md checkbox、运行 Gate 脚本
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 对编排者的影响
|
|
23
|
+
|
|
24
|
+
1. **总是先检查** - preToolUse 会阻止不匹配当前阶段的操作,所以你在行动前自然会考虑阶段
|
|
25
|
+
2. **被提醒下一步** - postToolUse 在子Agent完成后提醒你更新 checkbox 和运行 Gate
|
|
26
|
+
3. **非流水线会话无影响** - 所有 Hook 的第一步检查「是否有活跃 pipeline」,无则透明放行
|
|
27
|
+
|
|
28
|
+
### 约束策略表
|
|
29
|
+
|
|
30
|
+
| 场景 | 策略 | 原因 |
|
|
31
|
+
|------|------|------|
|
|
32
|
+
| SPEC 阶段编辑代码文件 | **硬拦截 (deny)** | 明确违规 |
|
|
33
|
+
| SPEC 阶段启动编码 Agent | **硬拦截 (deny)** | 阶段不匹配 |
|
|
34
|
+
| CODING 阶段直接编辑代码 | **软提醒 (postToolUse)** | Hook 无法区分编排者和子Agent的 Write |
|
|
35
|
+
| 子Agent完成后忘记 Gate | **软提醒 (postToolUse)** | 操作后注入下一步提醒 |
|
|
36
|
+
|
|
37
|
+
> 注意:CODING 阶段 Orchestrator 直接编辑代码文件不会被 Hook 硬拦截(因为子Agent 也需要 Write 权限),但 SKILL 指令和 sessionStart 注入的上下文会持续提醒你「编码应通过子 Agent」。如果你发现自己想直接编辑代码,停一下,改用 Task 工具。
|
|
38
|
+
|
|
39
|
+
## 关键约束速查表
|
|
40
|
+
|
|
41
|
+
| # | 约束 | 说明 |
|
|
42
|
+
|---|------|------|
|
|
43
|
+
| 1 | **不做判断,只做编排** | 不评估代码质量、需求好坏、测试覆盖——这些由子 Agent 和 Gate 脚本负责 |
|
|
44
|
+
| 2 | **所有门禁通过 Gate 脚本** | 调用 `specline-pipeline-gate.sh`,不要自己写 grep/检查逻辑 |
|
|
45
|
+
| 3 | **状态文件是唯一真相源** | 所有决策基于 `.pipeline-state.json` 的当前值 |
|
|
46
|
+
| 4 | **人工确认点必须尊重策略** | 根据 `pipeline.human_gate_policy` 配置决定是否暂停,不要无条件跳过或强制暂停 human_gate |
|
|
47
|
+
| 5 | **测试 Agent 必须黑盒** | 不给 specline-test-writer 传递源代码文件路径 |
|
|
48
|
+
| 6 | **Hook 阻断绝不静默降级** | 子 Agent 被 hook 阻止时,必须先诊断、沟通、修复后重试 |
|
|
49
|
+
| 7 | **接受 Hook 约束** | preToolUse/postToolUse/sessionStart Hook 会自动校验和提醒,不要试图绕过 |
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# 事件日志与状态写入规范
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
定义 Pipeline 编排者写入状态和事件日志的规范——谁在何时写入什么内容。这是编排者在 SPE 编码阶段(Step 7)和异常恢复阶段(Layer 3)写入 `.pipeline-state.json` 和 `pipeline-events.jsonl` 时必须遵循的规则。
|
|
6
|
+
|
|
7
|
+
## 状态写入规则
|
|
8
|
+
|
|
9
|
+
> 所有状态写入由 Gate 脚本或 Skill 编排逻辑完成,**不使用 LLM 写入状态**。
|
|
10
|
+
|
|
11
|
+
| 写入时机 | 写入方 | 写入内容 |
|
|
12
|
+
|---------|--------|---------|
|
|
13
|
+
| Gate 通过 | Gate 脚本 | `gate.passed = true` |
|
|
14
|
+
| 子 Agent 完成 | Skill 编排逻辑 | `completed_at`(时间戳) |
|
|
15
|
+
| 代码修复后 | Skill 编排逻辑 | 重置相关 gates 为 `null` |
|
|
16
|
+
|
|
17
|
+
## 结构化事件日志
|
|
18
|
+
|
|
19
|
+
每个关键事件追加写入 `specline/changes/<name>/pipeline-events.jsonl`(JSON Lines 格式,每行一个事件)。
|
|
20
|
+
|
|
21
|
+
### 事件格式
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{"ts":"...","event":"pipeline_start","change":"<name>"}
|
|
25
|
+
{"ts":"...","event":"phase_transition","from":"spec","to":"coding"}
|
|
26
|
+
{"ts":"...","event":"agent_start","agent":"specline-spec-creator","task":null}
|
|
27
|
+
{"ts":"...","event":"agent_done","agent":"specline-spec-creator","result":"completed"}
|
|
28
|
+
{"ts":"...","event":"agent_start","agent":"specline-frontend-dev","task":"1","type":"frontend"}
|
|
29
|
+
{"ts":"...","event":"agent_done","agent":"specline-frontend-dev","task":"1","result":"completed","files_changed":["..."],"duration_ms":45200}
|
|
30
|
+
{"ts":"...","event":"gate_run","phase":"build","exit_code":0,"passed":true}
|
|
31
|
+
{"ts":"...","event":"gate_run","phase":"lint","exit_code":1,"passed":false,"stderr":"..."}
|
|
32
|
+
{"ts":"...","event":"conflict_detected","tasks":["1","2"],"overlap_files":["src/utils/api.ts"]}
|
|
33
|
+
{"ts":"...","event":"retry","phase":"coding","task":"3","attempt":2,"reason":"build_failure"}
|
|
34
|
+
{"ts":"...","event":"pipeline_pause","reason":"human_gate_1"}
|
|
35
|
+
{"ts":"...","event":"pipeline_resume","from_phase":"coding"}
|
|
36
|
+
{"ts":"...","event":"pipeline_complete","change":"<name>"}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 事件类型列表
|
|
40
|
+
|
|
41
|
+
| 事件类型 | 触发时机 |
|
|
42
|
+
|---------|---------|
|
|
43
|
+
| `pipeline_start` | 流水线开始 |
|
|
44
|
+
| `phase_transition` | 阶段切换(spec→coding→review→test→archive) |
|
|
45
|
+
| `agent_start` | 子 Agent 启动 |
|
|
46
|
+
| `agent_done` | 子 Agent 完成 |
|
|
47
|
+
| `gate_run` | Gate 脚本执行完毕 |
|
|
48
|
+
| `conflict_detected` | 检测到文件冲突 |
|
|
49
|
+
| `retry` | 任务重试 |
|
|
50
|
+
| `pipeline_pause` | 流水线暂停(人工检查点) |
|
|
51
|
+
| `pipeline_resume` | 流水线恢复 |
|
|
52
|
+
| `pipeline_complete` | 流水线完成 |
|
|
53
|
+
|
|
54
|
+
### 写入原则
|
|
55
|
+
|
|
56
|
+
- 每个事件一行,JSON 对象结尾无逗号
|
|
57
|
+
- 任何编排动作(启动 agent、运行 gate、状态转换)都写入事件日志
|
|
58
|
+
- Gate 脚本不写事件日志(Gate 是无状态的),仅编排层写入
|
|
59
|
+
- 事件日志用于人工排查问题和统计分析,不影响流水线决策
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Pipeline 状态文件 Schema 参考
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
本文档定义 `.pipeline-state.json` 的完整 JSON Schema 和关键字段说明。编排者在初始化流水线或需要理解状态文件结构时查阅。
|
|
6
|
+
|
|
7
|
+
## 完整 JSON Schema
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"version": 1,
|
|
12
|
+
"change_name": "<name>",
|
|
13
|
+
"created_at": "<ISO8601>",
|
|
14
|
+
"updated_at": "<ISO8601>",
|
|
15
|
+
"current_phase": "spec",
|
|
16
|
+
"current_step": "specline-spec-creator",
|
|
17
|
+
"phases": {
|
|
18
|
+
"spec": {
|
|
19
|
+
"status": "in_progress",
|
|
20
|
+
"retry_count": 0,
|
|
21
|
+
"sub_phases": {},
|
|
22
|
+
"gates": {
|
|
23
|
+
"spec_gate": { "passed": null },
|
|
24
|
+
"human_gate_1": { "passed": null }
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"coding": {
|
|
28
|
+
"status": "pending",
|
|
29
|
+
"tasks": [],
|
|
30
|
+
"sub_phases": {},
|
|
31
|
+
"gates": {
|
|
32
|
+
"build_gate": { "passed": null }
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"code_review": {
|
|
36
|
+
"status": "pending",
|
|
37
|
+
"retry_count": 0,
|
|
38
|
+
"gates": {
|
|
39
|
+
"lint_gate": { "passed": null },
|
|
40
|
+
"human_gate_2": { "passed": null }
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"test": {
|
|
44
|
+
"status": "pending",
|
|
45
|
+
"framework": null,
|
|
46
|
+
"sub_phases": {
|
|
47
|
+
"unit": {
|
|
48
|
+
"status": "pending",
|
|
49
|
+
"gates": { "test_unit_gate": { "passed": null } }
|
|
50
|
+
},
|
|
51
|
+
"integration": {
|
|
52
|
+
"status": "pending",
|
|
53
|
+
"gates": { "test_integration_gate": { "passed": null } }
|
|
54
|
+
},
|
|
55
|
+
"e2e": {
|
|
56
|
+
"status": "pending",
|
|
57
|
+
"gates": { "test_e2e_gate": { "passed": null } }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"archive": {
|
|
62
|
+
"status": "pending",
|
|
63
|
+
"gates": {
|
|
64
|
+
"human_gate_3": { "passed": null },
|
|
65
|
+
"archive_gate": { "passed": null }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## 关键字段说明
|
|
73
|
+
|
|
74
|
+
| 字段 | 说明 |
|
|
75
|
+
|------|------|
|
|
76
|
+
| `version` | Schema 版本号,当前为 1 |
|
|
77
|
+
| `change_name` | 变更名称,与 `specline/changes/<name>/` 目录名一致 |
|
|
78
|
+
| `created_at` | 流水线创建时间(ISO 8601 格式) |
|
|
79
|
+
| `updated_at` | 流水线最后更新时间(ISO 8601 格式) |
|
|
80
|
+
| `current_phase` | 当前阶段(spec / coding / code_review / test / archive) |
|
|
81
|
+
| `current_step` | 当前正在执行的步骤名称(如 `specline-spec-creator`) |
|
|
82
|
+
| `phases.<phase>.status` | 阶段状态(pending / in_progress / completed) |
|
|
83
|
+
| `phases.<phase>.retry_count` | 该阶段重试次数 |
|
|
84
|
+
| `phases.<phase>.gates.<gate_name>.passed` | 门禁通过状态(null / true / false) |
|
|
85
|
+
| `phases.coding.tasks[]` | 编码任务列表(含 id / type / deps / batch / status / files) |
|
|
86
|
+
| `phases.test.framework` | 测试框架名称,由 test-writer 确认后填入 |
|
|
87
|
+
| `phases.test.sub_phases.<type>.status` | 测试子阶段状态(unit / integration / e2e) |
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# 子 Agent Prompt 模板
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
3 套子 Agent prompt 模板,供 SKILL.md Step 7 的编排者按需读取。编排者根据 `task.type` 和 `task.testable` 选择对应模板,填充 `${变量}` 后作为子 Agent 的 prompt。
|
|
6
|
+
|
|
7
|
+
## 使用说明
|
|
8
|
+
|
|
9
|
+
编排者在 Step 7 中执行以下逻辑:
|
|
10
|
+
|
|
11
|
+
1. 读取本文件(`templates/subagent-prompts.md`)
|
|
12
|
+
2. 根据 `task.type` 和 `task.testable` 选择模板:
|
|
13
|
+
|
|
14
|
+
| 条件 | 模板 |
|
|
15
|
+
|------|------|
|
|
16
|
+
| `task.testable === true`(type 为 frontend/backend/infra/db) | Template 1: TDD Prompt |
|
|
17
|
+
| `task.testable === false` 且 type 为 frontend/backend/infra/db | Template 2: Standard Coding Prompt |
|
|
18
|
+
| type 为 config 或 docs | Template 3: Config/Docs Prompt |
|
|
19
|
+
|
|
20
|
+
3. 用任务数据填充模板中的 `${变量}` 占位符(见各模板头部的变量列表)
|
|
21
|
+
4. 将填充后的内容作为子 Agent 的 system prompt 传入
|
|
22
|
+
|
|
23
|
+
**注意**:如果模板中使用了 `${变量}` 但任务数据中无对应字段,编排者应报 WARNING 事件日志并使用空字符串兜底。
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Template 1: TDD Prompt(Testable: true)
|
|
28
|
+
|
|
29
|
+
**适用条件**:`task.testable === true`,type 为 `frontend`/`backend`/`infra`/`db`
|
|
30
|
+
|
|
31
|
+
**所需变量**:
|
|
32
|
+
|
|
33
|
+
| 变量 | 来源 | 说明 |
|
|
34
|
+
|------|------|------|
|
|
35
|
+
| `${changeName}` | 流水线上下文 | 当前 change 名称 |
|
|
36
|
+
| `${capability}` | 流水线上下文 | 当前 capability 名称 |
|
|
37
|
+
| `${task.id}` | `task.id` | 任务 ID |
|
|
38
|
+
| `${task.type}` | `task.type` | 任务类型(frontend/backend/infra/db) |
|
|
39
|
+
| `${task.covers}` | `task.covers` | 覆盖的需求声明 |
|
|
40
|
+
| `${task.files}` | `task.files` | 预期产出文件 |
|
|
41
|
+
| `${task.content}` | `task.content` | 从 tasks.md 提取的任务完整描述 |
|
|
42
|
+
|
|
43
|
+
### Prompt 模板
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
你收到一个编码任务(Type: ${task.type}, Testable: true),请按 TDD(测试驱动开发)方式实现本任务范围内的代码。
|
|
47
|
+
|
|
48
|
+
## 上下文文件(只读参考)
|
|
49
|
+
- Spec: specline/changes/${changeName}/specs/${capability}/spec.md
|
|
50
|
+
- Design: specline/changes/${changeName}/design.md
|
|
51
|
+
- Tasks: specline/changes/${changeName}/tasks.md
|
|
52
|
+
|
|
53
|
+
## 当前任务(只实现这个)
|
|
54
|
+
任务 ID: ${task.id}
|
|
55
|
+
覆盖需求: ${task.covers}
|
|
56
|
+
预期文件: ${task.files}
|
|
57
|
+
|
|
58
|
+
从 tasks.md 中提取的任务 ${task.id} 的完整描述:
|
|
59
|
+
---
|
|
60
|
+
${task.content}
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## TDD 约束(RED-GREEN-REFACTOR)
|
|
64
|
+
|
|
65
|
+
你必须按以下 TDD 循环编写代码:
|
|
66
|
+
|
|
67
|
+
### RED 阶段
|
|
68
|
+
1. 分析 Spec 中本任务覆盖的 Scenario,提取需要测试的逻辑单元
|
|
69
|
+
2. 在 tests/unit/<module>/test_<feature>.{ext} 下编写测试文件
|
|
70
|
+
3. 每个 Scenario 至少 1 个测试函数/方法
|
|
71
|
+
4. 覆盖:Happy Path + 边界条件(空值、极值、边界值)+ 异常路径(错误输入、异常状态)
|
|
72
|
+
5. 运行测试,确认全部 FAIL(RED)
|
|
73
|
+
|
|
74
|
+
### GREEN 阶段
|
|
75
|
+
6. 编写最小实现代码,只使当前测试通过
|
|
76
|
+
7. 不编写测试未覆盖的逻辑
|
|
77
|
+
8. 运行测试,确认全部 PASS(GREEN)
|
|
78
|
+
|
|
79
|
+
### REFACTOR 阶段
|
|
80
|
+
9. 重构实现代码改善结构(提取方法、消除重复、优化命名)
|
|
81
|
+
10. 运行测试,确保持续 PASS
|
|
82
|
+
11. 如果需要,补充缺失的边界条件测试
|
|
83
|
+
|
|
84
|
+
## 关键约束
|
|
85
|
+
1. 只修改本任务 Files 范围内的文件
|
|
86
|
+
2. 不修改其他任务负责的文件
|
|
87
|
+
3. 与已完成任务的接口约定必须遵守(参考已生成的接口/类型定义文件)
|
|
88
|
+
4. 确认过 design.md 中的技术决策后再动手
|
|
89
|
+
5. 测试文件只能写入 tests/unit/ 或 tests/models/ 目录
|
|
90
|
+
6. 不得修改 tests/integration/ 或 tests/e2e/ 目录下的文件(属于 test-writer)
|
|
91
|
+
7. **完成后必须将 tasks.md 中本任务的 `[ ]` 改为 `[x]`**(方便断点续跑识别进度)
|
|
92
|
+
|
|
93
|
+
## 产出报告
|
|
94
|
+
完成后在 specline/changes/${changeName}/.tmp/task-${task.id}-result.json 写入:
|
|
95
|
+
{
|
|
96
|
+
"task_id": "${task.id}",
|
|
97
|
+
"type": "${task.type}",
|
|
98
|
+
"testable": true,
|
|
99
|
+
"covers": "${task.covers}",
|
|
100
|
+
"status": "completed",
|
|
101
|
+
"files_changed": [...],
|
|
102
|
+
"test_files": ["tests/unit/...", ...],
|
|
103
|
+
"tests_passed": true,
|
|
104
|
+
"summary": "..."
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Template 2: Standard Coding Prompt(Testable: false,有代码逻辑)
|
|
111
|
+
|
|
112
|
+
**适用条件**:`task.testable === false`,type 为 `frontend`/`backend`/`infra`/`db`
|
|
113
|
+
|
|
114
|
+
**所需变量**:
|
|
115
|
+
|
|
116
|
+
| 变量 | 来源 | 说明 |
|
|
117
|
+
|------|------|------|
|
|
118
|
+
| `${changeName}` | 流水线上下文 | 当前 change 名称 |
|
|
119
|
+
| `${capability}` | 流水线上下文 | 当前 capability 名称 |
|
|
120
|
+
| `${task.id}` | `task.id` | 任务 ID |
|
|
121
|
+
| `${task.type}` | `task.type` | 任务类型(frontend/backend/infra/db) |
|
|
122
|
+
| `${task.covers}` | `task.covers` | 覆盖的需求声明 |
|
|
123
|
+
| `${task.files}` | `task.files` | 预期产出文件 |
|
|
124
|
+
| `${task.content}` | `task.content` | 从 tasks.md 提取的任务完整描述 |
|
|
125
|
+
|
|
126
|
+
### Prompt 模板
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
你收到一个编码任务(Type: ${task.type}, Testable: false),请只实现本任务范围内的代码。
|
|
130
|
+
|
|
131
|
+
## 上下文文件(只读参考)
|
|
132
|
+
- Spec: specline/changes/${changeName}/specs/${capability}/spec.md
|
|
133
|
+
- Design: specline/changes/${changeName}/design.md
|
|
134
|
+
- Tasks: specline/changes/${changeName}/tasks.md
|
|
135
|
+
|
|
136
|
+
## 当前任务(只实现这个)
|
|
137
|
+
任务 ID: ${task.id}
|
|
138
|
+
覆盖需求: ${task.covers}
|
|
139
|
+
预期文件: ${task.files}
|
|
140
|
+
|
|
141
|
+
从 tasks.md 中提取的任务 ${task.id} 的完整描述:
|
|
142
|
+
---
|
|
143
|
+
${task.content}
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 约束
|
|
147
|
+
1. 只修改本任务 Files 范围内的文件
|
|
148
|
+
2. 不修改其他任务负责的文件
|
|
149
|
+
3. 与已完成任务的接口约定必须遵守(参考已生成的接口/类型定义文件)
|
|
150
|
+
4. 确认过 design.md 中的技术决策后再动手
|
|
151
|
+
5. **完成后必须将 tasks.md 中本任务的 `[ ]` 改为 `[x]`**(方便断点续跑识别进度)
|
|
152
|
+
|
|
153
|
+
## 产出报告
|
|
154
|
+
完成后在 specline/changes/${changeName}/.tmp/task-${task.id}-result.json 写入:
|
|
155
|
+
{
|
|
156
|
+
"task_id": "${task.id}",
|
|
157
|
+
"type": "${task.type}",
|
|
158
|
+
"testable": false,
|
|
159
|
+
"covers": "${task.covers}",
|
|
160
|
+
"status": "completed",
|
|
161
|
+
"files_changed": [...],
|
|
162
|
+
"summary": "..."
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Template 3: Config/Docs Prompt(config/docs 类型)
|
|
169
|
+
|
|
170
|
+
**适用条件**:type 为 `config` 或 `docs`
|
|
171
|
+
|
|
172
|
+
**所需变量**:
|
|
173
|
+
|
|
174
|
+
| 变量 | 来源 | 说明 |
|
|
175
|
+
|------|------|------|
|
|
176
|
+
| `${changeName}` | 流水线上下文 | 当前 change 名称 |
|
|
177
|
+
| `${capability}` | 流水线上下文 | 当前 capability 名称 |
|
|
178
|
+
| `${task.id}` | `task.id` | 任务 ID |
|
|
179
|
+
| `${task.type}` | `task.type` | 任务类型(config/docs) |
|
|
180
|
+
| `${task.covers}` | `task.covers` | 覆盖的需求声明 |
|
|
181
|
+
| `${task.files}` | `task.files` | 预期产出文件 |
|
|
182
|
+
| `${task.content}` | `task.content` | 从 tasks.md 提取的任务完整描述 |
|
|
183
|
+
|
|
184
|
+
### Prompt 模板
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
你收到一个编码任务(Type: ${task.type}),请只实现本任务范围内的代码。
|
|
188
|
+
|
|
189
|
+
## 上下文文件(只读参考)
|
|
190
|
+
- Spec: specline/changes/${changeName}/specs/${capability}/spec.md
|
|
191
|
+
- Design: specline/changes/${changeName}/design.md
|
|
192
|
+
- Tasks: specline/changes/${changeName}/tasks.md
|
|
193
|
+
|
|
194
|
+
## 当前任务(只实现这个)
|
|
195
|
+
任务 ID: ${task.id}
|
|
196
|
+
覆盖需求: ${task.covers}
|
|
197
|
+
预期文件: ${task.files}
|
|
198
|
+
|
|
199
|
+
从 tasks.md 中提取的任务 ${task.id} 的完整描述:
|
|
200
|
+
---
|
|
201
|
+
${task.content}
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 约束
|
|
205
|
+
1. 只修改本任务 Files 范围内的文件
|
|
206
|
+
2. 不修改其他任务负责的文件
|
|
207
|
+
3. 与已完成任务的接口约定必须遵守(参考已生成的接口/类型定义文件)
|
|
208
|
+
4. 确认过 design.md 中的技术决策后再动手
|
|
209
|
+
5. **完成后必须将 tasks.md 中本任务的 `[ ]` 改为 `[x]`**(方便断点续跑识别进度)
|
|
210
|
+
|
|
211
|
+
## 产出报告
|
|
212
|
+
完成后在 specline/changes/${changeName}/.tmp/task-${task.id}-result.json 写入:
|
|
213
|
+
{
|
|
214
|
+
"task_id": "${task.id}",
|
|
215
|
+
"type": "${task.type}",
|
|
216
|
+
"covers": "${task.covers}",
|
|
217
|
+
"status": "completed",
|
|
218
|
+
"files_changed": [...],
|
|
219
|
+
"summary": "..."
|
|
220
|
+
}
|
|
221
|
+
```
|