Refactor workflow session commands to utilize ccw CLI for session management

- Updated session completion process to use `ccw session` commands for listing, reading, and updating session statuses.
- Enhanced session listing command to provide metadata and statistics using `ccw session list` and `ccw session stats`.
- Streamlined session resume functionality with `ccw session` commands for checking status and updating session state.
- Improved session creation process by replacing manual directory and metadata handling with `ccw session init`.
- Introduced `session_manager` tool for simplified session operations, including listing, updating, and archiving sessions.
- Updated conflict resolution tools to generate structured output in `conflict-resolution.json` instead of markdown files.
- Enhanced TDD and UI design tools to utilize `ccw cli exec` for executing analysis commands, improving integration with the workflow.
This commit is contained in:
catlog22
2025-12-13 10:45:03 +08:00
parent 25ac862f46
commit 30e9ae0153
32 changed files with 758 additions and 625 deletions

View File

@@ -133,7 +133,7 @@ Task(subagent_type="cli-execution-agent", prompt=`
### 2. Execute CLI Analysis (Enhanced with Exploration + Scenario Uniqueness)
Primary (Gemini):
cd {project_root} && gemini -p "
ccw cli exec "
PURPOSE: Detect conflicts between plan and codebase, using exploration insights
TASK:
• **Review pre-identified conflict_indicators from exploration results**
@@ -152,7 +152,7 @@ Task(subagent_type="cli-execution-agent", prompt=`
- ModuleOverlap conflicts with overlap_analysis
- Targeted clarification questions
RULES: $(cat ~/.claude/workflows/cli-templates/prompts/analysis/02-analyze-code-patterns.txt) | Focus on breaking changes, migration needs, and functional overlaps | Prioritize exploration-identified conflicts | analysis=READ-ONLY
"
" --tool gemini --cd {project_root}
Fallback: Qwen (same prompt) → Claude (manual analysis)
@@ -169,7 +169,7 @@ Task(subagent_type="cli-execution-agent", prompt=`
### 4. Return Structured Conflict Data
⚠️ DO NOT generate CONFLICT_RESOLUTION.md file
⚠️ Output to conflict-resolution.json (generated in Phase 4)
Return JSON format for programmatic processing:
@@ -467,14 +467,30 @@ selectedStrategies.forEach(item => {
console.log(`\n正在应用 ${modifications.length} 个修改...`);
// 2. Apply each modification using Edit tool
// 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,
@@ -502,14 +518,45 @@ modifications.forEach((mod, idx) => {
}
});
// 3. Update context-package.json with resolution details
// 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));
console.log(`\n📄 冲突解决结果已保存: ${resolutionPath}`);
// 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.resolved_conflicts = selectedStrategies.map(s => ({
conflict_id: s.conflict_id,
strategy_name: s.strategy.name,
clarifications: s.clarifications
}));
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));
@@ -582,12 +629,50 @@ return {
✓ Agent log saved to .workflow/active/{session_id}/.chat/
```
## Output Format: Agent JSON Response
## 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": []
}
```
### Secondary: Agent JSON Response (stdout)
**Focus**: Structured conflict data with actionable modifications for programmatic processing.
**Format**: JSON to stdout (NO file generation)
**Structure**: Defined in Phase 2, Step 4 (agent prompt)
### Key Requirements
@@ -635,11 +720,12 @@ If Edit tool fails mid-application:
- Requires: `conflict_risk ≥ medium`
**Output**:
- Modified files:
- 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)
- NO report file generation
- `.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
@@ -667,7 +753,7 @@ If Edit tool fails mid-application:
✓ guidance-specification.md updated with resolved conflicts
✓ Role analyses (*.md) updated with resolved conflicts
✓ context-package.json marked as "resolved" with clarification records
No CONFLICT_RESOLUTION.md file generated
conflict-resolution.json generated with full resolution details
✓ Modification summary includes:
- Total conflicts
- Resolved with strategy (count)

View File

@@ -89,6 +89,14 @@ Phase 3: Integration (+1 Coordinator, Multi-Module Only)
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 [
@@ -112,8 +120,9 @@ Phase 3: Integration (+1 Coordinator, Multi-Module Only)
```
**Decision Logic**:
- `complexity !== 'High'` → Force Phase 2A (Single Agent, maximize context reuse)
- `modules.length == 1` → Phase 2A (Single Agent, original flow)
- `modules.length >= 2` → Phase 2B + Phase 3 (N+1 Parallel)
- `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.
@@ -163,6 +172,13 @@ Determine CLI tool usage per-step based on user's task description:
- 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)
@@ -203,7 +219,9 @@ Hard Constraints:
**Condition**: `modules.length >= 2` (multi-module detected)
**Purpose**: Launch N action-planning-agents simultaneously, one per module, for parallel task generation.
**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
@@ -211,27 +229,49 @@ Hard Constraints:
const planningTasks = modules.map(module =>
Task(
subagent_type="action-planning-agent",
description=`Plan ${module.name} module`,
description=`Generate ${module.name} module task JSONs`,
prompt=`
## SCOPE
## 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 progressive loading strategy in agent specification
## MODULE SCOPE
- Module: ${module.name} (${module.type})
- Focus Paths: ${module.paths.join(', ')}
- Task ID Prefix: IMPL-${module.prefix}
- Task Limit: ≤9 tasks
- Other Modules: ${otherModules.join(', ')}
- Cross-module deps format: "CROSS::{module}::{pattern}"
## SESSION PATHS
Input:
- Session Metadata: .workflow/active/{session-id}/workflow-session.json
- Context Package: .workflow/active/{session-id}/.process/context-package.json
Output:
- Task Dir: .workflow/active/{session-id}/.task/
## INSTRUCTIONS
- Generate tasks ONLY for ${module.name} module
- Use task ID format: IMPL-${module.prefix}1, IMPL-${module.prefix}2, ...
- For cross-module dependencies, use: depends_on: ["CROSS::B::api-endpoint"]
- Maximum 9 tasks per module
## CONTEXT METADATA
Session ID: {session-id}
MCP Capabilities: {exa_code, exa_web, code_index}
## CROSS-MODULE DEPENDENCIES
- Use placeholder: depends_on: ["CROSS::{module}::{pattern}"]
- Example: depends_on: ["CROSS::B::api-endpoint"]
- Phase 3 Coordinator resolves to actual task IDs
## EXPECTED DELIVERABLES
Task JSON Files (.task/IMPL-${module.prefix}*.json):
- 6-field schema per agent specification
- Task ID format: IMPL-${module.prefix}1, IMPL-${module.prefix}2, ...
- Focus ONLY on ${module.name} module scope
## SUCCESS CRITERIA
- Task JSONs saved to .task/ with IMPL-${module.prefix}* naming
- Cross-module dependencies use CROSS:: placeholder format
- Return task count and brief summary
`
)
);
@@ -255,37 +295,78 @@ await Promise.all(planningTasks);
- Prefix: A, B, C... (assigned by detection order)
- Sequence: 1, 2, 3... (per-module increment)
### Phase 3: Integration (+1 Coordinator, Multi-Module Only)
### 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 documents.
**Purpose**: Collect all module tasks, resolve cross-module dependencies, generate unified IMPL_PLAN.md and TODO_LIST.md documents.
**Integration Logic**:
**Coordinator Agent Invocation**:
```javascript
// 1. Collect all module task JSONs
const allTasks = glob('.task/IMPL-*.json').map(loadJson);
// Wait for all Phase 2B agents to complete
const moduleResults = await Promise.all(planningTasks);
// 2. Resolve cross-module dependencies
for (const task of allTasks) {
if (task.depends_on) {
task.depends_on = task.depends_on.map(dep => {
if (dep.startsWith('CROSS::')) {
// CROSS::B::api-endpoint → find matching IMPL-B* task
const [, targetModule, pattern] = dep.match(/CROSS::(\w+)::(.+)/);
return findTaskByModuleAndPattern(allTasks, targetModule, pattern);
}
return dep;
});
}
}
// Launch +1 Coordinator Agent
Task(
subagent_type="action-planning-agent",
description="Integrate module tasks and generate unified documents",
prompt=`
## TASK OBJECTIVE
Integrate all module task JSONs, resolve cross-module dependencies, and generate unified IMPL_PLAN.md and TODO_LIST.md
// 3. Generate unified IMPL_PLAN.md (grouped by module)
generateIMPL_PLAN(allTasks, modules);
IMPORTANT: This is INTEGRATION ONLY - consolidate existing task JSONs, NOT creating new tasks.
// 4. Generate TODO_LIST.md (hierarchical structure)
generateTODO_LIST(allTasks, modules);
## 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
`
)
```
**Note**: IMPL_PLAN.md and TODO_LIST.md structure definitions are in `action-planning-agent.md`.
**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
}
```

View File

@@ -152,9 +152,14 @@ Phase 2: Agent Execution (Document Generation)
roleAnalysisPaths.forEach(path => Read(path));
```
5. **Load Conflict Resolution** (from context-package.json, if exists)
5. **Load Conflict Resolution** (from conflict-resolution.json, if exists)
```javascript
if (contextPackage.brainstorm_artifacts.conflict_resolution?.exists) {
// Check for new conflict-resolution.json format
if (contextPackage.conflict_detection?.resolution_file) {
Read(contextPackage.conflict_detection.resolution_file) // .process/conflict-resolution.json
}
// Fallback: legacy brainstorm_artifacts path
else if (contextPackage.brainstorm_artifacts?.conflict_resolution?.exists) {
Read(contextPackage.brainstorm_artifacts.conflict_resolution.path)
}
```
@@ -223,7 +228,7 @@ If conflict_risk was medium/high, modifications have been applied to:
- **guidance-specification.md**: Design decisions updated to resolve conflicts
- **Role analyses (*.md)**: Recommendations adjusted for compatibility
- **context-package.json**: Marked as "resolved" with conflict IDs
- NO separate CONFLICT_RESOLUTION.md file (conflicts resolved in-place)
- Conflict resolution results stored in conflict-resolution.json
### MCP Analysis Results (Optional)
**Code Structure**: {mcp_code_index_results}
@@ -373,10 +378,12 @@ const agentContext = {
.flatMap(role => role.files)
.map(file => Read(file.path)),
// Load conflict resolution if exists (from context package)
conflict_resolution: brainstorm_artifacts.conflict_resolution?.exists
? Read(brainstorm_artifacts.conflict_resolution.path)
: null,
// Load conflict resolution if exists (prefer new JSON format)
conflict_resolution: context_package.conflict_detection?.resolution_file
? Read(context_package.conflict_detection.resolution_file) // .process/conflict-resolution.json
: (brainstorm_artifacts?.conflict_resolution?.exists
? Read(brainstorm_artifacts.conflict_resolution.path)
: null),
// Optional MCP enhancements
mcp_analysis: executeMcpDiscovery()
@@ -408,7 +415,7 @@ This section provides quick reference for TDD task JSON structure. For complete
│ ├── IMPL-3.2.json # Complex feature subtask (if needed)
│ └── ...
└── .process/
├── CONFLICT_RESOLUTION.md # Conflict resolution strategies (if conflict_risk ≥ medium)
├── conflict-resolution.json # Conflict resolution results (if conflict_risk ≥ medium)
├── test-context-package.json # Test coverage analysis
├── context-package.json # Input from context-gather
├── context_package_path # Path to smart context package

View File

@@ -89,7 +89,7 @@ Template: ~/.claude/workflows/cli-templates/prompts/test/test-concept-analysis.t
## EXECUTION STEPS
1. Execute Gemini analysis:
cd .workflow/active/{test_session_id}/.process && gemini -p "$(cat ~/.claude/workflows/cli-templates/prompts/test/test-concept-analysis.txt)" --approval-mode yolo
ccw cli exec "$(cat ~/.claude/workflows/cli-templates/prompts/test/test-concept-analysis.txt)" --tool gemini --mode write --cd .workflow/active/{test_session_id}/.process
2. Generate TEST_ANALYSIS_RESULTS.md:
Synthesize gemini-test-analysis.md into standardized format for task generation