@gong-ym/ai-spec-auto 0.2.17 → 0.2.19

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.
@@ -237,7 +237,99 @@ frontend-implementer(前端实现专家)
237
237
  - 追加一条 `run-cancelled` 事件
238
238
  - 记录 `timestamps.finished_at`
239
239
 
240
- ## 7. 当前阶段边界
240
+ ## 7. 上下文传递优化(Context Pass-through)
241
+
242
+ ### 7.1 问题背景
243
+
244
+ 当前每个专家都需要独立加载以下上下文:
245
+
246
+ - `context/PROJECT.md`
247
+ - `.agents/rules/` 下的项目规则
248
+ - `openspec/changes/<change-id>/` 下的变更文档
249
+ - 前序专家的分析产物
250
+
251
+ 这导致:
252
+
253
+ - 重复读取相同文件
254
+ - 每个专家都要重新解析项目规则
255
+ - 上下文信息在多轮对话中逐渐稀释
256
+
257
+ ### 7.2 上下文传递机制
258
+
259
+ 当发生专家交接时,handoff payload 应携带 `context_payload`:
260
+
261
+ ```json
262
+ {
263
+ "context_payload": {
264
+ "project_facts": {
265
+ "tech_stack": "Vue 3 + TypeScript + Vite",
266
+ "directory_structure": "src/views/, src/components/",
267
+ "api_pattern": "@/utils/request",
268
+ "style_pattern": "主题变量 + Tailwind"
269
+ },
270
+ "current_change": {
271
+ "change_id": "add-product-delete",
272
+ "proposal_path": "openspec/changes/add-product-delete/proposal.md",
273
+ "tasks_path": "openspec/changes/add-product-delete/tasks.md",
274
+ "specs_dir": "openspec/changes/add-product-delete/specs/"
275
+ },
276
+ "previous_analysis": {
277
+ "requirement_summary": "给商品卡片加删除按钮,点击后调用 DELETE API",
278
+ "key_decisions": ["沿用项目 Button 组件", "删除前弹确认框"],
279
+ "open_questions": []
280
+ },
281
+ "rules_snapshot": {
282
+ "loaded_rules": ["01-项目概述.md", "03-项目结构.md", "05-API规范.md", "09-样式规范.md"],
283
+ "key_constraints": ["API 必须使用 @/utils/request 封装", "样式必须使用主题变量"]
284
+ }
285
+ }
286
+ }
287
+ ```
288
+
289
+ ### 7.3 下游专家行为
290
+
291
+ 当收到 `context_payload` 时,下游专家应:
292
+
293
+ 1. **优先使用传递的上下文**:不再重复读取已包含的文件
294
+ 2. **按需补充读取**:只读取 `context_payload` 中未覆盖的规则
295
+ 3. **继承前序分析**:直接引用 `previous_analysis` 中的结论,不重新分析
296
+
297
+ ### 7.4 简单需求直接交接
298
+
299
+ 当 `delivery_profile = micro` 且 `complexity = low` 时,允许:
300
+
301
+ - `requirement-analyst` 完成后直接产出 `frontend-implementer` 的执行载荷
302
+ - `task-orchestrator` 只做状态记录,不做额外干预
303
+ - 实现专家直接读取 `context_payload` 进入编码
304
+
305
+ ## 8. 并行分析阶段(可选)
306
+
307
+ ### 8.1 适用场景
308
+
309
+ 当复杂需求同时触发多个可选专家时:
310
+
311
+ - `requirement-analyst` 完成基础分析
312
+ - `design-collaborator` 分析设计约束
313
+ - `api-contract-specialist` 分析接口契约
314
+
315
+ ### 8.2 并行执行模式
316
+
317
+ ```
318
+ requirement-analyst(完成基础分析)
319
+
320
+ ├─ design-collaborator(并行分析)
321
+ └─ api-contract-specialist(并行分析)
322
+
323
+ frontend-implementer(合并分析结果后进入实现)
324
+ ```
325
+
326
+ ### 8.3 实现约束
327
+
328
+ - 并行专家必须基于同一份 `context_payload`
329
+ - 各专家产出独立文档,不互相依赖
330
+ - `task-orchestrator` 在所有并行专家完成后合并结果
331
+
332
+ ## 9. 当前阶段边界
241
333
 
