mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-14 02:42:04 +08:00
refactor: optimize TodoWrite format with hierarchical display across workflow commands
Adopt consistent hierarchical TodoWrite format for better visual clarity: - Phase-level tasks: "Phase N: Description" - Sub-tasks: " → Sub-task description" (indented with arrow) - Clear parent-child relationships through visual hierarchy - Task attachment/collapse pattern visualization Updated commands: - lite-plan.md (Phase 1-4 examples) - auto-parallel.md (Phase 0-3 examples) - tdd-plan.md (Phase 3-5 examples) - test-fix-gen.md (TodoWrite Pattern with examples) - explore-auto.md (TodoWrite Pattern) - imitate-auto.md (TodoWrite Pattern) - review-session-cycle.md - review-module-cycle.md Benefits: - Visual hierarchy shows task relationships - Expanded view shows detailed progress - Collapsed view maintains clean orchestrator-level summary - Consistent format across all multi-phase workflows
This commit is contained in:
@@ -47,7 +47,7 @@ User Input → Task Analysis & Exploration Decision (Phase 1)
|
||||
|
||||
## Implementation
|
||||
|
||||
### Phase 1: Task Analysis & Exploration Decision
|
||||
### Phase 1: Intelligent Multi-Angle Exploration
|
||||
|
||||
**Session Setup**:
|
||||
```javascript
|
||||
@@ -60,7 +60,7 @@ const sessionFolder = `.workflow/.lite-plan/${sessionId}`
|
||||
bash(`mkdir -p ${sessionFolder}`)
|
||||
```
|
||||
|
||||
**Decision Logic**:
|
||||
**Exploration Decision Logic**:
|
||||
```javascript
|
||||
needsExploration = (
|
||||
flags.includes('--explore') || flags.includes('-e') ||
|
||||
@@ -69,16 +69,66 @@ needsExploration = (
|
||||
task.needs_architecture_understanding ||
|
||||
task.modifies_existing_code
|
||||
)
|
||||
|
||||
if (!needsExploration) {
|
||||
// Skip to Phase 2 (Clarification) or Phase 3 (Planning)
|
||||
proceed_to_next_phase()
|
||||
}
|
||||
```
|
||||
|
||||
**If exploration needed** - Invoke cli-explore-agent:
|
||||
**Complexity Assessment & Exploration Count**:
|
||||
```javascript
|
||||
// Estimate task complexity based on description
|
||||
function estimateComplexity(taskDescription) {
|
||||
const wordCount = taskDescription.split(/\s+/).length
|
||||
const text = taskDescription.toLowerCase()
|
||||
|
||||
const indicators = {
|
||||
high: ['refactor', 'migrate', 'redesign', 'architecture', 'system'],
|
||||
medium: ['implement', 'add feature', 'integrate', 'modify module'],
|
||||
low: ['fix', 'update', 'adjust', 'tweak']
|
||||
}
|
||||
|
||||
let score = 0
|
||||
if (wordCount > 50) score += 2
|
||||
else if (wordCount > 20) score += 1
|
||||
|
||||
if (indicators.high.some(w => text.includes(w))) score += 3
|
||||
else if (indicators.medium.some(w => text.includes(w))) score += 2
|
||||
else if (indicators.low.some(w => text.includes(w))) score += 1
|
||||
|
||||
// 0-2: Low, 3-4: Medium, 5+: High
|
||||
if (score >= 5) return 'High'
|
||||
if (score >= 3) return 'Medium'
|
||||
return 'Low'
|
||||
}
|
||||
|
||||
const complexity = estimateComplexity(task_description)
|
||||
const explorationCount = complexity === 'High' ? 4 : (complexity === 'Medium' ? 3 : 1)
|
||||
|
||||
console.log(`
|
||||
## Exploration Plan
|
||||
|
||||
Task Complexity: ${complexity}
|
||||
Exploration Count: ${explorationCount} angle(s)
|
||||
|
||||
Starting intelligent multi-angle exploration...
|
||||
`)
|
||||
```
|
||||
|
||||
**Launch Parallel Explorations** - Each agent chooses its own angle:
|
||||
|
||||
```javascript
|
||||
Task(
|
||||
subagent_type="cli-explore-agent",
|
||||
description="Analyze codebase for task context",
|
||||
prompt=`
|
||||
Analyze codebase for task context and generate exploration.json.
|
||||
// Launch multiple cli-explore-agent tasks in parallel
|
||||
const explorationTasks = []
|
||||
|
||||
for (let i = 1; i <= explorationCount; i++) {
|
||||
explorationTasks.push(
|
||||
Task(
|
||||
subagent_type="cli-explore-agent",
|
||||
description=`Explore angle ${i}/${explorationCount}`,
|
||||
prompt=`
|
||||
**以解决任务为目标的智能探索** - 从不同角度分析代码库,为任务规划提供上下文。
|
||||
|
||||
## Output Schema Reference
|
||||
~/.claude/workflows/cli-templates/schemas/explore-json-schema.json
|
||||
@@ -86,45 +136,155 @@ Analyze codebase for task context and generate exploration.json.
|
||||
## Task Description
|
||||
${task_description}
|
||||
|
||||
## Requirements
|
||||
Generate exploration.json with:
|
||||
- project_structure: Architecture and module organization
|
||||
- relevant_files: File paths to be affected
|
||||
- patterns: Code patterns, conventions, styles
|
||||
- dependencies: External/internal module dependencies
|
||||
- integration_points: Task connections with existing code
|
||||
- constraints: Technical limitations/requirements
|
||||
- clarification_needs: Ambiguities requiring user input
|
||||
- _metadata: timestamp, task_description, source
|
||||
## Your Mission
|
||||
You are exploration ${i} of ${explorationCount} parallel explorations.
|
||||
|
||||
## Execution
|
||||
1. Structural scan: get_modules_by_depth.sh, find, rg
|
||||
2. Semantic analysis: Gemini for patterns/architecture
|
||||
3. Write JSON: Write('${sessionFolder}/exploration.json', jsonContent)
|
||||
4. Return brief completion summary
|
||||
**Choose ONE unique angle** most relevant to solving this task:
|
||||
- Choose different angles from what other explorations might cover
|
||||
- Focus on aspects critical for task success
|
||||
- Examples: architecture, security, dataflow, patterns, performance, dependencies, testing, error-handling, state-management, etc.
|
||||
- Be creative and task-driven - not limited to examples above
|
||||
|
||||
## Output File Naming
|
||||
Choose a descriptive angle name (lowercase, no spaces, hyphen-separated if needed)
|
||||
Examples: "architecture", "security", "dataflow", "auth-patterns", "error-handling"
|
||||
|
||||
Generate file: exploration-{your-chosen-angle}.json
|
||||
|
||||
Example angles based on task type:
|
||||
- Architecture refactoring → "architecture", "modularity", "dependencies"
|
||||
- Security feature → "security", "auth-patterns", "dataflow"
|
||||
- Performance fix → "performance", "bottlenecks", "caching"
|
||||
- Bug fix → "error-handling", "dataflow", "state-management"
|
||||
|
||||
## Requirements
|
||||
Generate exploration-{angle}.json with:
|
||||
- project_structure: Architecture and module organization relevant to your angle
|
||||
- relevant_files: File paths to be affected
|
||||
- patterns: Code patterns relevant to your angle
|
||||
- dependencies: Dependencies relevant to your angle
|
||||
- integration_points: Integration points from your angle's viewpoint
|
||||
- constraints: Constraints related to your angle
|
||||
- clarification_needs: Ambiguities requiring user input
|
||||
- _metadata:
|
||||
- timestamp: ISO 8601 timestamp
|
||||
- task_description: Original task description
|
||||
- source: "cli-explore-agent"
|
||||
- exploration_angle: "your-chosen-angle"
|
||||
- exploration_index: ${i}
|
||||
- total_explorations: ${explorationCount}
|
||||
|
||||
## Execution Steps
|
||||
1. Decide your unique exploration angle based on task needs
|
||||
2. Structural scan: get_modules_by_depth.sh, find, rg (focused on your angle)
|
||||
3. Semantic analysis: Use Gemini for patterns/architecture specific to your angle
|
||||
4. Write JSON: Write('${sessionFolder}/exploration-{your-angle}.json', jsonContent)
|
||||
5. Return: Brief summary stating your chosen angle and key findings
|
||||
|
||||
Time Limit: 60 seconds
|
||||
|
||||
**Remember**: Choose a unique, task-relevant angle. Don't duplicate other explorations' focus.
|
||||
`
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// Execute all exploration tasks in parallel (single message, multiple tool calls)
|
||||
console.log(`Launching ${explorationCount} parallel explorations...`)
|
||||
```
|
||||
|
||||
**Output**: `${sessionFolder}/exploration.json` (if exploration performed)
|
||||
**Auto-discover Generated Exploration Files**:
|
||||
```javascript
|
||||
// After explorations complete, auto-discover all exploration-*.json files
|
||||
const explorationFiles = bash(`find ${sessionFolder} -name "exploration-*.json" -type f`)
|
||||
.split('\n')
|
||||
.filter(f => f.trim())
|
||||
|
||||
// Read metadata to build manifest
|
||||
const explorationManifest = {
|
||||
session_id: sessionId,
|
||||
task_description: task_description,
|
||||
timestamp: new Date().toISOString(),
|
||||
complexity: complexity,
|
||||
exploration_count: explorationCount,
|
||||
explorations: explorationFiles.map(file => {
|
||||
const data = JSON.parse(Read(file))
|
||||
const filename = path.basename(file)
|
||||
return {
|
||||
angle: data._metadata.exploration_angle,
|
||||
file: filename,
|
||||
path: file,
|
||||
index: data._metadata.exploration_index
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Write(`${sessionFolder}/explorations-manifest.json`, JSON.stringify(explorationManifest, null, 2))
|
||||
|
||||
console.log(`
|
||||
## Exploration Complete
|
||||
|
||||
Generated exploration files in ${sessionFolder}:
|
||||
${explorationManifest.explorations.map(e => `- exploration-${e.angle}.json (angle: ${e.angle})`).join('\n')}
|
||||
|
||||
Manifest: explorations-manifest.json
|
||||
Angles explored: ${explorationManifest.explorations.map(e => e.angle).join(', ')}
|
||||
`)
|
||||
```
|
||||
|
||||
**Output**:
|
||||
- `${sessionFolder}/exploration-{angle1}.json`
|
||||
- `${sessionFolder}/exploration-{angle2}.json`
|
||||
- ... (1-4 files based on complexity)
|
||||
- `${sessionFolder}/explorations-manifest.json`
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Clarification (Optional)
|
||||
|
||||
**Skip if**: No exploration or `clarification_needs` is empty
|
||||
**Skip if**: No exploration or `clarification_needs` is empty across all explorations
|
||||
|
||||
**If clarification needed**:
|
||||
**Aggregate clarification needs from all exploration angles**:
|
||||
```javascript
|
||||
const exploration = JSON.parse(Read(`${sessionFolder}/exploration.json`))
|
||||
// Load manifest and all exploration files
|
||||
const manifest = JSON.parse(Read(`${sessionFolder}/explorations-manifest.json`))
|
||||
const explorations = manifest.explorations.map(exp => ({
|
||||
angle: exp.angle,
|
||||
data: JSON.parse(Read(exp.path))
|
||||
}))
|
||||
|
||||
if (exploration.clarification_needs?.length > 0) {
|
||||
// Aggregate clarification needs from all explorations
|
||||
const allClarifications = []
|
||||
explorations.forEach(exp => {
|
||||
if (exp.data.clarification_needs?.length > 0) {
|
||||
exp.data.clarification_needs.forEach(need => {
|
||||
allClarifications.push({
|
||||
...need,
|
||||
source_angle: exp.angle
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Deduplicate by question similarity
|
||||
function deduplicateClarifications(clarifications) {
|
||||
const unique = []
|
||||
clarifications.forEach(c => {
|
||||
const isDuplicate = unique.some(u =>
|
||||
u.question.toLowerCase() === c.question.toLowerCase()
|
||||
)
|
||||
if (!isDuplicate) unique.push(c)
|
||||
})
|
||||
return unique
|
||||
}
|
||||
|
||||
const uniqueClarifications = deduplicateClarifications(allClarifications)
|
||||
|
||||
if (uniqueClarifications.length > 0) {
|
||||
AskUserQuestion({
|
||||
questions: exploration.clarification_needs.map(need => ({
|
||||
question: `${need.context}\n\n${need.question}`,
|
||||
header: "Clarification",
|
||||
questions: uniqueClarifications.map(need => ({
|
||||
question: `[${need.source_angle}] ${need.question}\n\nContext: ${need.context}`,
|
||||
header: need.source_angle,
|
||||
multiSelect: false,
|
||||
options: need.options.map(opt => ({
|
||||
label: opt,
|
||||
@@ -172,8 +332,17 @@ Generate implementation plan and write plan.json.
|
||||
## Task Description
|
||||
${task_description}
|
||||
|
||||
## Exploration Context
|
||||
${sessionFolder}/exploration.json (if exists)
|
||||
## Multi-Angle Exploration Context
|
||||
|
||||
${manifest.explorations.map(exp => `### Exploration: ${exp.angle} (${exp.file})
|
||||
Path: ${exp.path}
|
||||
|
||||
Read this file for detailed ${exp.angle} analysis.`).join('\n\n')}
|
||||
|
||||
Total explorations: ${manifest.exploration_count}
|
||||
Angles covered: ${manifest.explorations.map(e => e.angle).join(', ')}
|
||||
|
||||
Manifest: ${sessionFolder}/explorations-manifest.json
|
||||
|
||||
## User Clarifications
|
||||
${JSON.stringify(clarificationContext) || "None"}
|
||||
@@ -184,19 +353,23 @@ ${complexity}
|
||||
## Requirements
|
||||
Generate plan.json with:
|
||||
- summary: 2-3 sentence overview
|
||||
- approach: High-level implementation strategy
|
||||
- approach: High-level implementation strategy (incorporating insights from all exploration angles)
|
||||
- tasks: 3-10 structured tasks with:
|
||||
- title, file, action, description
|
||||
- implementation (3-7 steps)
|
||||
- reference (pattern, files, examples)
|
||||
- acceptance (2-4 criteria)
|
||||
- estimated_time, recommended_execution, complexity
|
||||
- _metadata: timestamp, source, planning_mode
|
||||
- _metadata:
|
||||
- timestamp, source, planning_mode
|
||||
- exploration_angles: ${JSON.stringify(manifest.explorations.map(e => e.angle))}
|
||||
|
||||
## Execution
|
||||
1. Execute CLI planning using Gemini (Qwen fallback)
|
||||
2. Parse output and structure plan
|
||||
3. Write JSON: Write('${sessionFolder}/plan.json', jsonContent)
|
||||
1. Read ALL exploration files for comprehensive context
|
||||
2. Execute CLI planning using Gemini (Qwen fallback)
|
||||
3. Synthesize findings from multiple exploration angles
|
||||
4. Parse output and structure plan
|
||||
5. Write JSON: Write('${sessionFolder}/plan.json', jsonContent)
|
||||
4. Return brief completion summary
|
||||
`
|
||||
)
|
||||
@@ -273,9 +446,17 @@ AskUserQuestion({
|
||||
|
||||
```javascript
|
||||
const taskId = `LP-${shortTimestamp}`
|
||||
const exploration = file_exists(`${sessionFolder}/exploration.json`)
|
||||
? JSON.parse(Read(`${sessionFolder}/exploration.json`))
|
||||
: null
|
||||
|
||||
// Load manifest and all exploration files
|
||||
const manifest = JSON.parse(Read(`${sessionFolder}/explorations-manifest.json`))
|
||||
const explorations = {}
|
||||
|
||||
manifest.explorations.forEach(exp => {
|
||||
if (file_exists(exp.path)) {
|
||||
explorations[exp.angle] = JSON.parse(Read(exp.path))
|
||||
}
|
||||
})
|
||||
|
||||
const plan = JSON.parse(Read(`${sessionFolder}/plan.json`))
|
||||
|
||||
const taskJson = {
|
||||
@@ -291,7 +472,9 @@ const taskJson = {
|
||||
recommended_execution: plan.recommended_execution,
|
||||
workflow: "lite-plan",
|
||||
session_id: sessionId,
|
||||
session_folder: sessionFolder
|
||||
session_folder: sessionFolder,
|
||||
exploration_count: manifest.exploration_count,
|
||||
exploration_angles: manifest.explorations.map(e => e.angle)
|
||||
},
|
||||
|
||||
context: {
|
||||
@@ -301,9 +484,25 @@ const taskJson = {
|
||||
approach: plan.approach,
|
||||
tasks: plan.tasks
|
||||
},
|
||||
exploration: exploration,
|
||||
|
||||
// Multi-angle exploration structure
|
||||
explorations: explorations,
|
||||
|
||||
// Exploration files for reference
|
||||
exploration_files: manifest.explorations.map(exp => ({
|
||||
angle: exp.angle,
|
||||
file: exp.file,
|
||||
path: exp.path,
|
||||
index: exp.index
|
||||
})),
|
||||
|
||||
clarifications: clarificationContext || null,
|
||||
focus_paths: exploration?.relevant_files || [],
|
||||
|
||||
// Aggregate relevant files from all exploration angles
|
||||
focus_paths: Array.from(new Set(
|
||||
Object.values(explorations).flatMap(exp => exp.relevant_files || [])
|
||||
)),
|
||||
|
||||
acceptance: plan.tasks.flatMap(t => t.acceptance)
|
||||
}
|
||||
}
|
||||
@@ -316,7 +515,9 @@ Write(`${sessionFolder}/task.json`, JSON.stringify(taskJson, null, 2))
|
||||
```javascript
|
||||
executionContext = {
|
||||
planObject: plan,
|
||||
explorationContext: exploration,
|
||||
explorationsContext: explorations, // Multiple explorations
|
||||
explorationAngles: manifest.explorations.map(e => e.angle),
|
||||
explorationManifest: manifest,
|
||||
clarificationContext: clarificationContext || null,
|
||||
executionMethod: userSelection.execution_method,
|
||||
codeReviewTool: userSelection.code_review_tool,
|
||||
@@ -325,7 +526,11 @@ executionContext = {
|
||||
id: sessionId,
|
||||
folder: sessionFolder,
|
||||
artifacts: {
|
||||
exploration: exploration ? `${sessionFolder}/exploration.json` : null,
|
||||
explorations: manifest.explorations.map(exp => ({
|
||||
angle: exp.angle,
|
||||
path: exp.path
|
||||
})),
|
||||
explorations_manifest: `${sessionFolder}/explorations-manifest.json`,
|
||||
plan: `${sessionFolder}/plan.json`,
|
||||
task: `${sessionFolder}/task.json`
|
||||
}
|
||||
@@ -343,9 +548,24 @@ SlashCommand(command="/workflow:lite-execute --in-memory")
|
||||
|
||||
```
|
||||
.workflow/.lite-plan/{task-slug}-{timestamp}/
|
||||
├── exploration.json # If exploration performed (by cli-explore-agent)
|
||||
├── plan.json # Always created (by agent or direct planning)
|
||||
└── task.json # Always created (by command)
|
||||
├── exploration-{angle1}.json # Exploration angle 1 (agent-decided)
|
||||
├── exploration-{angle2}.json # Exploration angle 2 (agent-decided)
|
||||
├── exploration-{angle3}.json # Exploration angle 3 (if applicable)
|
||||
├── exploration-{angle4}.json # Exploration angle 4 (if applicable)
|
||||
├── explorations-manifest.json # Exploration index
|
||||
├── plan.json # Implementation plan
|
||||
└── task.json # Task definition with multi-exploration refs
|
||||
```
|
||||
|
||||
**Example** (angles decided by agents):
|
||||
```
|
||||
.workflow/.lite-plan/implement-jwt-refresh-2025-11-25-14-30-25/
|
||||
├── exploration-architecture.json
|
||||
├── exploration-auth-patterns.json
|
||||
├── exploration-security.json
|
||||
├── explorations-manifest.json
|
||||
├── plan.json
|
||||
└── task.json
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
Reference in New Issue
Block a user