Add Phase 4: Task Generation documentation and execution process

- Introduced comprehensive guidelines for generating implementation plan documents (IMPL_PLAN.md, task JSONs, TODO_LIST.md) using the action-planning-agent.
- Defined auto mode for user configuration with default settings.
- Outlined core philosophy emphasizing planning only, agent-driven document generation, and memory-first context loading.
- Detailed execution process divided into phases: User Configuration, Context Preparation, Single Agent Planning, N Parallel Planning, and Integration.
- Included lifecycle management for user configuration and agent interactions.
- Specified document generation lifecycle with clear expectations for outputs and quality standards.
This commit is contained in:
catlog22
2026-02-05 20:50:21 +08:00
parent 01459a34a5
commit 9fc2c876f7
12 changed files with 2126 additions and 414 deletions

View File

@@ -0,0 +1,677 @@
# 命令转 Skill 规范 v1.0
> 基于 `workflow-plan` 命令转换实践提炼的标准流程
## ⚠️ 核心要求
**Phase 文件内容必须与原命令文件内容一致**
转换时只改变结构和组织方式,不改变功能实现细节。
---
## 目录
1. [转换目标](#1-转换目标)
2. [核心原则](#2-核心原则)
3. [结构映射](#3-结构映射)
4. [转换步骤](#4-转换步骤)
5. [SKILL.md 编写规范](#5-skillmd-编写规范)
6. [Phase 文件编写规范](#6-phase-文件编写规范)
7. [内容一致性验证](#7-内容一致性验证)
8. [质量检查清单](#8-质量检查清单)
9. [示例对照](#9-示例对照)
---
## 1. 转换目标
### 1.1 为什么转换
| 命令格式 | Skill 格式 |
|----------|-----------|
| 单文件 + 子命令引用 | 结构化目录 + 分阶段执行 |
| 一次性全量加载 | **分布读取**(按需加载) |
| 执行流程隐式 | 执行流程**显式定义** |
| 子命令散落各处 | Phase 文件**集中管理** |
| 缺乏复用机制 | 模板/规范可复用 |
### 1.2 转换收益
- **上下文优化**Phase 文件按需加载,减少 token 消耗
- **可维护性**:结构清晰,修改范围可控
- **可扩展性**:新增阶段只需添加 Phase 文件
- **执行可视化**TodoWrite 与 Phase 对齐,进度透明
---
## 2. 核心原则
### 2.1 内容一致性原则(最高优先级)
> **Phase 文件内容必须与原命令文件内容一致**
>
> 这是转换的第一要求,不可妥协。
**一致性定义**
| 维度 | 一致性要求 | 验证方法 |
|------|-----------|---------|
| **代码逻辑** | 所有Bash命令、函数、条件判断完全一致 | 逐行对比代码块 |
| **Agent Prompt** | Prompt内容100%保留,包括示例和约束 | 全文搜索关键段落 |
| **数据结构** | 表格、Schema、类型定义完整复制 | 对比字段数量 |
| **执行步骤** | 步骤顺序、子步骤层级保持不变 | 对比步骤编号 |
| **文本说明** | 关键说明、注释、警告完整保留 | 抽查重要段落 |
**允许的差异**
| 差异类型 | 说明 | 示例 |
|---------|------|------|
| ✅ 添加阶段标识 | Phase标题、来源标注 | `# Phase 1: Session Discovery` |
| ✅ 添加组织结构 | 章节标题优化 | 添加 `## Execution Steps` |
| ✅ 添加衔接说明 | Post-Phase Update | 阶段完成后的状态说明 |
| ✅ 移除命令调用语法 | 移除 `/workflow``/command` 等命令引用 | 原文 `/workflow:session:start` → 移除 |
| ✅ 移除 Frontmatter | 移除命令的 argument-hint、examples | 命令级元数据在 Skill 中不需要 |
| ❌ 简化代码 | 任何代码的省略或改写 | 不允许 |
| ❌ 简化Prompt | Agent Prompt的任何删减 | 不允许 |
| ❌ 调整步骤 | 合并、拆分、重排步骤 | 不允许 |
**内容保留清单**
| 内容类型 | 保留要求 | 示例 |
|---------|---------|------|
| **Bash命令** | 完整命令,包含所有参数、管道、重定向 | `find . -name "*.json" \| head -1` |
| **Agent Prompt** | 全文保留包含OBJECTIVE、TASK、EXPECTED等所有节 | 完整的Task({prompt: "..."}) |
| **代码函数** | 完整函数体所有if/else分支 | `analyzeTaskComplexity()` 全部代码 |
| **参数表格** | 所有行列,不省略任何参数 | Session Types表格 |
| **JSON Schema** | 所有字段、类型、required定义 | context-package.json schema |
| **验证逻辑** | 所有校验条件、错误处理、回滚代码 | conflict resolution验证清单 |
| **配置示例** | 输入输出示例、配置模板 | planning-notes.md模板 |
| **注释说明** | 重要的行内注释、块注释 | `// CRITICAL: ...` |
**严格禁止的简化行为**
1. **将代码替换为描述**
- ❌ 错误:`Execute context gathering agent`
- ✅ 正确:完整的 `Task({ subagent_type: "context-search-agent", prompt: "...[完整200行prompt]..." })`
2. **省略Prompt内容**
- ❌ 错误:`Agent prompt for context gathering (see original file)`
- ✅ 正确复制粘贴完整Prompt文本
3. **压缩表格**
- ❌ 错误:`Session types: Discovery/Auto/Force (see details in code)`
- ✅ 正确完整Session Types表格包含type/description/use case列
4. **合并步骤**
- ❌ 错误将Step 1.1-1.4合并为Step 1
- ✅ 正确保持1.1、1.2、1.3、1.4独立步骤
5. **删除示例**
- ❌ 错误省略JSON输出示例
- ✅ 正确:保留所有输入输出示例
**应移除的命令特有内容**
转换时应移除以下命令格式专有的内容:
| 移除内容 | 原因 | 示例 |
|---------|------|------|
| **Frontmatter** | Skill 使用 SKILL.md 的 Frontmatter | `argument-hint``allowed-tools``examples` |
| **命令调用语法** | Skill 使用 Phase 引用 | `/workflow:session:start` → 移除 |
| **命令路径引用** | 改为 Phase 路径引用 | `commands/workflow/tools/` → 移除 |
| **Skill 调用说明** | 在 SKILL.md 中统一说明 | `使用 /workflow:xxx 调用` → 移除 |
| **命令参数说明** | 仅保留执行参数 | `usage: /workflow:plan [session-id]` → 移除 |
**示例**
原命令文件中:
```markdown
## Related Commands
- `/workflow:session:start` - Start new session
- `/workflow:tools:context-gather` - Gather context
```
转换后Phase文件中
```markdown
## Related Phases
- Phase 1: Session Discovery
- Phase 2: Context Gathering
```
或直接移除相关命令说明章节,因为 SKILL.md 已包含完整的 Phase 引用表。
### 2.2 分布读取原则
> **SKILL.md 引用 PhasePhase 按执行顺序加载**
```
执行流程:
Phase 1 → Read: phases/01-xxx.md → 执行 → 释放
Phase 2 → Read: phases/02-xxx.md → 执行 → 释放
Phase N → Read: phases/0N-xxx.md → 执行 → 完成
```
### 2.3 职责分离原则
| 层级 | 职责 | 内容 |
|------|------|------|
| **SKILL.md** | 编排协调 | 流程图、数据流、TodoWrite 模式、阶段入口 |
| **Phase 文件** | 具体执行 | 完整执行逻辑、代码实现、Agent Prompt |
| **Specs** | 规范约束 | Schema 定义、质量标准、领域规范 |
| **Templates** | 可复用片段 | Agent 基础模板、输出模板 |
---
## 3. 结构映射
### 3.1 命令结构 → Skill 结构
```
commands/ skills/
├── workflow/ ├── workflow-plan/
│ ├── plan.md ────────→ │ ├── SKILL.md (orchestrator)
│ ├── session/ │ ├── phases/
│ │ └── start.md ────────→ │ │ ├── 01-session-discovery.md
│ └── tools/ │ │ ├── 02-context-gathering.md
│ ├── context-gather.md ───→ │ │ ├── 03-conflict-resolution.md
│ ├── conflict-resolution.md │ │ └── 04-task-generation.md
│ └── task-generate-agent.md │ └── (specs/, templates/ 可选)
```
### 3.2 文件映射规则
| 源文件类型 | 目标文件 | 映射规则 |
|-----------|---------|---------|
| 主命令文件 | `SKILL.md` | 提取元数据、流程、协调逻辑 |
| 子命令文件 | `phases/0N-xxx.md` | 完整内容 + 阶段标识 |
| 引用的规范 | `specs/xxx.md` | 独立提取或保留在 Phase 中 |
| 通用模板 | `templates/xxx.md` | 多处引用时提取 |
### 3.3 命名转换
| 原命令路径 | Phase 文件名 |
|-----------|-------------|
| `session/start.md` | `01-session-discovery.md` |
| `tools/context-gather.md` | `02-context-gathering.md` |
| `tools/conflict-resolution.md` | `03-conflict-resolution.md` |
| `tools/task-generate-agent.md` | `04-task-generation.md` |
**命名规则**`{序号}-{动作描述}.md`
- 序号:两位数字 `01`, `02`, ...
- 动作:动词-名词形式,小写连字符
---
## 4. 转换步骤
### 4.1 准备阶段
```markdown
□ Step 0: 分析源命令结构
- 读取主命令文件,识别调用的子命令
- 绘制命令调用关系图
- 统计各文件行数(用于后续验证)
```
### 4.2 创建目录结构
```markdown
□ Step 1: 创建 Skill 目录
mkdir skills/{skill-name}/
mkdir skills/{skill-name}/phases/
```
### 4.3 编写 SKILL.md
```markdown
□ Step 2: 编写 SKILL.md
- 提取 Frontmatter (name, description, allowed-tools)
- 编写架构概览图
- 编写执行流程(含 Phase 引用表)
- 编写数据流定义
- 编写 TodoWrite 模式
- 编写协调逻辑(阶段间衔接)
```
### 4.4 转换 Phase 文件
```markdown
□ Step 3: 逐个转换子命令为 Phase 文件
FOR each 子命令:
- 读取原命令完整内容
- 添加 Phase 标题和元信息
- 保留所有代码、表格、Agent Prompt
- 添加 Post-Phase Update 节(如需)
- 验证行数接近原文件
```
### 4.5 验证完整性
```markdown
□ Step 4: 验证内容完整性
- 比较 Phase 文件与原命令行数
- 确认关键代码块存在
- 确认 Agent Prompt 完整
- 确认表格和 Schema 完整
```
---
## 5. SKILL.md 编写规范
### 5.1 Frontmatter 模板
```yaml
---
name: {skill-name}
description: {简短描述}. Triggers on "{trigger-phrase}".
allowed-tools: Task, AskUserQuestion, TodoWrite, Read, Write, Edit, Bash, Glob, Grep
---
```
### 5.2 必需章节
```markdown
# {Skill Name}
{一句话描述功能}
## Architecture Overview
{ASCII 架构图}
## Execution Flow
{流程图 + Phase 引用表}
### Phase Reference Documents
| Phase | Document | Load When |
|-------|----------|-----------|
| Phase 1 | phases/01-xxx.md | Phase 1 开始时 |
| ... | ... | ... |
## Core Rules
{执行约束和规则}
## Data Flow
{阶段间数据传递定义}
## TodoWrite Pattern
{任务列表模板}
## Error Handling
{错误处理策略}
```
### 5.3 执行流程示例
```markdown
## Execution Flow
```
Phase 1: Session Discovery
│ Ref: phases/01-session-discovery.md
Phase 2: Context Gathering
│ Ref: phases/02-context-gathering.md
Phase 3: Conflict Resolution (conditional)
│ Ref: phases/03-conflict-resolution.md
Phase 4: Task Generation
│ Ref: phases/04-task-generation.md
Complete: IMPL_PLAN.md + Task JSONs
```
### Phase Reference Documents
| Phase | Document | Load When |
|-------|----------|-----------|
| Phase 1 | `phases/01-session-discovery.md` | Phase 1 开始执行时 |
| Phase 2 | `phases/02-context-gathering.md` | Phase 1 完成后 |
| Phase 3 | `phases/03-conflict-resolution.md` | conflict_risk ≥ medium 时 |
| Phase 4 | `phases/04-task-generation.md` | Phase 3 完成或跳过后 |
```
---
## 6. Phase 文件编写规范
### 6.1 Phase 文件结构
```markdown
# Phase N: {Phase Name}
> 来源: `commands/{path}/original.md`
## Overview
{阶段目标和职责}
## Prerequisites
{前置条件和输入}
## Execution Steps
### Step N.1: {Step Name}
{完整实现代码}
### Step N.2: {Step Name}
{完整实现代码}
## Agent Prompt (如有)
{完整 Agent Prompt不简化}
## Output Format
{输出 Schema 和示例}
## Post-Phase Update
{阶段完成后的状态更新}
```
### 6.2 转换原则:只改结构,不改内容
**转换时的思维模式**
> "我是在**搬运**内容,不是在**改写**内容"
| 操作 | 允许 | 禁止 |
|------|------|------|
| 复制粘贴代码 | ✅ | |
| 调整章节标题 | ✅ | |
| 添加Phase标识 | ✅ | |
| 改写代码逻辑 | | ❌ |
| 简化Prompt | | ❌ |
| 省略步骤 | | ❌ |
**转换流程**
1. **打开原命令文件和新Phase文件并排显示**
2. **逐段复制粘贴**(不要凭记忆改写)
3. **只添加结构性元素**Phase标题、章节标题
4. **保留100%功能性内容**代码、Prompt、表格、示例
### 6.3 内容完整性自查
转换每个Phase文件后必须完成以下检查
| 检查项 | 检查方法 | 合格标准 |
|--------|---------|---------|
| **代码块数量** | 计数 ` ```bash `` ```javascript ` | 与原文件相等 |
| **表格数量** | 计数 ` \| ` 开头的行 | 与原文件相等 |
| **Agent Prompt** | 搜索 `Task({` | 完整的prompt参数内容 |
| **步骤编号** | 检查 `### Step` | 编号序列与原文件一致 |
| **文件行数** | `wc -l` | ±20%以内 |
| **关键函数** | 搜索函数名 | 所有函数完整保留 |
**示例检查**
```bash
# 原命令文件
$ grep -c "^###" commands/workflow/tools/context-gather.md
15
# Phase文件应该相等或略多
$ grep -c "^###" skills/workflow-plan/phases/02-context-gathering.md
16 # ✓ 只多了"Post-Phase Update"节
# 代码块数量对比
$ grep -c '```' commands/workflow/tools/context-gather.md
24
$ grep -c '```' skills/workflow-plan/phases/02-context-gathering.md
24 # ✓ 完全相等
```
### 6.4 内容保留清单(详细版)
转换时必须完整保留:
| 内容类型 | 保留要求 |
|---------|---------|
| **Bash 命令** | 完整命令,包含所有参数和路径 |
| **Agent Prompt** | 全文,包含示例和约束 |
| **代码函数** | 完整函数体,不简化 |
| **参数表格** | 所有列和行 |
| **JSON Schema** | 完整字段定义 |
| **验证逻辑** | if/else、校验代码 |
| **错误处理** | try/catch、回滚逻辑 |
| **示例** | 输入输出示例 |
### 6.3 禁止的简化
**不要这样**
```markdown
### Step 2: Run context gathering
Execute the context-search-agent to gather project context.
```
**应该这样**
```markdown
### Step 2: Run context gathering
```javascript
Task({
subagent_type: "context-search-agent",
prompt: `
## Context Search Task
### OBJECTIVE
Gather comprehensive context for planning session ${sessionId}
### MULTI-SOURCE DISCOVERY STRATEGY
**Track 0: Project Foundation**
- Read CLAUDE.md files at all levels
- Check .workflow/project-tech.json for stack info
...
[完整 Prompt 内容]
`,
run_in_background: false
})
```
```
---
## 7. 内容一致性验证
### 7.1 验证流程
每完成一个Phase文件转换后执行以下验证
```
┌─────────────────────────────────────────────────────────────────┐
│ 内容一致性验证流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Step 1: 行数对比 │
│ $ wc -l 原文件 Phase文件 │
│ └─→ 差异应在 ±20% 以内 │
│ │
│ Step 2: 代码块对比 │
│ $ grep -c '```' 原文件 Phase文件 │
│ └─→ 数量应相等 │
│ │
│ Step 3: 关键内容抽查 │
│ - 搜索 Task({ → Agent Prompt 完整性 │
│ - 搜索函数名 → 函数体完整性 │
│ - 搜索表格标记 → 表格完整性 │
│ │
│ Step 4: 并排对比 │
│ - 打开原文件和Phase文件 │
│ - 逐节对比功能性内容 │
│ - 确认无省略无改写 │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### 7.2 验证命令
```bash
# 1. 行数对比
wc -l commands/workflow/tools/context-gather.md skills/workflow-plan/phases/02-context-gathering.md
# 2. 代码块数量
grep -c '```' commands/workflow/tools/context-gather.md
grep -c '```' skills/workflow-plan/phases/02-context-gathering.md
# 3. 表格行数
grep -c '^|' commands/workflow/tools/context-gather.md
grep -c '^|' skills/workflow-plan/phases/02-context-gathering.md
# 4. Agent Prompt检查
grep -c 'Task({' commands/workflow/tools/context-gather.md
grep -c 'Task({' skills/workflow-plan/phases/02-context-gathering.md
# 5. 函数定义检查
grep -E '^(function|const.*=.*=>|async function)' commands/workflow/tools/context-gather.md
grep -E '^(function|const.*=.*=>|async function)' skills/workflow-plan/phases/02-context-gathering.md
```
### 7.3 一致性检查表
每个Phase文件必须填写
| 检查项 | 原文件 | Phase文件 | 是否一致 |
|--------|--------|-----------|---------|
| 文件行数 | ___ | ___ | □ ±20%内 |
| 代码块数量 | ___ | ___ | □ 相等 |
| 表格行数 | ___ | ___ | □ 相等 |
| Task调用数 | ___ | ___ | □ 相等 |
| 函数定义数 | ___ | ___ | □ 相等 |
| 步骤数量 | ___ | ___ | □ 相等或+1 |
### 7.4 不一致处理
发现不一致时:
| 情况 | 处理方式 |
|------|---------|
| Phase文件行数少>20% | ❌ **必须补充**:定位缺失内容,从原文件复制 |
| 代码块数量少 | ❌ **必须补充**:找出缺失的代码块 |
| Agent Prompt缺失 | ❌ **严重问题**:立即从原文件完整复制 |
| 表格缺失 | ❌ **必须补充**:复制完整表格 |
| Phase文件行数多>20% | ✓ 可接受(添加了结构性内容) |
---
## 8. 质量检查清单
### 8.1 结构检查
```markdown
□ SKILL.md 存在且包含必需章节
□ phases/ 目录存在
□ Phase 文件按数字前缀排序
□ 所有子命令都有对应 Phase 文件
```
### 8.2 内容完整性检查
```markdown
□ Phase 文件行数 ≈ 原命令行数 (±20%)
□ 所有 Bash 命令完整保留
□ 所有 Agent Prompt 完整保留
□ 所有表格完整保留
□ 所有 JSON Schema 完整保留
□ 验证逻辑和错误处理完整
```
### 8.3 引用检查
```markdown
□ SKILL.md 中 Phase 引用路径正确
□ Phase 文件标注了来源命令
□ 跨 Phase 数据引用明确
```
### 8.4 行数对比表
| 原命令 | 行数 | Phase 文件 | 行数 | 差异 |
|--------|------|-----------|------|------|
| session/start.md | 202 | 01-session-discovery.md | 281 | +39% ✓ |
| tools/context-gather.md | 404 | 02-context-gathering.md | 427 | +6% ✓ |
| tools/conflict-resolution.md | 604 | 03-conflict-resolution.md | 645 | +7% ✓ |
| tools/task-generate-agent.md | 693 | 04-task-generation.md | 701 | +1% ✓ |
> Phase 文件可以比原命令稍长添加了阶段标识、Post-Phase Update 等),但不应显著缩短。
---
## 9. 示例对照
### 9.1 workflow-plan 转换示例
**转换前**(命令结构):
```
commands/workflow/
├── plan.md (163 行) ─── 主命令,调用子命令
├── session/
│ └── start.md (202 行) ─── 会话管理
└── tools/
├── context-gather.md (404 行) ─── 上下文收集
├── conflict-resolution.md (604 行) ─── 冲突解决
└── task-generate-agent.md (693 行) ─── 任务生成
```
**转换后**Skill 结构):
```
skills/workflow-plan/
├── SKILL.md (348 行) ─── 编排协调
└── phases/
├── 01-session-discovery.md (281 行)
├── 02-context-gathering.md (427 行)
├── 03-conflict-resolution.md (645 行)
└── 04-task-generation.md (701 行)
```
### 9.2 SKILL.md 与原主命令对比
| 原 plan.md 内容 | SKILL.md 对应位置 |
|----------------|-------------------|
| Frontmatter | Frontmatter (扩展) |
| 执行流程描述 | Execution Flow (可视化) |
| 子命令调用 | Phase Reference Table |
| 数据传递 | Data Flow (显式定义) |
| (无) | TodoWrite Pattern (新增) |
| (无) | Error Handling (新增) |
### 9.3 Phase 文件与原子命令对比
| 原子命令内容 | Phase 文件对应 |
|-------------|---------------|
| Frontmatter | 移除 (Skill 不需要) |
| 步骤说明 | Execution Steps |
| 代码实现 | **完整保留(一致性要求)** |
| Agent Prompt | **完整保留(一致性要求)** |
| 输出格式 | Output Format |
| (无) | Post-Phase Update (新增) |
---
## 附录:快速转换命令
```bash
# 1. 统计原命令行数
wc -l commands/{path}/*.md commands/{path}/**/*.md
# 2. 创建 Skill 目录
mkdir -p skills/{skill-name}/phases
# 3. 转换完成后验证
wc -l skills/{skill-name}/SKILL.md skills/{skill-name}/phases/*.md
# 4. 对比行数差异
# Phase 文件行数应 ≈ 原命令行数 (±20%)
```
---
## 修订历史
| 版本 | 日期 | 变更 |
|------|------|------|
| v1.0 | 2025-02-05 | 基于 workflow-plan 转换实践创建 |
| v1.1 | 2025-02-05 | 强化内容一致性要求添加第7章一致性验证添加应移除的命令特有内容说明 |

View File

@@ -0,0 +1,693 @@
# Phase 3: Conflict Resolution
Detect and resolve conflicts between plan and existing codebase using CLI-powered analysis with Gemini/Qwen.
## Objective
- Analyze conflicts between plan and existing code, **including module scenario uniqueness detection**
- Generate multiple resolution strategies with **iterative clarification until boundaries are clear**
- Apply selected modifications to brainstorm artifacts
**Scope**: Detection and strategy generation only - NO code modification or task creation.
**Trigger**: Auto-executes when `conflict_risk >= medium`.
## Auto Mode
When `--yes` or `-y`: Auto-select recommended strategy for each conflict, skip clarification questions.
## Core Responsibilities
| Responsibility | Description |
|---------------|-------------|
| **Detect Conflicts** | Analyze plan vs existing code inconsistencies |
| **Scenario Uniqueness** | Search and compare new modules with existing modules for functional overlaps |
| **Generate Strategies** | Provide 2-4 resolution options per conflict |
| **Iterative Clarification** | Ask unlimited questions until scenario boundaries are clear and unique |
| **Agent Re-analysis** | Dynamically update strategies based on user clarifications |
| **CLI Analysis** | Use Gemini/Qwen (Claude fallback) |
| **User Decision** | Present options ONE BY ONE, never auto-apply |
| **Direct Text Output** | Output questions via text directly, NEVER use bash echo/printf |
| **Structured Data** | JSON output for programmatic processing, NO file generation |
| **Explicit Lifecycle** | Manage agent lifecycle with spawn_agent → wait → send_input → close_agent |
## Conflict Categories
### 1. Architecture Conflicts
- Incompatible design patterns
- Module structure changes
- Pattern migration requirements
### 2. API Conflicts
- Breaking contract changes
- Signature modifications
- Public interface impacts
### 3. Data Model Conflicts
- Schema modifications
- Type breaking changes
- Data migration needs
### 4. Dependency Conflicts
- Version incompatibilities
- Setup conflicts
- Breaking updates
### 5. Module Scenario Overlap
- Functional overlap between new and existing modules
- Scenario boundary ambiguity
- Duplicate responsibility detection
- Module merge/split decisions
- **Requires iterative clarification until uniqueness confirmed**
## Execution Process
```
Input Parsing:
├─ Parse flags: --session, --context
└─ Validation: Both REQUIRED, conflict_risk >= medium
Phase 1: Validation
├─ Step 1: Verify session directory exists
├─ Step 2: Load context-package.json
├─ Step 3: Check conflict_risk (skip if none/low)
└─ Step 4: Prepare agent task prompt
Phase 2: CLI-Powered Analysis (Agent with Dual Role)
├─ Spawn agent with exploration + planning capability
├─ Execute Gemini analysis (Qwen fallback)
├─ Detect conflicts including ModuleOverlap category
└─ Generate 2-4 strategies per conflict with modifications
Phase 3: Iterative User Interaction (using send_input)
└─ FOR each conflict (one by one):
├─ Display conflict with overlap_analysis (if ModuleOverlap)
├─ Display strategies (2-4 + custom option)
├─ User selects strategy
└─ IF clarification_needed:
├─ Collect answers
├─ send_input for agent re-analysis
└─ Loop until uniqueness_confirmed (max 10 rounds)
Phase 4: Apply Modifications
├─ Step 1: Extract modifications from resolved strategies
├─ Step 2: Apply using Edit tool
├─ Step 3: Update context-package.json (mark resolved)
├─ Step 4: Close agent
└─ Step 5: Output custom conflict summary (if any)
```
## Execution Flow
### Phase 1: Validation
```
1. Verify session directory exists
2. Load context-package.json
3. Check conflict_risk (skip if none/low)
4. Prepare agent task prompt
```
### Phase 2: CLI-Powered Analysis
**Agent Delegation with Dual Role** (enables multi-round interaction):
```javascript
// Spawn agent with combined analysis + resolution capability
const conflictAgentId = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/cli-execution-agent.md (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
## Context
- Session: ${session_id}
- Risk: ${conflict_risk}
- Files: ${existing_files_list}
## Exploration Context (from context-package.exploration_results)
- Exploration Count: ${contextPackage.exploration_results?.exploration_count || 0}
- Angles Analyzed: ${JSON.stringify(contextPackage.exploration_results?.angles || [])}
- Pre-identified Conflict Indicators: ${JSON.stringify(contextPackage.exploration_results?.aggregated_insights?.conflict_indicators || [])}
- Critical Files: ${JSON.stringify(contextPackage.exploration_results?.aggregated_insights?.critical_files?.map(f => f.path) || [])}
- All Patterns: ${JSON.stringify(contextPackage.exploration_results?.aggregated_insights?.all_patterns || [])}
- All Integration Points: ${JSON.stringify(contextPackage.exploration_results?.aggregated_insights?.all_integration_points || [])}
## Analysis Steps
### 0. Load Output Schema (MANDATORY)
Execute: cat ~/.claude/workflows/cli-templates/schemas/conflict-resolution-schema.json
### 1. Load Context
- Read existing files from conflict_detection.existing_files
- Load plan from .workflow/active/${session_id}/.process/context-package.json
- Load exploration_results and use aggregated_insights for enhanced analysis
- Extract role analyses and requirements
### 2. Execute CLI Analysis (Enhanced with Exploration + Scenario Uniqueness)
Primary (Gemini):
ccw cli -p "
PURPOSE: Detect conflicts between plan and codebase, using exploration insights
TASK:
• **Review pre-identified conflict_indicators from exploration results**
• Compare architectures (use exploration key_patterns)
• Identify breaking API changes
• Detect data model incompatibilities
• Assess dependency conflicts
• **Analyze module scenario uniqueness**
- Use exploration integration_points for precise locations
- Cross-validate with exploration critical_files
- Generate clarification questions for boundary definition
MODE: analysis
CONTEXT: @**/*.ts @**/*.js @**/*.tsx @**/*.jsx @.workflow/active/${session_id}/**/*
EXPECTED: Conflict list with severity ratings, including:
- Validation of exploration conflict_indicators
- ModuleOverlap conflicts with overlap_analysis
- Targeted clarification questions
CONSTRAINTS: Focus on breaking changes, migration needs, and functional overlaps | Prioritize exploration-identified conflicts | analysis=READ-ONLY
" --tool gemini --mode analysis --rule analysis-code-patterns --cd ${project_root}
Fallback: Qwen (same prompt) → Claude (manual analysis)
### 3. Generate Strategies (2-4 per conflict)
Template per conflict:
- Severity: Critical/High/Medium
- Category: Architecture/API/Data/Dependency/ModuleOverlap
- Affected files + impact
- **For ModuleOverlap**: Include overlap_analysis with existing modules and scenarios
- Options with pros/cons, effort, risk
- **For ModuleOverlap strategies**: Add clarification_needed questions for boundary definition
- Recommended strategy + rationale
### 4. Return Structured Conflict Data
⚠️ Output to conflict-resolution.json (generated in Phase 4)
**Schema Reference**: Execute \`cat ~/.claude/workflows/cli-templates/schemas/conflict-resolution-schema.json\` to get full schema
Return JSON following the schema above. Key requirements:
- Minimum 2 strategies per conflict, max 4
- All text in Chinese for user-facing fields (brief, name, pros, cons, modification_suggestions)
- modifications.old_content: 20-100 chars for unique Edit tool matching
- modifications.new_content: preserves markdown formatting
- modification_suggestions: 2-5 actionable suggestions for custom handling
### 5. Planning Notes Record (REQUIRED)
After analysis complete, append a brief execution record to planning-notes.md:
**File**: .workflow/active/${session_id}/planning-notes.md
**Location**: Under "## Conflict Decisions (Phase 3)" section
**Format**:
\`\`\`
### [Conflict-Resolution Agent] YYYY-MM-DD
- **Note**: [brief summary of conflict types, resolution strategies, key decisions]
\`\`\`
`
});
// Wait for initial analysis
const analysisResult = wait({
ids: [conflictAgentId],
timeout_ms: 600000 // 10 minutes
});
// Parse conflicts from result
const conflicts = parseConflictsFromResult(analysisResult);
```
### Phase 3: User Interaction Loop
```javascript
const autoYes = $ARGUMENTS.includes('--yes') || $ARGUMENTS.includes('-y')
FOR each conflict:
round = 0, clarified = false, userClarifications = []
WHILE (!clarified && round++ < 10):
// 1. Display conflict info (text output for context)
displayConflictSummary(conflict) // id, brief, severity, overlap_analysis if ModuleOverlap
// 2. Strategy selection
if (autoYes) {
console.log(`[--yes] Auto-selecting recommended strategy`)
selectedStrategy = conflict.strategies[conflict.recommended || 0]
clarified = true // Skip clarification loop
} else {
AskUserQuestion({
questions: [{
question: formatStrategiesForDisplay(conflict.strategies),
header: "策略选择",
multiSelect: false,
options: [
...conflict.strategies.map((s, i) => ({
label: `${s.name}${i === conflict.recommended ? ' (推荐)' : ''}`,
description: `${s.complexity}复杂度 | ${s.risk}风险${s.clarification_needed?.length ? ' | ⚠️需澄清' : ''}`
})),
{ label: "自定义修改", description: `建议: ${conflict.modification_suggestions?.slice(0,2).join('; ')}` }
]
}]
})
// 3. Handle selection
if (userChoice === "自定义修改") {
customConflicts.push({ id, brief, category, suggestions, overlap_analysis })
break
}
selectedStrategy = findStrategyByName(userChoice)
}
// 4. Clarification (if needed) - using send_input for agent re-analysis
if (!autoYes && selectedStrategy.clarification_needed?.length > 0) {
for (batch of chunk(selectedStrategy.clarification_needed, 4)) {
AskUserQuestion({
questions: batch.map((q, i) => ({
question: q, header: `澄清${i+1}`, multiSelect: false,
options: [{ label: "详细说明", description: "提供答案" }]
}))
})
userClarifications.push(...collectAnswers(batch))
}
// 5. Agent re-analysis via send_input (key: agent stays active)
send_input({
id: conflictAgentId,
message: `
## CLARIFICATION ANSWERS
Conflict: ${conflict.id}
Strategy: ${selectedStrategy.name}
User Clarifications: ${JSON.stringify(userClarifications)}
## REQUEST
Based on the clarifications above, update the strategy assessment.
Output: { uniqueness_confirmed: boolean, rationale: string, updated_strategy: {...}, remaining_questions: [...] }
`
});
// Wait for re-analysis result
const reanalysisResult = wait({
ids: [conflictAgentId],
timeout_ms: 300000 // 5 minutes
});
const parsedResult = parseReanalysisResult(reanalysisResult);
if (parsedResult.uniqueness_confirmed) {
selectedStrategy = { ...parsedResult.updated_strategy, clarifications: userClarifications }
clarified = true
} else {
selectedStrategy.clarification_needed = parsedResult.remaining_questions
}
} else {
clarified = true
}
if (clarified) resolvedConflicts.push({ conflict, strategy: selectedStrategy })
END WHILE
END FOR
selectedStrategies = resolvedConflicts.map(r => ({
conflict_id: r.conflict.id, strategy: r.strategy, clarifications: r.strategy.clarifications || []
}))
```
**Key Points**:
- AskUserQuestion: max 4 questions/call, batch if more
- Strategy options: 2-4 strategies + "自定义修改"
- Clarification loop via send_input: max 10 rounds, agent判断 uniqueness_confirmed
- Agent stays active throughout interaction (no close_agent until Phase 4 complete)
- Custom conflicts: 记录 overlap_analysis 供后续手动处理
### Phase 4: Apply Modifications
```javascript
// 1. Extract modifications from resolved strategies
const modifications = [];
selectedStrategies.forEach(item => {
if (item.strategy && item.strategy.modifications) {
modifications.push(...item.strategy.modifications.map(mod => ({
...mod,
conflict_id: item.conflict_id,
clarifications: item.clarifications
})));
}
});
console.log(`\n正在应用 ${modifications.length} 个修改...`);
// 2. Apply each modification using Edit tool (with fallback to context-package.json)
const appliedModifications = [];
const failedModifications = [];
const fallbackConstraints = []; // For files that don't exist
modifications.forEach((mod, idx) => {
try {
console.log(`[${idx + 1}/${modifications.length}] 修改 ${mod.file}...`);
// Check if target file exists (brainstorm files may not exist in lite workflow)
if (!file_exists(mod.file)) {
console.log(` ⚠️ 文件不存在,写入 context-package.json 作为约束`);
fallbackConstraints.push({
source: "conflict-resolution",
conflict_id: mod.conflict_id,
target_file: mod.file,
section: mod.section,
change_type: mod.change_type,
content: mod.new_content,
rationale: mod.rationale
});
return; // Skip to next modification
}
if (mod.change_type === "update") {
Edit({
file_path: mod.file,
old_string: mod.old_content,
new_string: mod.new_content
});
} else if (mod.change_type === "add") {
// Handle addition - append or insert based on section
const fileContent = Read(mod.file);
const updated = insertContentAfterSection(fileContent, mod.section, mod.new_content);
Write(mod.file, updated);
} else if (mod.change_type === "remove") {
Edit({
file_path: mod.file,
old_string: mod.old_content,
new_string: ""
});
}
appliedModifications.push(mod);
console.log(` ✓ 成功`);
} catch (error) {
console.log(` ✗ 失败: ${error.message}`);
failedModifications.push({ ...mod, error: error.message });
}
});
// 2b. Generate conflict-resolution.json output file
const resolutionOutput = {
session_id: sessionId,
resolved_at: new Date().toISOString(),
summary: {
total_conflicts: conflicts.length,
resolved_with_strategy: selectedStrategies.length,
custom_handling: customConflicts.length,
fallback_constraints: fallbackConstraints.length
},
resolved_conflicts: selectedStrategies.map(s => ({
conflict_id: s.conflict_id,
strategy_name: s.strategy.name,
strategy_approach: s.strategy.approach,
clarifications: s.clarifications || [],
modifications_applied: s.strategy.modifications?.filter(m =>
appliedModifications.some(am => am.conflict_id === s.conflict_id)
) || []
})),
custom_conflicts: customConflicts.map(c => ({
id: c.id,
brief: c.brief,
category: c.category,
suggestions: c.suggestions,
overlap_analysis: c.overlap_analysis || null
})),
planning_constraints: fallbackConstraints, // Constraints for files that don't exist
failed_modifications: failedModifications
};
const resolutionPath = `.workflow/active/${sessionId}/.process/conflict-resolution.json`;
Write(resolutionPath, JSON.stringify(resolutionOutput, null, 2));
// 3. Update context-package.json with resolution details (reference to JSON file)
const contextPackage = JSON.parse(Read(contextPath));
contextPackage.conflict_detection.conflict_risk = "resolved";
contextPackage.conflict_detection.resolution_file = resolutionPath; // Reference to detailed JSON
contextPackage.conflict_detection.resolved_conflicts = selectedStrategies.map(s => s.conflict_id);
contextPackage.conflict_detection.custom_conflicts = customConflicts.map(c => c.id);
contextPackage.conflict_detection.resolved_at = new Date().toISOString();
Write(contextPath, JSON.stringify(contextPackage, null, 2));
// 4. Close the conflict agent (IMPORTANT: explicit lifecycle management)
close_agent({ id: conflictAgentId });
// 5. Output custom conflict summary with overlap analysis (if any)
if (customConflicts.length > 0) {
console.log(`\n${'='.repeat(60)}`);
console.log(`需要自定义处理的冲突 (${customConflicts.length})`);
console.log(`${'='.repeat(60)}\n`);
customConflicts.forEach(conflict => {
console.log(`${conflict.category}${conflict.id}: ${conflict.brief}`);
// Show overlap analysis for ModuleOverlap conflicts
if (conflict.category === 'ModuleOverlap' && conflict.overlap_analysis) {
console.log(`\n场景重叠信息:`);
console.log(` 新模块: ${conflict.overlap_analysis.new_module.name}`);
console.log(` 场景: ${conflict.overlap_analysis.new_module.scenarios.join(', ')}`);
console.log(`\n 与以下模块重叠:`);
conflict.overlap_analysis.existing_modules.forEach(mod => {
console.log(` - ${mod.name} (${mod.file})`);
console.log(` 重叠场景: ${mod.overlap_scenarios.join(', ')}`);
});
}
console.log(`\n修改建议:`);
conflict.suggestions.forEach(suggestion => {
console.log(` - ${suggestion}`);
});
console.log();
});
}
// 6. Output failure summary (if any)
if (failedModifications.length > 0) {
console.log(`\n⚠️ 部分修改失败 (${failedModifications.length}):`);
failedModifications.forEach(mod => {
console.log(` - ${mod.file}: ${mod.error}`);
});
}
// 7. Return summary
return {
total_conflicts: conflicts.length,
resolved_with_strategy: selectedStrategies.length,
custom_handling: customConflicts.length,
modifications_applied: appliedModifications.length,
modifications_failed: failedModifications.length,
modified_files: [...new Set(appliedModifications.map(m => m.file))],
custom_conflicts: customConflicts,
clarification_records: selectedStrategies.filter(s => s.clarifications.length > 0)
};
```
**Validation**:
```
✓ Agent returns valid JSON structure with ModuleOverlap conflicts
✓ Conflicts processed ONE BY ONE (not in batches)
✓ ModuleOverlap conflicts include overlap_analysis field
✓ Strategies with clarification_needed display questions
✓ User selections captured correctly per conflict
✓ Clarification loop continues until uniqueness confirmed via send_input
✓ Agent re-analysis with user clarifications updates strategy
✓ Uniqueness confirmation based on clear scenario boundaries
✓ Maximum 10 rounds per conflict safety limit enforced
✓ Edit tool successfully applies modifications
✓ guidance-specification.md updated
✓ Role analyses (*.md) updated
✓ context-package.json marked as resolved with clarification records
✓ Custom conflicts display overlap_analysis for manual handling
✓ Agent closed after all interactions complete (explicit lifecycle)
✓ Agent log saved to .workflow/active/{session_id}/.chat/
```
## Output Format
### Primary Output: conflict-resolution.json
**Path**: `.workflow/active/{session_id}/.process/conflict-resolution.json`
**Schema**:
```json
{
"session_id": "WFS-xxx",
"resolved_at": "ISO timestamp",
"summary": {
"total_conflicts": 3,
"resolved_with_strategy": 2,
"custom_handling": 1,
"fallback_constraints": 0
},
"resolved_conflicts": [
{
"conflict_id": "CON-001",
"strategy_name": "策略名称",
"strategy_approach": "实现方法",
"clarifications": [],
"modifications_applied": []
}
],
"custom_conflicts": [
{
"id": "CON-002",
"brief": "冲突摘要",
"category": "ModuleOverlap",
"suggestions": ["建议1", "建议2"],
"overlap_analysis": null
}
],
"planning_constraints": [],
"failed_modifications": []
}
```
### Key Requirements
| Requirement | Details |
|------------|---------|
| **Conflict batching** | Max 10 conflicts per round (no total limit) |
| **Strategy count** | 2-4 strategies per conflict |
| **Modifications** | Each strategy includes file paths, old_content, new_content |
| **User-facing text** | Chinese (brief, strategy names, pros/cons) |
| **Technical fields** | English (severity, category, complexity, risk) |
| **old_content precision** | 20-100 chars for unique Edit tool matching |
| **File targets** | guidance-specification.md, role analyses (*.md) |
| **Agent lifecycle** | Keep active during interaction, close after Phase 4 |
## Error Handling
### Recovery Strategy
```
1. Pre-check: Verify conflict_risk ≥ medium
2. Monitor: Track agent via wait with timeout
3. Validate: Parse agent JSON output
4. Recover:
- Agent failure → check logs + report error
- Invalid JSON → retry once with Claude fallback
- CLI failure → fallback to Claude analysis
- Edit tool failure → report affected files + rollback option
- User cancels → mark as "unresolved", continue to task-generate
5. Degrade: If all fail, generate minimal conflict report and skip modifications
6. Cleanup: Always close_agent even on error path
```
### Rollback Handling
```
If Edit tool fails mid-application:
1. Log all successfully applied modifications
2. Output rollback option via text interaction
3. If rollback selected: restore files from git or backups
4. If continue: mark partial resolution in context-package.json
```
## Integration
### Interface
**Input**:
- `--session` (required): WFS-{session-id}
- `--context` (required): context-package.json path
- Requires: `conflict_risk >= medium`
**Output**:
- Generated file:
- `.workflow/active/{session_id}/.process/conflict-resolution.json` (primary output)
- Modified files (if exist):
- `.workflow/active/{session_id}/.brainstorm/guidance-specification.md`
- `.workflow/active/{session_id}/.brainstorm/{role}/analysis.md`
- `.workflow/active/{session_id}/.process/context-package.json` (conflict_risk → resolved, resolution_file reference)
**User Interaction**:
- **Iterative conflict processing**: One conflict at a time, not in batches
- Each conflict: 2-4 strategy options + "自定义修改" option (with suggestions)
- **Clarification loop via send_input**: Unlimited questions per conflict until uniqueness confirmed (max 10 rounds)
- **ModuleOverlap conflicts**: Display overlap_analysis with existing modules
- **Agent re-analysis**: Dynamic strategy updates based on user clarifications
### Success Criteria
```
✓ CLI analysis returns valid JSON structure with ModuleOverlap category
✓ Agent performs scenario uniqueness detection (searches existing modules)
✓ Conflicts processed ONE BY ONE with iterative clarification via send_input
✓ Min 2 strategies per conflict with modifications
✓ ModuleOverlap conflicts include overlap_analysis with existing modules
✓ Strategies requiring clarification include clarification_needed questions
✓ Each conflict includes 2-5 modification_suggestions
✓ Text output displays conflict with overlap analysis (if ModuleOverlap)
✓ User selections captured per conflict
✓ Clarification loop continues until uniqueness confirmed (unlimited rounds, max 10)
✓ Agent re-analysis with user clarifications updates strategy
✓ Uniqueness confirmation based on clear scenario boundaries
✓ Edit tool applies modifications successfully
✓ Custom conflicts displayed with overlap_analysis for manual handling
✓ guidance-specification.md updated with resolved conflicts
✓ Role analyses (*.md) updated with resolved conflicts
✓ context-package.json marked as "resolved" with clarification records
✓ conflict-resolution.json generated with full resolution details
✓ Agent explicitly closed after all interactions
✓ Modification summary includes:
- Total conflicts
- Resolved with strategy (count)
- Custom handling (count)
- Clarification records
- Overlap analysis for custom ModuleOverlap conflicts
✓ Agent log saved to .workflow/active/{session_id}/.chat/
✓ Error handling robust (validate/retry/degrade)
```
## Post-Phase Update
If Phase 3 was executed, update planning-notes.md:
```javascript
const conflictResPath = `.workflow/active/${sessionId}/.process/conflict-resolution.json`
if (file_exists(conflictResPath)) {
const conflictRes = JSON.parse(Read(conflictResPath))
const resolved = conflictRes.resolved_conflicts || []
const planningConstraints = conflictRes.planning_constraints || []
// Update Phase 3 section
Edit(planningNotesPath, {
old: '## Conflict Decisions (Phase 3)\n(To be filled if conflicts detected)',
new: `## Conflict Decisions (Phase 3)
- **RESOLVED**: ${resolved.map(r => `${r.conflict_id}${r.strategy_name}`).join('; ') || 'None'}
- **CUSTOM_HANDLING**: ${conflictRes.custom_conflicts?.map(c => c.id).join(', ') || 'None'}
- **CONSTRAINTS**: ${planningConstraints.map(c => c.content).join('; ') || 'None'}`
})
// Append Phase 3 constraints to consolidated list
if (planningConstraints.length > 0) {
Edit(planningNotesPath, {
old: '## Consolidated Constraints (Phase 4 Input)',
new: `## Consolidated Constraints (Phase 4 Input)
${planningConstraints.map((c, i) => `${constraintCount + i + 1}. [Conflict] ${c.content}`).join('\n')}`
})
}
}
```
## Memory State Check
After Phase 3 completion, evaluate context window usage.
If memory usage is high (>120K tokens):
```javascript
// Codex: Use compact command if available
codex compact
```
## Output
- **File**: `.workflow/active/{sessionId}/.process/conflict-resolution.json`
- **Modified files**: brainstorm artifacts (guidance-specification.md, role analyses)
- **Updated**: `context-package.json` with resolved conflict status
## Next Phase
Return to orchestrator, then auto-continue to [Phase 4: Task Generation](04-task-generation.md).

View File

@@ -0,0 +1,756 @@
# Phase 4: Task Generation
Generate implementation plan documents (IMPL_PLAN.md, task JSONs, TODO_LIST.md) using action-planning-agent - produces planning artifacts, does NOT execute code implementation.
## Auto Mode
When `--yes` or `-y`: Skip user questions, use defaults (no materials, Agent executor, Codex CLI tool).
## Core Philosophy
- **Planning Only**: Generate planning documents (IMPL_PLAN.md, task JSONs, TODO_LIST.md) - does NOT implement code
- **Agent-Driven Document Generation**: Delegate plan generation to action-planning-agent
- **NO Redundant Context Sorting**: Context priority sorting is ALREADY completed in context-gather Phase 2/3
- Use `context-package.json.prioritized_context` directly
- DO NOT re-sort files or re-compute priorities
- `priority_tiers` and `dependency_order` are pre-computed and ready-to-use
- **N+1 Parallel Planning**: Auto-detect multi-module projects, enable parallel planning (2+1 or 3+1 mode)
- **Progressive Loading**: Load context incrementally (Core → Selective → On-Demand) due to analysis.md file size
- **Memory-First**: Reuse loaded documents from conversation memory
- **Smart Selection**: Load synthesis_output OR guidance + relevant role analyses, NOT all role analyses
- **MCP-Enhanced**: Use MCP tools for advanced code analysis and research
- **Path Clarity**: All `focus_paths` prefer absolute paths (e.g., `D:\\project\\src\\module`), or clear relative paths from project root (e.g., `./src/module`)
- **Explicit Lifecycle**: Manage subagent lifecycle with spawn_agent → wait → close_agent
## Execution Process
```
Input Parsing:
├─ Parse flags: --session
└─ Validation: session_id REQUIRED
Phase 0: User Configuration (Interactive)
├─ Question 1: Supplementary materials/guidelines?
├─ Question 2: Execution method preference (Agent/CLI/Hybrid)
├─ Question 3: CLI tool preference (if CLI selected)
└─ Store: userConfig for agent prompt
Phase 1: Context Preparation & Module Detection (Command)
├─ Assemble session paths (metadata, context package, output dirs)
├─ Provide metadata (session_id, execution_mode, mcp_capabilities)
├─ Auto-detect modules from context-package + directory structure
└─ Decision:
├─ modules.length == 1 → Single Agent Mode (Phase 2A)
└─ modules.length >= 2 → Parallel Mode (Phase 2B + Phase 3)
Phase 2A: Single Agent Planning (Original Flow)
├─ Spawn action-planning-agent
├─ Wait for completion
├─ Close agent
├─ Outputs: Task JSONs, IMPL_PLAN.md, TODO_LIST.md
└─ Lifecycle: spawn_agent → wait → close_agent
Phase 2B: N Parallel Planning (Multi-Module)
├─ Spawn N action-planning-agents simultaneously (one per module)
├─ Wait for all agents (batch wait)
├─ Close all agents
├─ Each generates module-scoped tasks (IMPL-{prefix}{seq}.json)
├─ Task ID format: IMPL-A1, IMPL-A2... / IMPL-B1, IMPL-B2...
└─ Each module limited to ≤9 tasks
Phase 3: Integration (+1 Coordinator, Multi-Module Only)
├─ Spawn coordinator agent
├─ Wait for completion
├─ Close agent
├─ Collect all module task JSONs
├─ Resolve cross-module dependencies (CROSS::{module}::{pattern} → actual ID)
├─ Generate unified IMPL_PLAN.md (grouped by module)
└─ Generate TODO_LIST.md (hierarchical: module → tasks)
```
## Document Generation Lifecycle
### Phase 0: User Configuration (Interactive)
**Purpose**: Collect user preferences before task generation to ensure generated tasks match execution expectations.
**Auto Mode Check**:
```javascript
const autoYes = $ARGUMENTS.includes('--yes') || $ARGUMENTS.includes('-y')
if (autoYes) {
console.log(`[--yes] Using defaults: No materials, Agent executor, Codex CLI`)
userConfig = {
supplementaryMaterials: { type: "none", content: [] },
executionMethod: "agent",
preferredCliTool: "codex",
enableResume: true
}
// Skip to Phase 1
}
```
**User Questions** (skipped if autoYes):
```javascript
if (!autoYes) AskUserQuestion({
questions: [
{
question: "Do you have supplementary materials or guidelines to include?",
header: "Materials",
multiSelect: false,
options: [
{ label: "No additional materials", description: "Use existing context only" },
{ label: "Provide file paths", description: "I'll specify paths to include" },
{ label: "Provide inline content", description: "I'll paste content directly" }
]
},
{
question: "Select execution method for generated tasks:",
header: "Execution",
multiSelect: false,
options: [
{ label: "Agent (Recommended)", description: "Claude agent executes tasks directly" },
{ label: "Hybrid", description: "Agent orchestrates, calls CLI for complex steps" },
{ label: "CLI Only", description: "All execution via CLI tools (codex/gemini/qwen)" }
]
},
{
question: "If using CLI, which tool do you prefer?",
header: "CLI Tool",
multiSelect: false,
options: [
{ label: "Codex (Recommended)", description: "Best for implementation tasks" },
{ label: "Gemini", description: "Best for analysis and large context" },
{ label: "Qwen", description: "Alternative analysis tool" },
{ label: "Auto", description: "Let agent decide per-task" }
]
}
]
})
```
**Handle Materials Response** (skipped if autoYes):
```javascript
if (!autoYes && userConfig.materials === "Provide file paths") {
// Follow-up question for file paths
const pathsResponse = AskUserQuestion({
questions: [{
question: "Enter file paths to include (comma-separated or one per line):",
header: "Paths",
multiSelect: false,
options: [
{ label: "Enter paths", description: "Provide paths in text input" }
]
}]
})
userConfig.supplementaryPaths = parseUserPaths(pathsResponse)
}
```
**Build userConfig**:
```javascript
const userConfig = {
supplementaryMaterials: {
type: "none|paths|inline",
content: [...], // Parsed paths or inline content
},
executionMethod: "agent|hybrid|cli",
preferredCliTool: "codex|gemini|qwen|auto",
enableResume: true // Always enable resume for CLI executions
}
```
**Pass to Agent**: Include `userConfig` in agent prompt for Phase 2A/2B.
### Phase 1: Context Preparation & Module Detection (Command Responsibility)
**Command prepares session paths, metadata, detects module structure. Context priority sorting is NOT performed here - it's already completed in context-gather Phase 2/3.**
**Session Path Structure**:
```
.workflow/active/WFS-{session-id}/
├── workflow-session.json # Session metadata
├── planning-notes.md # Consolidated planning notes
├── .process/
│ └── context-package.json # Context package with artifact catalog
├── .task/ # Output: Task JSON files
│ ├── IMPL-A1.json # Multi-module: prefixed by module
│ ├── IMPL-A2.json
│ ├── IMPL-B1.json
│ └── ...
├── IMPL_PLAN.md # Output: Implementation plan (grouped by module)
└── TODO_LIST.md # Output: TODO list (hierarchical)
```
**Command Preparation**:
1. **Assemble Session Paths** for agent prompt:
- `session_metadata_path`
- `context_package_path`
- Output directory paths
2. **Provide Metadata** (simple values):
- `session_id`
- `mcp_capabilities` (available MCP tools)
3. **Auto Module Detection** (determines single vs parallel mode):
```javascript
function autoDetectModules(contextPackage, projectRoot) {
// === Complexity Gate: Only parallelize for High complexity ===
const complexity = contextPackage.metadata?.complexity || 'Medium';
if (complexity !== 'High') {
// Force single agent mode for Low/Medium complexity
// This maximizes agent context reuse for related tasks
return [{ name: 'main', prefix: '', paths: ['.'] }];
}
// Priority 1: Explicit frontend/backend separation
if (exists('src/frontend') && exists('src/backend')) {
return [
{ name: 'frontend', prefix: 'A', paths: ['src/frontend'] },
{ name: 'backend', prefix: 'B', paths: ['src/backend'] }
];
}
// Priority 2: Monorepo structure
if (exists('packages/*') || exists('apps/*')) {
return detectMonorepoModules(); // Returns 2-3 main packages
}
// Priority 3: Context-package dependency clustering
const modules = clusterByDependencies(contextPackage.dependencies?.internal);
if (modules.length >= 2) return modules.slice(0, 3);
// Default: Single module (original flow)
return [{ name: 'main', prefix: '', paths: ['.'] }];
}
```
**Decision Logic**:
- `complexity !== 'High'` → Force Phase 2A (Single Agent, maximize context reuse)
- `modules.length == 1` → Phase 2A (Single Agent, original flow)
- `modules.length >= 2 && complexity == 'High'` → Phase 2B + Phase 3 (N+1 Parallel)
**Note**: CLI tool usage is now determined semantically by action-planning-agent based on user's task description, not by flags.
### Phase 2A: Single Agent Planning (Original Flow)
**Condition**: `modules.length == 1` (no multi-module detected)
**Purpose**: Generate IMPL_PLAN.md, task JSONs, and TODO_LIST.md - planning documents only, NOT code implementation.
**Agent Invocation**:
```javascript
// Spawn action-planning-agent
const planningAgentId = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/action-planning-agent.md (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
## TASK OBJECTIVE
Generate implementation planning documents (IMPL_PLAN.md, task JSONs, TODO_LIST.md) for workflow session
IMPORTANT: This is PLANNING ONLY - you are generating planning documents, NOT implementing code.
CRITICAL: Follow the progressive loading strategy defined in agent specification (load analysis.md files incrementally due to file size)
## PLANNING NOTES (PHASE 1-3 CONTEXT)
Load: .workflow/active/${session_id}/planning-notes.md
This document contains:
- User Intent: Original GOAL and KEY_CONSTRAINTS from Phase 1
- Context Findings: Critical files, architecture, and constraints from Phase 2
- Conflict Decisions: Resolved conflicts and planning constraints from Phase 3
- Consolidated Constraints: All constraints from all phases
**USAGE**: Read planning-notes.md FIRST. Use Consolidated Constraints list to guide task sequencing and dependencies.
## SESSION PATHS
Input:
- Session Metadata: .workflow/active/${session_id}/workflow-session.json
- Planning Notes: .workflow/active/${session_id}/planning-notes.md
- Context Package: .workflow/active/${session_id}/.process/context-package.json
Output:
- Task Dir: .workflow/active/${session_id}/.task/
- IMPL_PLAN: .workflow/active/${session_id}/IMPL_PLAN.md
- TODO_LIST: .workflow/active/${session_id}/TODO_LIST.md
## CONTEXT METADATA
Session ID: ${session_id}
MCP Capabilities: {exa_code, exa_web, code_index}
## USER CONFIGURATION (from Phase 0)
Execution Method: ${userConfig.executionMethod} // agent|hybrid|cli
Preferred CLI Tool: ${userConfig.preferredCliTool} // codex|gemini|qwen|auto
Supplementary Materials: ${userConfig.supplementaryMaterials}
## EXECUTION METHOD MAPPING
Based on userConfig.executionMethod, set task-level meta.execution_config:
"agent" →
meta.execution_config = { method: "agent", cli_tool: null, enable_resume: false }
Agent executes implementation_approach steps directly
"cli" →
meta.execution_config = { method: "cli", cli_tool: userConfig.preferredCliTool, enable_resume: true }
Agent executes pre_analysis, then hands off full context to CLI via buildCliHandoffPrompt()
"hybrid" →
Per-task decision: Analyze task complexity, set method to "agent" OR "cli" per task
- Simple tasks (≤3 files, straightforward logic) → method: "agent"
- Complex tasks (>3 files, complex logic, refactoring) → method: "cli"
CLI tool: userConfig.preferredCliTool, enable_resume: true
IMPORTANT: Do NOT add command field to implementation_approach steps. Execution routing is controlled by task-level meta.execution_config.method only.
## PRIORITIZED CONTEXT (from context-package.prioritized_context) - ALREADY SORTED
Context sorting is ALREADY COMPLETED in context-gather Phase 2/3. DO NOT re-sort.
Direct usage:
- **user_intent**: Use goal/scope/key_constraints for task alignment
- **priority_tiers.critical**: These files are PRIMARY focus for task generation
- **priority_tiers.high**: These files are SECONDARY focus
- **dependency_order**: Use this for task sequencing - already computed
- **sorting_rationale**: Reference for understanding priority decisions
## EXPLORATION CONTEXT (from context-package.exploration_results) - SUPPLEMENT ONLY
If prioritized_context is incomplete, fall back to exploration_results:
- Load exploration_results from context-package.json
- Use aggregated_insights.critical_files for focus_paths generation
- Apply aggregated_insights.constraints to acceptance criteria
- Reference aggregated_insights.all_patterns for implementation approach
- Use aggregated_insights.all_integration_points for precise modification locations
- Use conflict_indicators for risk-aware task sequencing
## CONFLICT RESOLUTION CONTEXT (if exists)
- Check context-package.conflict_detection.resolution_file for conflict-resolution.json path
- If exists, load .process/conflict-resolution.json:
- Apply planning_constraints as task constraints (for brainstorm-less workflows)
- Reference resolved_conflicts for implementation approach alignment
- Handle custom_conflicts with explicit task notes
## EXPECTED DELIVERABLES
1. Task JSON Files (.task/IMPL-*.json)
- 6-field schema (id, title, status, context_package_path, meta, context, flow_control)
- Quantified requirements with explicit counts
- Artifacts integration from context package
- **focus_paths generated directly from prioritized_context.priority_tiers (critical + high)**
- NO re-sorting or re-prioritization - use pre-computed tiers as-is
- Critical files are PRIMARY focus, High files are SECONDARY
- Flow control with pre_analysis steps (use prioritized_context.dependency_order for task sequencing)
- **CLI Execution IDs and strategies (MANDATORY)**
2. Implementation Plan (IMPL_PLAN.md)
- Context analysis and artifact references
- Task breakdown and execution strategy
- Complete structure per agent definition
3. TODO List (TODO_LIST.md)
- Hierarchical structure (containers, pending, completed markers)
- Links to task JSONs and summaries
- Matches task JSON hierarchy
## CLI EXECUTION ID REQUIREMENTS (MANDATORY)
Each task JSON MUST include:
- **cli_execution_id**: Unique ID for CLI execution (format: \`{session_id}-{task_id}\`)
- **cli_execution**: Strategy object based on depends_on:
- No deps → \`{ "strategy": "new" }\`
- 1 dep (single child) → \`{ "strategy": "resume", "resume_from": "parent-cli-id" }\`
- 1 dep (multiple children) → \`{ "strategy": "fork", "resume_from": "parent-cli-id" }\`
- N deps → \`{ "strategy": "merge_fork", "merge_from": ["id1", "id2", ...] }\`
**CLI Execution Strategy Rules**:
1. **new**: Task has no dependencies - starts fresh CLI conversation
2. **resume**: Task has 1 parent AND that parent has only this child - continues same conversation
3. **fork**: Task has 1 parent BUT parent has multiple children - creates new branch with parent context
4. **merge_fork**: Task has multiple parents - merges all parent contexts into new conversation
**Execution Command Patterns**:
- new: \`ccw cli -p "[prompt]" --tool [tool] --mode write --id [cli_execution_id]\`
- resume: \`ccw cli -p "[prompt]" --resume [resume_from] --tool [tool] --mode write\`
- fork: \`ccw cli -p "[prompt]" --resume [resume_from] --id [cli_execution_id] --tool [tool] --mode write\`
- merge_fork: \`ccw cli -p "[prompt]" --resume [merge_from.join(',')] --id [cli_execution_id] --tool [tool] --mode write\`
## QUALITY STANDARDS
Hard Constraints:
- Task count <= 18 (hard limit - request re-scope if exceeded)
- All requirements quantified (explicit counts and enumerated lists)
- Acceptance criteria measurable (include verification commands)
- Artifact references mapped from context package
- All documents follow agent-defined structure
## SUCCESS CRITERIA
- All planning documents generated successfully:
- Task JSONs valid and saved to .task/ directory
- IMPL_PLAN.md created with complete structure
- TODO_LIST.md generated matching task JSONs
- Return completion status with document count and task breakdown summary
## PLANNING NOTES RECORD (REQUIRED)
After completing, update planning-notes.md:
**File**: .workflow/active/${session_id}/planning-notes.md
1. **Task Generation (Phase 4)**: Task count and key tasks
2. **N+1 Context**: Key decisions (with rationale) + deferred items
\`\`\`markdown
## Task Generation (Phase 4)
### [Action-Planning Agent] YYYY-MM-DD
- **Tasks**: [count] ([IDs])
## N+1 Context
### Decisions
| Decision | Rationale | Revisit? |
|----------|-----------|----------|
| [choice] | [why] | [Yes/No] |
### Deferred
- [ ] [item] - [reason]
\`\`\`
`
});
// Wait for planning agent to complete
const planningResult = wait({
ids: [planningAgentId],
timeout_ms: 900000 // 15 minutes
});
// Close planning agent
close_agent({ id: planningAgentId });
```
### Phase 2B: N Parallel Planning (Multi-Module)
**Condition**: `modules.length >= 2` (multi-module detected)
**Purpose**: Launch N action-planning-agents simultaneously, one per module, for parallel task JSON generation.
**Note**: Phase 2B agents generate Task JSONs ONLY. IMPL_PLAN.md and TODO_LIST.md are generated by Phase 3 Coordinator.
**Parallel Agent Invocation**:
```javascript
// Spawn N agents in parallel (one per module)
const moduleAgents = [];
modules.forEach(module => {
const agentId = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/action-planning-agent.md (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
## TASK OBJECTIVE
Generate task JSON files for ${module.name} module within workflow session
IMPORTANT: This is PLANNING ONLY - generate task JSONs, NOT implementing code.
IMPORTANT: Generate Task JSONs ONLY. IMPL_PLAN.md and TODO_LIST.md by Phase 3 Coordinator.
CRITICAL: Follow the progressive loading strategy defined in agent specification (load analysis.md files incrementally due to file size)
## PLANNING NOTES (PHASE 1-3 CONTEXT)
Load: .workflow/active/${session_id}/planning-notes.md
This document contains consolidated constraints and user intent to guide module-scoped task generation.
## MODULE SCOPE
- Module: ${module.name} (${module.type})
- Focus Paths: ${module.paths.join(', ')}
- Task ID Prefix: IMPL-${module.prefix}
- Task Limit: ≤6 tasks (hard limit for this module)
- Other Modules: ${otherModules.join(', ')} (reference only, do NOT generate tasks for them)
## SESSION PATHS
Input:
- Session Metadata: .workflow/active/${session_id}/workflow-session.json
- Planning Notes: .workflow/active/${session_id}/planning-notes.md
- Context Package: .workflow/active/${session_id}/.process/context-package.json
Output:
- Task Dir: .workflow/active/${session_id}/.task/
## CONTEXT METADATA
Session ID: ${session_id}
MCP Capabilities: {exa_code, exa_web, code_index}
## USER CONFIGURATION (from Phase 0)
Execution Method: ${userConfig.executionMethod} // agent|hybrid|cli
Preferred CLI Tool: ${userConfig.preferredCliTool} // codex|gemini|qwen|auto
Supplementary Materials: ${userConfig.supplementaryMaterials}
## EXECUTION METHOD MAPPING
Based on userConfig.executionMethod, set task-level meta.execution_config:
"agent" →
meta.execution_config = { method: "agent", cli_tool: null, enable_resume: false }
Agent executes implementation_approach steps directly
"cli" →
meta.execution_config = { method: "cli", cli_tool: userConfig.preferredCliTool, enable_resume: true }
Agent executes pre_analysis, then hands off full context to CLI via buildCliHandoffPrompt()
"hybrid" →
Per-task decision: Analyze task complexity, set method to "agent" OR "cli" per task
- Simple tasks (≤3 files, straightforward logic) → method: "agent"
- Complex tasks (>3 files, complex logic, refactoring) → method: "cli"
CLI tool: userConfig.preferredCliTool, enable_resume: true
IMPORTANT: Do NOT add command field to implementation_approach steps. Execution routing is controlled by task-level meta.execution_config.method only.
## PRIORITIZED CONTEXT (from context-package.prioritized_context) - ALREADY SORTED
Context sorting is ALREADY COMPLETED in context-gather Phase 2/3. DO NOT re-sort.
Filter by module scope (${module.paths.join(', ')}):
- **user_intent**: Use for task alignment within module
- **priority_tiers.critical**: Filter for files in ${module.paths.join(', ')} → PRIMARY focus
- **priority_tiers.high**: Filter for files in ${module.paths.join(', ')} → SECONDARY focus
- **dependency_order**: Use module-relevant entries for task sequencing
## EXPLORATION CONTEXT (from context-package.exploration_results) - SUPPLEMENT ONLY
If prioritized_context is incomplete for this module, fall back to exploration_results:
- Load exploration_results from context-package.json
- Filter for ${module.name} module: Use aggregated_insights.critical_files matching ${module.paths.join(', ')}
- Apply module-relevant constraints from aggregated_insights.constraints
- Reference aggregated_insights.all_patterns applicable to ${module.name}
- Use aggregated_insights.all_integration_points for precise modification locations within module scope
- Use conflict_indicators for risk-aware task sequencing
## CONFLICT RESOLUTION CONTEXT (if exists)
- Check context-package.conflict_detection.resolution_file for conflict-resolution.json path
- If exists, load .process/conflict-resolution.json:
- Apply planning_constraints relevant to ${module.name} as task constraints
- Reference resolved_conflicts affecting ${module.name} for implementation approach alignment
- Handle custom_conflicts with explicit task notes
## CROSS-MODULE DEPENDENCIES
- For dependencies ON other modules: Use placeholder depends_on: ["CROSS::{module}::{pattern}"]
- Example: depends_on: ["CROSS::B::api-endpoint"] (this module depends on B's api-endpoint task)
- Phase 3 Coordinator resolves to actual task IDs
- For dependencies FROM other modules: Document in task context as "provides_for" annotation
## EXPECTED DELIVERABLES
Task JSON Files (.task/IMPL-${module.prefix}*.json):
- 6-field schema (id, title, status, context_package_path, meta, context, flow_control)
- Task ID format: IMPL-${module.prefix}1, IMPL-${module.prefix}2, ...
- Quantified requirements with explicit counts
- Artifacts integration from context package (filtered for ${module.name})
- **focus_paths generated directly from prioritized_context.priority_tiers filtered by ${module.paths.join(', ')}**
- NO re-sorting - use pre-computed tiers filtered for this module
- Critical files are PRIMARY focus, High files are SECONDARY
- Flow control with pre_analysis steps (use prioritized_context.dependency_order for module task sequencing)
- **CLI Execution IDs and strategies (MANDATORY)**
- Focus ONLY on ${module.name} module scope
## CLI EXECUTION ID REQUIREMENTS (MANDATORY)
Each task JSON MUST include:
- **cli_execution_id**: Unique ID for CLI execution (format: \`{session_id}-IMPL-${module.prefix}{seq}\`)
- **cli_execution**: Strategy object based on depends_on:
- No deps → \`{ "strategy": "new" }\`
- 1 dep (single child) → \`{ "strategy": "resume", "resume_from": "parent-cli-id" }\`
- 1 dep (multiple children) → \`{ "strategy": "fork", "resume_from": "parent-cli-id" }\`
- N deps → \`{ "strategy": "merge_fork", "merge_from": ["id1", "id2", ...] }\`
- Cross-module dep → \`{ "strategy": "cross_module_fork", "resume_from": "CROSS::{module}::{pattern}" }\`
**CLI Execution Strategy Rules**:
1. **new**: Task has no dependencies - starts fresh CLI conversation
2. **resume**: Task has 1 parent AND that parent has only this child - continues same conversation
3. **fork**: Task has 1 parent BUT parent has multiple children - creates new branch with parent context
4. **merge_fork**: Task has multiple parents - merges all parent contexts into new conversation
5. **cross_module_fork**: Task depends on task from another module - Phase 3 resolves placeholder
**Execution Command Patterns**:
- new: \`ccw cli -p "[prompt]" --tool [tool] --mode write --id [cli_execution_id]\`
- resume: \`ccw cli -p "[prompt]" --resume [resume_from] --tool [tool] --mode write\`
- fork: \`ccw cli -p "[prompt]" --resume [resume_from] --id [cli_execution_id] --tool [tool] --mode write\`
- merge_fork: \`ccw cli -p "[prompt]" --resume [merge_from.join(',')] --id [cli_execution_id] --tool [tool] --mode write\`
- cross_module_fork: (Phase 3 resolves placeholder, then uses fork pattern)
## QUALITY STANDARDS
Hard Constraints:
- Task count <= 9 for this module (hard limit - coordinate with Phase 3 if exceeded)
- All requirements quantified (explicit counts and enumerated lists)
- Acceptance criteria measurable (include verification commands)
- Artifact references mapped from context package (module-scoped filter)
- Focus paths use absolute paths or clear relative paths from project root
- Cross-module dependencies use CROSS:: placeholder format
## SUCCESS CRITERIA
- Task JSONs saved to .task/ with IMPL-${module.prefix}* naming
- All task JSONs include cli_execution_id and cli_execution strategy
- Cross-module dependencies use CROSS:: placeholder format consistently
- Focus paths scoped to ${module.paths.join(', ')} only
- Return: task count, task IDs, dependency summary (internal + cross-module)
## PLANNING NOTES RECORD (REQUIRED)
After completing, append to planning-notes.md:
\`\`\`markdown
### [${module.name}] YYYY-MM-DD
- **Tasks**: [count] ([IDs])
- **CROSS deps**: [placeholders used]
\`\`\`
`
});
moduleAgents.push(agentId);
});
// Batch wait for all module agents
const moduleResults = wait({
ids: moduleAgents,
timeout_ms: 900000 // 15 minutes
});
// Close all module agents
moduleAgents.forEach(agentId => {
close_agent({ id: agentId });
});
```
**Output Structure** (direct to .task/):
```
.task/
├── IMPL-A1.json # Module A (e.g., frontend)
├── IMPL-A2.json
├── IMPL-B1.json # Module B (e.g., backend)
├── IMPL-B2.json
└── IMPL-C1.json # Module C (e.g., shared)
```
**Task ID Naming**:
- Format: `IMPL-{prefix}{seq}.json`
- Prefix: A, B, C... (assigned by detection order)
- Sequence: 1, 2, 3... (per-module increment)
### Phase 3: Integration (+1 Coordinator Agent, Multi-Module Only)
**Condition**: Only executed when `modules.length >= 2`
**Purpose**: Collect all module tasks, resolve cross-module dependencies, generate unified IMPL_PLAN.md and TODO_LIST.md documents.
**Coordinator Agent Invocation**:
```javascript
// Wait for all Phase 2B agents to complete (already done above)
// Spawn +1 Coordinator Agent
const coordinatorAgentId = spawn_agent({
message: `
## TASK ASSIGNMENT
### MANDATORY FIRST STEPS (Agent Execute)
1. **Read role definition**: ~/.codex/agents/action-planning-agent.md (MUST read first)
2. Read: .workflow/project-tech.json
3. Read: .workflow/project-guidelines.json
---
## TASK OBJECTIVE
Integrate all module task JSONs, resolve cross-module dependencies, and generate unified IMPL_PLAN.md and TODO_LIST.md
IMPORTANT: This is INTEGRATION ONLY - consolidate existing task JSONs, NOT creating new tasks.
## SESSION PATHS
Input:
- Session Metadata: .workflow/active/${session_id}/workflow-session.json
- Context Package: .workflow/active/${session_id}/.process/context-package.json
- Task JSONs: .workflow/active/${session_id}/.task/IMPL-*.json (from Phase 2B)
Output:
- Updated Task JSONs: .workflow/active/${session_id}/.task/IMPL-*.json (resolved dependencies)
- IMPL_PLAN: .workflow/active/${session_id}/IMPL_PLAN.md
- TODO_LIST: .workflow/active/${session_id}/TODO_LIST.md
## CONTEXT METADATA
Session ID: ${session_id}
Modules: ${modules.map(m => m.name + '(' + m.prefix + ')').join(', ')}
Module Count: ${modules.length}
## INTEGRATION STEPS
1. Collect all .task/IMPL-*.json, group by module prefix
2. Resolve CROSS:: dependencies → actual task IDs, update task JSONs
3. Generate IMPL_PLAN.md (multi-module format per agent specification)
4. Generate TODO_LIST.md (hierarchical format per agent specification)
## CROSS-MODULE DEPENDENCY RESOLUTION
- Pattern: CROSS::{module}::{pattern} → IMPL-{module}* matching title/context
- Example: CROSS::B::api-endpoint → IMPL-B1 (if B1 title contains "api-endpoint")
- Log unresolved as warnings
## EXPECTED DELIVERABLES
1. Updated Task JSONs with resolved dependency IDs
2. IMPL_PLAN.md - multi-module format with cross-dependency section
3. TODO_LIST.md - hierarchical by module with cross-dependency section
## SUCCESS CRITERIA
- No CROSS:: placeholders remaining in task JSONs
- IMPL_PLAN.md and TODO_LIST.md generated with multi-module structure
- Return: task count, per-module breakdown, resolved dependency count
## PLANNING NOTES RECORD (REQUIRED)
After integration, update planning-notes.md:
\`\`\`markdown
### [Coordinator] YYYY-MM-DD
- **Total**: [count] tasks
- **Resolved**: [CROSS:: resolutions]
## N+1 Context
### Decisions
| Decision | Rationale | Revisit? |
|----------|-----------|----------|
| CROSS::X → IMPL-Y | [why this resolution] | [Yes/No] |
### Deferred
- [ ] [unresolved CROSS or conflict] - [reason]
\`\`\`
`
});
// Wait for coordinator agent to complete
const coordinatorResult = wait({
ids: [coordinatorAgentId],
timeout_ms: 600000 // 10 minutes
});
// Close coordinator agent
close_agent({ id: coordinatorAgentId });
```
**Dependency Resolution Algorithm**:
```javascript
function resolveCrossModuleDependency(placeholder, allTasks) {
const [, targetModule, pattern] = placeholder.match(/CROSS::(\w+)::(.+)/);
const candidates = allTasks.filter(t =>
t.id.startsWith(`IMPL-${targetModule}`) &&
(t.title.toLowerCase().includes(pattern.toLowerCase()) ||
t.context?.description?.toLowerCase().includes(pattern.toLowerCase()))
);
return candidates.length > 0
? candidates.sort((a, b) => a.id.localeCompare(b.id))[0].id
: placeholder; // Keep for manual resolution
}
```
## Output
- **Files**:
- `.workflow/active/{sessionId}/IMPL_PLAN.md`
- `.workflow/active/{sessionId}/.task/IMPL-*.json`
- `.workflow/active/{sessionId}/TODO_LIST.md`
- **Updated**: `planning-notes.md` with task generation record and N+1 context
## Next Step
Return to orchestrator. Present user with action choices:
1. Verify Plan Quality (Recommended) → `workflow:plan-verify`
2. Start Execution → `workflow:execute`
3. Review Status Only → `workflow:status`

View File

@@ -1,77 +0,0 @@
/**
* Test ask_question MCP tool
*/
import { executeTool } from './ccw/dist/tools/index.js';
async function testAskQuestion() {
console.log('Testing ask_question tool...\n');
// Test 1: Confirm question
console.log('Test 1: Confirm Question');
const confirmResult = await executeTool('ask_question', {
question: {
id: 'test-confirm-1',
type: 'confirm',
title: '是否继续执行当前操作?',
message: '这是一个确认对话框测试',
description: '点击确认继续,点击取消终止',
},
timeout: 30000, // 30 seconds
});
console.log('Result:', JSON.stringify(confirmResult, null, 2));
// Test 2: Select question
console.log('\n\nTest 2: Select Question');
const selectResult = await executeTool('ask_question', {
question: {
id: 'test-select-1',
type: 'select',
title: '请选择您的偏好颜色',
options: [
{ value: 'red', label: '红色', description: '热情的红色' },
{ value: 'blue', label: '蓝色', description: '冷静的蓝色' },
{ value: 'green', label: '绿色', description: '自然的绿色' },
],
},
timeout: 30000,
});
console.log('Result:', JSON.stringify(selectResult, null, 2));
// Test 3: Input question
console.log('\n\nTest 3: Input Question');
const inputResult = await executeTool('ask_question', {
question: {
id: 'test-input-1',
type: 'input',
title: '请输入您的名字',
placeholder: '例如: 张三',
required: true,
},
timeout: 30000,
});
console.log('Result:', JSON.stringify(inputResult, null, 2));
// Test 4: Multi-select question
console.log('\n\nTest 4: Multi-Select Question');
const multiResult = await executeTool('ask_question', {
question: {
id: 'test-multi-1',
type: 'multi-select',
title: '选择您感兴趣的编程语言(可多选)',
options: [
{ value: 'js', label: 'JavaScript' },
{ value: 'ts', label: 'TypeScript' },
{ value: 'py', label: 'Python' },
{ value: 'go', label: 'Go' },
],
},
timeout: 30000,
});
console.log('Result:', JSON.stringify(multiResult, null, 2));
console.log('\n✅ All tests completed');
}
// Run tests
testAskQuestion().catch(console.error);

View File

@@ -1,58 +0,0 @@
/**
* Simple test to verify the buildCliCommand function logic
*/
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
// Simulate buildCliCommand logic
function buildCliCommand(tool, promptFile, model) {
const normalizedPath = promptFile.replace(/\\/g, '/');
const promptContent = fs.readFileSync(promptFile, 'utf8');
const escapedPrompt = promptContent.replace(/'/g, "'\\''");
return `ccw cli -p '${escapedPrompt}' --tool ${tool} --model ${model} --mode write`;
}
// Test data
const testPromptFile = path.join(os.tmpdir(), 'test-prompt.txt');
fs.writeFileSync(testPromptFile, 'Test prompt content');
console.log('\n=== Build CLI Command Test ===\n');
// Test 1: With SECONDARY_MODEL alias
const cmd1 = buildCliCommand('gemini', testPromptFile, 'SECONDARY_MODEL');
console.log('Test 1: Command with SECONDARY_MODEL alias');
console.log(' Command:', cmd1.substring(0, 100) + '...');
console.log(' ✓ Uses ccw cli:', cmd1.includes('ccw cli'));
console.log(' ✓ Has --tool gemini:', cmd1.includes('--tool gemini'));
console.log(' ✓ Has --model SECONDARY_MODEL:', cmd1.includes('--model SECONDARY_MODEL'));
console.log(' ✓ Has --mode write:', cmd1.includes('--mode write'));
console.log('\n');
// Test 2: With explicit model
const cmd2 = buildCliCommand('codex', testPromptFile, 'gpt-5.2');
console.log('Test 2: Command with explicit model');
console.log(' Command:', cmd2.substring(0, 100) + '...');
console.log(' ✓ Uses ccw cli:', cmd2.includes('ccw cli'));
console.log(' ✓ Has --tool codex:', cmd2.includes('--tool codex'));
console.log(' ✓ Has --model gpt-5.2:', cmd2.includes('--model gpt-5.2'));
console.log(' ✓ Has --mode write:', cmd2.includes('--mode write'));
console.log('\n');
// Test 3: Model default fallback logic (simulating execute function)
function getActualModel(userProvidedModel) {
return userProvidedModel || 'SECONDARY_MODEL';
}
console.log('Test 3: Model default fallback');
console.log(' User provides no model:', getActualModel(undefined));
console.log(' User provides null:', getActualModel(null));
console.log(' User provides explicit model:', getActualModel('custom-model'));
// Cleanup
fs.unlinkSync(testPromptFile);
console.log('\n✅ All command generation tests passed!');
console.log('\n=== Test Complete ===\n');

View File

@@ -1,7 +0,0 @@
const { getToolConfig } = require('./ccw/dist/tools/claude-cli-tools.js');
const workingDir = 'D:\\Claude_dms3';
const tool = 'claude';
const config = getToolConfig(workingDir, tool);
console.log('Claude tool config:', JSON.stringify(config, null, 2));

View File

@@ -1,75 +0,0 @@
/**
* End-to-end test: Model alias resolution in ccw cli
*/
import { resolveModelAlias, getPrimaryModel, getSecondaryModel } from './ccw/dist/tools/cli-executor-core.js';
import { getPrimaryModel as getConfigPrimaryModel, getSecondaryModel as getConfigSecondaryModel } from './ccw/dist/tools/claude-cli-tools.js';
const testDir = process.cwd();
console.log('\n=== End-to-End Model Alias Test ===\n');
// Test resolveModelAlias function (this is what ccw cli uses internally)
console.log('Testing resolveModelAlias function:\n');
// Test 1: PRIMARY_MODEL for gemini
const result1 = resolveModelAlias('PRIMARY_MODEL', 'gemini', testDir);
const expected1 = getConfigPrimaryModel(testDir, 'gemini');
console.log('Test 1: PRIMARY_MODEL for gemini');
console.log(` Input: 'PRIMARY_MODEL'`);
console.log(` Resolved: ${result1}`);
console.log(` Expected: ${expected1}`);
console.log(` ✓ Match: ${result1 === expected1}\n`);
// Test 2: SECONDARY_MODEL for gemini
const result2 = resolveModelAlias('SECONDARY_MODEL', 'gemini', testDir);
const expected2 = getConfigSecondaryModel(testDir, 'gemini');
console.log('Test 2: SECONDARY_MODEL for gemini');
console.log(` Input: 'SECONDARY_MODEL'`);
console.log(` Resolved: ${result2}`);
console.log(` Expected: ${expected2}`);
console.log(` ✓ Match: ${result2 === expected2}\n`);
// Test 3: SECONDARY_MODEL for claude (different values)
const result3 = resolveModelAlias('SECONDARY_MODEL', 'claude', testDir);
const expected3 = getConfigSecondaryModel(testDir, 'claude');
console.log('Test 3: SECONDARY_MODEL for claude');
console.log(` Input: 'SECONDARY_MODEL'`);
console.log(` Resolved: ${result3}`);
console.log(` Expected: ${expected3}`);
console.log(` ✓ Match: ${result3 === expected3}\n`);
// Test 4: secondary_model (lowercase - should be case-insensitive)
const result4 = resolveModelAlias('secondary_model', 'codex', testDir);
const expected4 = getConfigSecondaryModel(testDir, 'codex');
console.log('Test 4: secondary_model (lowercase) for codex');
console.log(` Input: 'secondary_model'`);
console.log(` Resolved: ${result4}`);
console.log(` Expected: ${expected4}`);
console.log(` ✓ Match: ${result4 === expected4}\n`);
// Test 5: Explicit model (should pass through unchanged)
const result5 = resolveModelAlias('custom-model-123', 'gemini', testDir);
console.log('Test 5: Explicit model name (not an alias)');
console.log(` Input: 'custom-model-123'`);
console.log(` Resolved: ${result5}`);
console.log(` Expected: 'custom-model-123'`);
console.log(` ✓ Match: ${result5 === 'custom-model-123'}\n`);
// Test 6: Undefined model (should return undefined)
const result6 = resolveModelAlias(undefined, 'gemini', testDir);
console.log('Test 6: Undefined model');
console.log(` Input: undefined`);
console.log(` Resolved: ${result6}`);
console.log(` Expected: undefined`);
console.log(` ✓ Match: ${result6 === undefined}\n`);
// Summary
console.log('Summary:');
console.log(' ✓ PRIMARY_MODEL alias works');
console.log(' ✓ SECONDARY_MODEL alias works');
console.log(' ✓ Case-insensitive matching works');
console.log(' ✓ Explicit model names pass through');
console.log(' ✓ Undefined handling works correctly');
console.log('\n✅ All end-to-end tests passed!');
console.log('\n=== Test Complete ===\n');

View File

@@ -1,31 +0,0 @@
/**
* Test model alias resolution
*/
import { getSecondaryModel, getPrimaryModel } from './ccw/dist/tools/claude-cli-tools.js';
const testDir = process.cwd();
console.log('\n=== Model Alias Resolution Test ===\n');
// Test gemini
const geminiPrimary = getPrimaryModel(testDir, 'gemini');
const geminiSecondary = getSecondaryModel(testDir, 'gemini');
console.log('Gemini:');
console.log(` PRIMARY_MODEL => ${geminiPrimary}`);
console.log(` SECONDARY_MODEL => ${geminiSecondary}`);
// Test claude
const claudePrimary = getPrimaryModel(testDir, 'claude');
const claudeSecondary = getSecondaryModel(testDir, 'claude');
console.log('\nClaude:');
console.log(` PRIMARY_MODEL => ${claudePrimary}`);
console.log(` SECONDARY_MODEL => ${claudeSecondary}`);
// Test codex
const codexPrimary = getPrimaryModel(testDir, 'codex');
const codexSecondary = getSecondaryModel(testDir, 'codex');
console.log('\nCodex:');
console.log(` PRIMARY_MODEL => ${codexPrimary}`);
console.log(` SECONDARY_MODEL => ${codexSecondary}`);
console.log('\n=== Test Complete ===\n');

View File

@@ -1,2 +0,0 @@
Test prompt for model alias resolution.
This should be executed with SECONDARY_MODEL.

View File

@@ -1,99 +0,0 @@
/**
* Integration Test Summary Report
* Testing model alias resolution feature
*/
console.log('\n╔════════════════════════════════════════════════════════════════╗');
console.log('║ Model Alias Resolution - Integration Test Report ║');
console.log('╚════════════════════════════════════════════════════════════════╝\n');
console.log('Test Date:', new Date().toISOString());
console.log('Project: Claude DMS3 / CCW\n');
console.log('─────────────────────────────────────────────────────────────────');
console.log('📋 Feature Overview');
console.log('─────────────────────────────────────────────────────────────────\n');
console.log('Added support for model aliases in ccw cli:');
console.log(' • PRIMARY_MODEL → resolves to tool\'s primaryModel');
console.log(' • SECONDARY_MODEL → resolves to tool\'s secondaryModel');
console.log(' • Case-insensitive matching (primary_model, PRIMARY_MODEL)');
console.log(' • Non-alias values pass through unchanged\n');
console.log('─────────────────────────────────────────────────────────────────');
console.log('✅ Test Results - All Passed');
console.log('─────────────────────────────────────────────────────────────────\n');
console.log('Test 1: Configuration Reading');
console.log(' ✓ getPrimaryModel() reads cli-tools.json correctly');
console.log(' ✓ getSecondaryModel() reads cli-tools.json correctly');
console.log(' ✓ Gemini: primary=gemini-2.5-flash, secondary=gemini-2.5-flash');
console.log(' ✓ Claude: primary=sonnet, secondary=haiku');
console.log(' ✓ Codex: primary=gpt-5.2, secondary=gpt-5.2\n');
console.log('Test 2: Command Generation (update_module_claude)');
console.log(' ✓ Generates ccw cli commands (not direct tool calls)');
console.log(' ✓ Uses SECONDARY_MODEL as default when no model specified');
console.log(' ✓ Includes --mode write parameter');
console.log(' ✓ Includes --tool parameter');
console.log(' ✓ Properly escapes prompt content\n');
console.log('Test 3: Code Compilation');
console.log(' ✓ TypeScript compilation successful (backend)');
console.log(' ✓ resolveModelAlias() function compiled correctly');
console.log(' ✓ Function called in 2 code paths:');
console.log(' - Standard tools (gemini, qwen, codex, claude)');
console.log(' - API endpoints (LiteLLM integration)\n');
console.log('─────────────────────────────────────────────────────────────────');
console.log('📝 Modified Files');
console.log('─────────────────────────────────────────────────────────────────\n');
console.log('1. ccw/src/tools/cli-executor-core.ts');
console.log(' • Added resolveModelAlias() function');
console.log(' • Imported getSecondaryModel from claude-cli-tools');
console.log(' • Applied alias resolution to effectiveModel calculation');
console.log(' • Applied alias resolution to apiEndpointEffectiveModel\n');
console.log('2. ccw/src/tools/update-module-claude.js');
console.log(' • Removed getSecondaryModel() function (no longer needed)');
console.log(' • Removed DEFAULT_MODELS constant');
console.log(' • Changed default model to \'SECONDARY_MODEL\' string');
console.log(' • Updated buildCliCommand to use ccw cli');
console.log(' • Updated tool description\n');
console.log('3. ccw/src/commands/cli.ts');
console.log(' • Updated --model help text to mention aliases\n');
console.log('─────────────────────────────────────────────────────────────────');
console.log('💡 Usage Examples');
console.log('─────────────────────────────────────────────────────────────────\n');
console.log('# Use secondary model (via alias)');
console.log('ccw cli -p "prompt" --tool gemini --model SECONDARY_MODEL --mode write\n');
console.log('# Use primary model (via alias)');
console.log('ccw cli -p "prompt" --tool claude --model PRIMARY_MODEL --mode analysis\n');
console.log('# Explicit model (no alias)');
console.log('ccw cli -p "prompt" --tool codex --model gpt-5.2 --mode write\n');
console.log('# Default behavior (uses primary model from config)');
console.log('ccw cli -p "prompt" --tool gemini --mode analysis\n');
console.log('# update_module_claude tool (automatically uses SECONDARY_MODEL)');
console.log('ccw tool exec update_module_claude \'{"strategy":"multi-layer","tool":"gemini"}\'\n');
console.log('─────────────────────────────────────────────────────────────────');
console.log('🎯 Benefits');
console.log('─────────────────────────────────────────────────────────────────\n');
console.log('✓ Centralized: All model config logic in ccw cli');
console.log('✓ Simplified: External tools don\'t need to read cli-tools.json');
console.log('✓ Consistent: Same alias resolution across all tools');
console.log('✓ Flexible: Supports both aliases and explicit model names');
console.log('✓ Maintainable: Change models in one place (cli-tools.json)\n');
console.log('─────────────────────────────────────────────────────────────────');
console.log('✅ CONCLUSION: All tests passed, feature ready for use');
console.log('─────────────────────────────────────────────────────────────────\n');

View File

@@ -1,64 +0,0 @@
/**
* Test update_module_claude command generation
*/
import { updateModuleClaudeTool } from './ccw/dist/tools/update-module-claude.js';
console.log('\n=== Update Module Claude Tool Test ===\n');
// Mock execSync to capture the command without executing it
let capturedCommand = null;
const originalExecSync = (await import('child_process')).execSync;
// Temporarily replace execSync
const childProcess = await import('child_process');
childProcess.execSync = function(command, options) {
capturedCommand = command;
console.log('Generated Command:');
console.log(command);
throw new Error('Test mode - command not executed');
};
// Test parameters
const testParams = {
strategy: 'single-layer',
path: './test-update-claude/src',
tool: 'gemini'
// Note: no model specified, should default to SECONDARY_MODEL
};
console.log('Test Parameters:');
console.log(JSON.stringify(testParams, null, 2));
console.log('\n');
try {
await updateModuleClaudeTool.execute(testParams);
} catch (err) {
if (err.message !== 'Test mode - command not executed') {
console.error('Error:', err.message);
}
}
// Restore original
childProcess.execSync = originalExecSync;
// Analyze the captured command
if (capturedCommand) {
console.log('\nCommand Analysis:');
const hasSecondaryModel = capturedCommand.includes('SECONDARY_MODEL');
const hasCcwCli = capturedCommand.includes('ccw cli');
const hasModeWrite = capturedCommand.includes('--mode write');
const hasToolGemini = capturedCommand.includes('--tool gemini');
console.log(` ✓ Uses ccw cli: ${hasCcwCli}`);
console.log(` ✓ Has --mode write: ${hasModeWrite}`);
console.log(` ✓ Has --tool gemini: ${hasToolGemini}`);
console.log(` ✓ Uses SECONDARY_MODEL alias: ${hasSecondaryModel}`);
if (hasCcwCli && hasModeWrite && hasToolGemini && hasSecondaryModel) {
console.log('\n✅ Test PASSED - Command generation is correct!');
} else {
console.log('\n❌ Test FAILED - Command generation has issues');
}
}
console.log('\n=== Test Complete ===\n');

View File

@@ -1 +0,0 @@
// Test file