242
334
  当前最小实现只解决:
243
335
 
@@ -211,7 +211,34 @@ description: 定义 task-orchestrator 在首次识别任务时必须输出的最
211
211
  - 多状态联动、真实接口、复杂业务规则、核心模块改造
212
212
  - 使用完整产物与完整门禁
213
213
 
214
- ### 5.6 micro 的产物规格
214
+ ### 5.6 简单需求快速通道
215
+
216
+ 当 `delivery_profile = micro` 且 `complexity = low` 时,启用快速通道:
217
+
218
+ **简单需求判断标准**(满足全部):
219
+ - 单文件或 2-3 个文件的修改
220
+ - 任务明确(如"加个按钮"、"改个样式"、"加个校验")
221
+ - 不涉及新模块、新路由、新接口
222
+ - 无需设计稿或复杂交互
223
+ - 项目规则中已有明确实现模式
224
+
225
+ **快速通道行为**:
226
+ 1. `requirement-analyst` 跳过 `design-analysis` 调用
227
+ 2. `proposal.md` 使用极简版(目标、范围、假设,各 1-2 行)
228
+ 3. `specs/` 使用极简版(只写变更点,不写完整场景)
229
+ 4. `tasks.md` 使用极简版(3-5 条直接可执行任务)
230
+ 5. 快速进入实现,不做详细澄清
231
+
232
+ **复杂需求**(命中任一):
233
+ - 涉及多个模块或系统级变更
234
+ - 需要新接口、新状态管理、新路由设计
235
+ - 有设计稿或复杂交互需求
236
+ - 存在技术选型或架构决策
237
+ - 规则不明确,需要大量澄清
238
+
239
+ 复杂需求按完整流程执行,不做快速通道优化。
240
+
241
+ ### 5.7 micro 的产物规格
215
242
 
216
243
  当 `delivery_profile = micro` 时:
217
244
 
@@ -219,7 +246,8 @@ description: 定义 task-orchestrator 在首次识别任务时必须输出的最
219
246
  - `tasks.md` 使用短版:3-5 条可执行任务
220
247
  - `checklist.md` 使用短版:关键检查项、阻断项、是否建议通过
221
248
  - `iterations.md` 使用短版:问题、修正动作、残留风险
222
- - 不允许因为是 `micro` 而跳过专家或跳过 OpenSpec 落盘
249
+ - 对于简单需求(见 5.6),`requirement-analyst` 可采用快速通道行为
250
+ - 不允许因为 `micro` 而跳过 OpenSpec 落盘
223
251
 
224
252
  ### 5.7 page-development 任务的缺口分类
225
253
 
@@ -289,6 +317,59 @@ description: 定义 task-orchestrator 在首次识别任务时必须输出的最
289
317
  - 先按默认假设进入 requirement-analyst(需求解析专家);若需求收敛阶段发现高风险冲突,再转 suggest 或 manual
