mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
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:
677
.claude/skills/_shared/COMMAND-TO-SKILL-CONVERSION.md
Normal file
677
.claude/skills/_shared/COMMAND-TO-SKILL-CONVERSION.md
Normal 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 引用 Phase,Phase 按执行顺序加载**
|
||||||
|
|
||||||
|
```
|
||||||
|
执行流程:
|
||||||
|
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章一致性验证;添加应移除的命令特有内容说明 |
|
||||||
693
.codex/skills/workflow-plan/phases/03-conflict-resolution.md
Normal file
693
.codex/skills/workflow-plan/phases/03-conflict-resolution.md
Normal 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).
|
||||||
756
.codex/skills/workflow-plan/phases/04-task-generation.md
Normal file
756
.codex/skills/workflow-plan/phases/04-task-generation.md
Normal 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`
|
||||||
@@ -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);
|
|
||||||
@@ -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');
|
|
||||||
@@ -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));
|
|
||||||
@@ -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');
|
|
||||||
@@ -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');
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Test prompt for model alias resolution.
|
|
||||||
This should be executed with SECONDARY_MODEL.
|
|
||||||
@@ -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');
|
|
||||||
@@ -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');
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
// Test file
|
|
||||||
Reference in New Issue
Block a user