290
318
  ```
291
319
 
320
+ ### 简单需求示例(快速通道)
321
+
322
+ #### 输入
323
+
324
+ ```text
325
+ @task-orchestrator(任务主代理) 给商品卡片加个删除按钮
326
+ ```
327
+
328
+ #### 输出
329
+
330
+ ```md
331
+ ## 任务识别
332
+ - 类型:组件增强
333
+ - 当前输入:给商品卡片加个删除按钮
334
+ - 风险级别:low
335
+ - 复杂度:low(单文件修改,任务明确)
336
+
337
+ ## 推荐流程模板
338
+ - `selected_flow(选中的流程模板)`:prd-to-delivery
339
+ - 原因:简单增强任务,适合快速通道
340
+
341
+ ## 运行模式
342
+ - `mode(运行模式)`:auto
343
+
344
+ ## 交付档位
345
+ - `delivery_profile(交付档位)`:micro
346
+ - `artifact_profile(产物规格)`:compact
347
+ - `complexity(复杂度)`:low
348
+
349
+ ## 快速通道
350
+ - 已识别为简单需求,启用快速通道
351
+ - requirement-analyst 跳过 design-analysis
352
+ - 文档采用极简版
353
+
354
+ ## 推荐专家
355
+ - 必选:frontend-implementer(前端实现专家)、code-guardian(规范守护者)
356
+ - 可选:requirement-analyst(需求解析专家)
357
+ - 第一跳:requirement-analyst(需求解析专家)
358
+
359
+ ## 默认假设
360
+ - 沿用项目现有组件结构和样式规范
361
+ - 删除按钮样式沿用项目 Button 组件
362
+
363
+ ## 缺失输入
364
+ - 无
365
+
366
+ ## 审批点
367
+ - 暂无
368
+
369
+ ## 下一步
370
+ - 直接进入快速通道,requirement-analyst 生成极简文档后快速进入实现
371
+ ```
372
+
292
373
  ## 7. 一句话约束
293
374
 
294
375
  > `task-orchestrator(任务主代理)` 的首轮输出必须先形成结构化 `run-plan(运行计划)`;在 `auto(自动)` 模式下,应先做仓库推断并记录 `assumptions(默认假设)`,不默认回问用户,只有高风险关键分歧才转 `suggest(建议)` 或 `manual(手动)`。
@@ -43,6 +43,31 @@ handoff_to:
43
43
  - 输出必须服务后续实现与验收,不写空泛汇报材料
44
44
  - 专家不是发明新方案,而是通过 `rules + skills + OpenSpec` 收敛到当前项目可实施方案
45
45
 
46
+ ## 复杂度快速判断
47
+
48
+ **简单需求(快速通道)** - 满足以下全部条件:
49
+ - 单文件或 2-3 个文件的修改
50
+ - 任务明确(如"加个按钮"、"改个样式"、"加个校验")
51
+ - 不涉及新模块、新路由、新接口
52
+ - 无需设计稿或复杂交互
53
+ - 项目规则中已有明确实现模式
54
+
55
+ **快速通道行为**:
56
+ 1. 跳过 `design-analysis` 调用
57
+ 2. `proposal.md` 使用短版(目标、范围、假设,各 1-2 行)
58
+ 3. `specs/` 使用短版(只写变更点,不写完整场景)
59
+ 4. `tasks.md` 使用短版(3-5 条直接可执行任务)
60
+ 5. 直接进入实现,不做详细澄清
61
+
62
+ **复杂需求(完整分析)** - 命中以下任一条件:
63
+ - 涉及多个模块或系统级变更
64
+ - 需要新接口、新状态管理、新路由设计
65
+ - 有设计稿或复杂交互需求
66
+ - 存在技术选型或架构决策
67
+ - 规则不明确,需要大量澄清
68
+
69
+ **完整分析行为**:按下方"必做步骤"执行完整流程。
70
+
46
71
  ## 必做步骤
47
72
 
48
73
  1. 读取任务输入、项目背景、`role_rule_contract`、`repo_conventions`
@@ -431,7 +431,12 @@ async function main(mode, argv) {
431
431
  }
432
432
 
433
433
  if (options.json) {
434
- process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
434
+ const output = `${JSON.stringify(result, null, 2)}\n`;
435
+ // 确保 stdout 完整写入后再退出,避免 spawnSync 截断
436
+ process.stdout.write(output);
437
+ if (process.stdout.writableLength > 0) {
438
+ await new Promise((resolve) => process.stdout.once('drain', resolve));
439
+ }
435
440
  } else {
436
441
  if (mode === 'advance') {
437
442
  printStep(result);
@@ -115,56 +115,29 @@ function refresh(targetDir, pkgRoot) {
115
115
  updated.push('openspec/config.yaml.template');
116
116
  }
117
117
 
118
- // 4. 同步 IDE 命令文件
118
+ // 4. 同步 IDE 配置文件(跳过指针文件,只同步实际目录)
119
+ // IDE 的 commands/rules/skills 可能是指向 .agents/ 的指针文件(非目录),
120
+ // 这些指针文件不需要替换,因为 .agents/ 已经在步骤 1 中同步过了。
119
121
  const ides = ['cursor', 'claude', 'qoder', 'trae', 'opencode'];
120
122
  for (const ide of ides) {
121
123
  const sourceIdeDir = path.join(sourceDir, `.${ide}`);
122
124
  const targetIdeDir = path.join(targetDir, `.${ide}`);
123
125
  if (!fs.existsSync(sourceIdeDir) || !fs.existsSync(targetIdeDir)) continue;
124
126
 
125
- // 同步 commands
126
- const srcCmdDir = path.join(sourceIdeDir, 'commands');
127
- const destCmdDir = path.join(targetIdeDir, 'commands');
128
- if (fs.existsSync(srcCmdDir)) {
129
- try {
130
- if (fs.existsSync(destCmdDir)) {
131
- fs.rmSync(destCmdDir, { recursive: true, force: true });
132
- }
133
- copyDirSync(srcCmdDir, destCmdDir);
134
- updated.push(`.${ide}/commands/`);
135
- } catch (error) {
136
- skipped.push({ path: `.${ide}/commands/`, reason: error.message });
137
- }
138
- }
139
-
140
- // 同步 rules(如果是实际文件而非 symlink)
141
- const srcRulesDir = path.join(sourceIdeDir, 'rules');
142
- const destRulesDir = path.join(targetIdeDir, 'rules');
143
- if (fs.existsSync(srcRulesDir) && !isSymlink(destRulesDir)) {
144
- try {
145
- if (fs.existsSync(destRulesDir)) {
146
- fs.rmSync(destRulesDir, { recursive: true, force: true });
147
- }
148
- copyDirSync(srcRulesDir, destRulesDir);
149
- updated.push(`.${ide}/rules/`);
150
- } catch (error) {
151
- skipped.push({ path: `.${ide}/rules/`, reason: error.message });
152
- }
153
- }
154
-
155
- // 同步 skills
156
- const srcSkillsDir = path.join(sourceIdeDir, 'skills');
157
- const destSkillsDir = path.join(targetIdeDir, 'skills');
158
- if (fs.existsSync(srcSkillsDir)) {
159
- try {
160
- if (fs.existsSync(destSkillsDir)) {
161
- fs.rmSync(destSkillsDir, { recursive: true, force: true });
127
+ // 同步 IDE 特有配置文件(如 mcp.json)
128
+ try {
129
+ const sourceEntries = fs.readdirSync(sourceIdeDir);
130
+ for (const entry of sourceEntries) {
131
+ const srcPath = path.join(sourceIdeDir, entry);
132
+ const destPath = path.join(targetIdeDir, entry);
133
+ // 只同步文件,不同步目录(commands/rules/skills 目录由 .agents/ 指针管理)
134
+ if (fs.statSync(srcPath).isFile()) {
135
+ fs.copyFileSync(srcPath, destPath);
136
+ updated.push(`.${ide}/${entry}`);
162
137
  }
163
- copyDirSync(srcSkillsDir, destSkillsDir);
164
- updated.push(`.${ide}/skills/`);
165
- } catch (error) {
166
- skipped.push({ path: `.${ide}/skills/`, reason: error.message });
167
138
  }
139
+ } catch (error) {
140
+ skipped.push({ path: `.${ide}/`, reason: error.message });
168
141
  }
169
142
  }
170
143
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gong-ym/ai-spec-auto",
3
- "version": "0.2.17",
3
+ "version": "0.2.19",
4
4
  "description": "AI Coding 团队规范驱动开发 CLI — 一键安装规范、技能与工具配置",
5
5
  "homepage": "https://github.com/gong-chick/engineered-spec#readme",
6
6
  "repository": {