From 247db0d041b0f85dc64076dc1cc0702026c36bb5 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Wed, 26 Nov 2025 11:31:15 +0800 Subject: [PATCH] Refactor lite-execute and lite-plan workflows to support plan.json format, enhance task structure, and improve exploration angle assignment. Update review cycle dashboard with dimension summary table and associated styles. Modify plan JSON schema to include new properties and adjust validation rules. --- .claude/agents/cli-lite-planning-agent.md | 936 ++++++------------ .claude/commands/workflow/lite-execute.md | 86 +- .claude/commands/workflow/lite-plan.md | 218 ++-- .claude/templates/review-cycle-dashboard.html | 236 +++++ .../schemas/plan-json-schema.json | 107 +- 5 files changed, 759 insertions(+), 824 deletions(-) diff --git a/.claude/agents/cli-lite-planning-agent.md b/.claude/agents/cli-lite-planning-agent.md index 5f060b50..727e1335 100644 --- a/.claude/agents/cli-lite-planning-agent.md +++ b/.claude/agents/cli-lite-planning-agent.md @@ -1,724 +1,396 @@ --- name: cli-lite-planning-agent description: | - Specialized agent for executing CLI planning tools (Gemini/Qwen) to generate detailed implementation plans with actionable task breakdowns. Used by lite-plan workflow for Medium/High complexity tasks requiring structured planning. + Specialized agent for executing CLI planning tools (Gemini/Qwen) to generate detailed implementation plans. Used by lite-plan workflow for Medium/High complexity tasks. Core capabilities: - - Task decomposition into actionable steps (3-10 tasks) - - Dependency analysis and execution sequence - - Integration with exploration context - - Enhancement of conceptual tasks to actionable "how to do" steps - - Examples: - - Context: Medium complexity feature implementation - user: "Generate implementation plan for user authentication feature" - assistant: "Executing Gemini CLI planning → Parsing task breakdown → Generating planObject with 7 actionable tasks" - commentary: Agent transforms conceptual task into specific file operations - - - Context: High complexity refactoring - user: "Generate plan for refactoring logging module with exploration context" - assistant: "Using exploration findings → CLI planning with pattern injection → Generating enhanced planObject" - commentary: Agent leverages exploration context to create pattern-aware, file-specific tasks + - Task decomposition (1-10 tasks with IDs: T1, T2...) + - Dependency analysis (depends_on references) + - Flow control (parallel/sequential phases) + - Multi-angle exploration context integration color: cyan --- -You are a specialized execution agent that bridges CLI planning tools (Gemini/Qwen) with lite-plan workflow. You execute CLI commands for task breakdown, parse structured results, and generate actionable implementation plans (planObject) for downstream execution. +You are a specialized execution agent that bridges CLI planning tools (Gemini/Qwen) with lite-plan workflow. You execute CLI commands for task breakdown, parse structured results, and generate planObject for downstream execution. -## Execution Process +## Output Schema -### Input Processing +**Reference**: `~/.claude/workflows/cli-templates/schemas/plan-json-schema.json` -**What you receive (Context Package)**: +**planObject Structure**: ```javascript { - "task_description": "User's original task description", - "explorationContext": { - "project_structure": "Overall architecture description", - "relevant_files": ["file1.ts", "file2.ts", "..."], - "patterns": "Existing code patterns and conventions", - "dependencies": "Module dependencies and integration points", - "integration_points": "Where to connect with existing code", - "constraints": "Technical constraints and limitations", - "clarification_needs": [] // Used for Phase 2, not needed here - } || null, - "clarificationContext": { - "question1": "answer1", - "question2": "answer2" - } || null, - "complexity": "Low|Medium|High", - "cli_config": { - "tool": "gemini|qwen", - "template": "02-breakdown-task-steps.txt", - "timeout": 3600000, // 60 minutes for planning - "fallback": "qwen" - } + summary: string, // 2-3 sentence overview + approach: string, // High-level strategy + tasks: [TaskObject], // 1-10 structured tasks + flow_control: { // Execution phases + execution_order: [{ phase, tasks, type }], + exit_conditions: { success, failure } + }, + focus_paths: string[], // Affected files (aggregated) + estimated_time: string, + recommended_execution: "Agent" | "Codex", + complexity: "Low" | "Medium" | "High", + _metadata: { timestamp, source, planning_mode, exploration_angles, duration_seconds } } ``` -**Context Enrichment Strategy**: +**TaskObject Structure**: ```javascript -// Merge task description with exploration findings -const enrichedContext = { - task_description: task_description, - relevant_files: explorationContext?.relevant_files || [], - patterns: explorationContext?.patterns || "No patterns identified", - dependencies: explorationContext?.dependencies || "No dependencies identified", - integration_points: explorationContext?.integration_points || "Standalone implementation", - constraints: explorationContext?.constraints || "No constraints identified", - clarifications: clarificationContext || {} +{ + id: string, // T1, T2, T3... + title: string, // Action verb + target + file: string, // Target file path + action: string, // Create|Update|Implement|Refactor|Add|Delete|Configure|Test|Fix + description: string, // What to implement (1-2 sentences) + modification_points: [{ // Precise changes (optional) + file: string, + target: string, // function:lineRange + change: string + }], + implementation: string[], // 2-7 actionable steps + reference: { // Pattern guidance (optional) + pattern: string, + files: string[], + examples: string + }, + acceptance: string[], // 1-4 quantified criteria + depends_on: string[] // Task IDs: ["T1", "T2"] } - -// Generate context summary for CLI prompt -const contextSummary = ` -Exploration Findings: -- Relevant Files: ${enrichedContext.relevant_files.join(', ')} -- Patterns: ${enrichedContext.patterns} -- Dependencies: ${enrichedContext.dependencies} -- Integration: ${enrichedContext.integration_points} -- Constraints: ${enrichedContext.constraints} - -User Clarifications: -${Object.entries(enrichedContext.clarifications).map(([q, a]) => `- ${q}: ${a}`).join('\n')} -` ``` -### Execution Flow (Three-Phase) +## Input Context + +```javascript +{ + task_description: string, + explorationsContext: { [angle]: ExplorationResult } | null, + explorationAngles: string[], + clarificationContext: { [question]: answer } | null, + complexity: "Low" | "Medium" | "High", + cli_config: { tool, template, timeout, fallback }, + session: { id, folder, artifacts } +} +``` + +## Execution Flow ``` -Phase 1: Context Preparation & CLI Execution -1. Validate context package and extract task context -2. Merge task description with exploration and clarification context -3. Construct CLI command with planning template -4. Execute Gemini/Qwen CLI tool with timeout (60 minutes) -5. Handle errors and fallback to alternative tool if needed -6. Save raw CLI output to memory (optional file write for debugging) +Phase 1: CLI Execution +├─ Aggregate multi-angle exploration findings +├─ Construct CLI command with planning template +├─ Execute Gemini (fallback: Qwen → degraded mode) +└─ Timeout: 60 minutes -Phase 2: Results Parsing & Task Enhancement -1. Parse CLI output for structured information: - - Summary (2-3 sentence overview) - - Approach (high-level implementation strategy) - - Task breakdown (3-10 tasks with all 7 fields) - - Estimated time (with breakdown if available) - - Dependencies (task execution order) -2. Enhance tasks to be actionable: - - Add specific file paths from exploration context - - Reference existing patterns - - Transform conceptual tasks into "how to do" steps - - Format: "{Action} in {file_path}: {specific_details} following {pattern}" -3. Validate task quality (action verb + file path + pattern reference) +Phase 2: Parsing & Enhancement +├─ Parse CLI output sections (Summary, Approach, Tasks, Flow Control) +├─ Validate and enhance task objects +└─ Infer missing fields from exploration context Phase 3: planObject Generation -1. Build planObject structure from parsed and enhanced results -2. Map complexity to recommended_execution: - - Low → "Agent" (@code-developer) - - Medium/High → "Codex" (codex CLI tool) -3. Return planObject (in-memory, no file writes) -4. Return success status to orchestrator (lite-plan) +├─ Build planObject from parsed results +├─ Generate flow_control from depends_on if not provided +├─ Aggregate focus_paths from all tasks +└─ Return to orchestrator (lite-plan) +``` + +## CLI Command Template + +```bash +cd {project_root} && {cli_tool} -p " +PURPOSE: Generate implementation plan for {complexity} task +TASK: +• Analyze: {task_description} +• Break down into 1-10 tasks with: id, title, file, action, description, modification_points, implementation, reference, acceptance, depends_on +• Identify parallel vs sequential execution phases +MODE: analysis +CONTEXT: @**/* | Memory: {exploration_summary} +EXPECTED: +## Implementation Summary +[overview] + +## High-Level Approach +[strategy] + +## Task Breakdown +### T1: [Title] +**File**: [path] +**Action**: [type] +**Description**: [what] +**Modification Points**: - [file]: [target] - [change] +**Implementation**: 1. [step] +**Reference**: - Pattern: [name] - Files: [paths] - Examples: [guidance] +**Acceptance**: - [quantified criterion] +**Depends On**: [] + +## Flow Control +**Execution Order**: - Phase parallel-1: [T1, T2] (independent) +**Exit Conditions**: - Success: [condition] - Failure: [condition] + +## Time Estimate +**Total**: [time] + +RULES: $(cat ~/.claude/workflows/cli-templates/prompts/planning/02-breakdown-task-steps.txt) | +- Acceptance must be quantified (counts, method names, metrics) +- Dependencies use task IDs (T1, T2) +- analysis=READ-ONLY +" ``` ## Core Functions -### 1. CLI Planning Execution +### CLI Output Parsing -**Template-Based Command Construction**: -```bash -cd {project_root} && {cli_tool} -p " -PURPOSE: Generate detailed implementation plan for {complexity} complexity task with structured actionable task breakdown -TASK: -• Analyze task requirements: {task_description} -• Break down into 3-10 structured task objects with complete implementation guidance -• For each task, provide: - - Title and target file - - Action type (Create|Update|Implement|Refactor|Add|Delete) - - Description (what to implement) - - Implementation steps (how to do it, 3-7 specific steps) - - Reference (which patterns/files to follow, with specific examples) - - Acceptance criteria (verification checklist) -• Identify dependencies and execution sequence -• Provide realistic time estimates with breakdown -MODE: analysis -CONTEXT: @**/* | Memory: {exploration_context_summary} -EXPECTED: Structured plan with the following format: - -## Implementation Summary -[2-3 sentence overview] - -## High-Level Approach -[Strategy with pattern references] - -## Task Breakdown - -### Task 1: [Title] -**File**: [file/path.ts] -**Action**: [Create|Update|Implement|Refactor|Add|Delete] -**Description**: [What to implement - 1-2 sentences] -**Implementation**: -1. [Specific step 1 - how to do it] -2. [Specific step 2 - concrete action] -3. [Specific step 3 - implementation detail] -4. [Additional steps as needed] -**Reference**: -- Pattern: [Pattern name from exploration context] -- Files: [reference/file1.ts], [reference/file2.ts] -- Examples: [What specifically to copy/follow from reference files] -**Acceptance**: -- [Verification criterion 1] -- [Verification criterion 2] -- [Verification criterion 3] - -[Repeat for each task 2-10] - -## Time Estimate -**Total**: [X-Y hours] -**Breakdown**: Task 1 ([X]min) + Task 2 ([Y]min) + ... - -## Dependencies -- Task 2 depends on Task 1 (requires authentication service) -- Tasks 3-5 can run in parallel -- Task 6 requires all previous tasks - -RULES: $(cat ~/.claude/workflows/cli-templates/prompts/planning/02-breakdown-task-steps.txt) | -- Exploration context: Relevant files: {relevant_files_list} -- Existing patterns: {patterns_summary} -- User clarifications: {clarifications_summary} -- Complexity level: {complexity} -- Each task MUST include all 7 fields: title, file, action, description, implementation, reference, acceptance -- Implementation steps must be concrete and actionable (not conceptual) -- Reference must cite specific files from exploration context -- analysis=READ-ONLY -" {timeout_flag} -``` - -**Error Handling & Fallback Strategy**: ```javascript -// Primary execution with fallback chain -try { - result = executeCLI("gemini", config); -} catch (error) { - if (error.code === 429 || error.code === 404) { - console.log("Gemini unavailable, falling back to Qwen"); - try { - result = executeCLI("qwen", config); - } catch (qwenError) { - console.error("Both Gemini and Qwen failed"); - // Return degraded mode with basic plan - return { - status: "degraded", - message: "CLI planning failed, using fallback strategy", - planObject: generateBasicPlan(task_description, explorationContext) - }; - } - } else { - throw error; - } +// Extract text section by header +function extractSection(cliOutput, header) { + const pattern = new RegExp(`## ${header}\\n([\\s\\S]*?)(?=\\n## |$)`) + const match = pattern.exec(cliOutput) + return match ? match[1].trim() : null } -// Fallback plan generation when all CLI tools fail -function generateBasicPlan(taskDesc, exploration) { - const relevantFiles = exploration?.relevant_files || [] - - // Extract basic tasks from description - const basicTasks = extractTasksFromDescription(taskDesc, relevantFiles) - - return { - summary: `Direct implementation of: ${taskDesc}`, - approach: "Simple step-by-step implementation based on task description", - tasks: basicTasks.map((task, idx) => { - const file = relevantFiles[idx] || "files to be determined" - return { - title: task, - file: file, - action: "Implement", - description: task, - implementation: [ - `Analyze ${file} structure and identify integration points`, - `Implement ${task} following existing patterns`, - `Add error handling and validation`, - `Verify implementation matches requirements` - ], - reference: { - pattern: "Follow existing code structure", - files: relevantFiles.slice(0, 2), - examples: `Study the structure in ${relevantFiles[0] || 'related files'}` - }, - acceptance: [ - `${task} completed in ${file}`, - `Implementation follows project conventions`, - `No breaking changes to existing functionality` - ] - } - }), - estimated_time: `Estimated ${basicTasks.length * 30} minutes (${basicTasks.length} tasks × 30min avg)`, - recommended_execution: "Agent", - complexity: "Low" - } -} - -function extractTasksFromDescription(desc, files) { - // Basic heuristic: split on common separators - const potentialTasks = desc.split(/[,;]|\band\b/) - .map(s => s.trim()) - .filter(s => s.length > 10) - - if (potentialTasks.length >= 3) { - return potentialTasks.slice(0, 10) - } - - // Fallback: create generic tasks - return [ - `Analyze requirements and identify implementation approach`, - `Implement core functionality in ${files[0] || 'main file'}`, - `Add error handling and validation`, - `Create unit tests for new functionality`, - `Update documentation` - ] -} -``` - -### 2. Output Parsing & Enhancement - -**Structured Task Parsing**: -```javascript -// Parse CLI output for structured tasks +// Parse structured tasks from CLI output function extractStructuredTasks(cliOutput) { const tasks = [] - const taskPattern = /### Task \d+: (.+?)\n\*\*File\*\*: (.+?)\n\*\*Action\*\*: (.+?)\n\*\*Description\*\*: (.+?)\n\*\*Implementation\*\*:\n((?:\d+\. .+?\n)+)\*\*Reference\*\*:\n((?:- .+?\n)+)\*\*Acceptance\*\*:\n((?:- .+?\n)+)/g + const taskPattern = /### (T\d+): (.+?)\n\*\*File\*\*: (.+?)\n\*\*Action\*\*: (.+?)\n\*\*Description\*\*: (.+?)\n\*\*Modification Points\*\*:\n((?:- .+?\n)*)\*\*Implementation\*\*:\n((?:\d+\. .+?\n)+)\*\*Reference\*\*:\n((?:- .+?\n)+)\*\*Acceptance\*\*:\n((?:- .+?\n)+)\*\*Depends On\*\*: (.+)/g let match while ((match = taskPattern.exec(cliOutput)) !== null) { - // Parse implementation steps - const implementation = match[5].trim() - .split('\n') - .map(s => s.replace(/^\d+\. /, '')) - .filter(s => s.length > 0) - - // Parse reference fields - const referenceText = match[6].trim() - const patternMatch = /- Pattern: (.+)/m.exec(referenceText) - const filesMatch = /- Files: (.+)/m.exec(referenceText) - const examplesMatch = /- Examples: (.+)/m.exec(referenceText) + // Parse modification points + const modPoints = match[6].trim().split('\n').filter(s => s.startsWith('-')).map(s => { + const m = /- \[(.+?)\]: \[(.+?)\] - (.+)/.exec(s) + return m ? { file: m[1], target: m[2], change: m[3] } : null + }).filter(Boolean) + // Parse reference + const refText = match[8].trim() const reference = { - pattern: patternMatch ? patternMatch[1].trim() : "No pattern specified", - files: filesMatch ? filesMatch[1].split(',').map(f => f.trim()) : [], - examples: examplesMatch ? examplesMatch[1].trim() : "Follow general pattern" + pattern: (/- Pattern: (.+)/m.exec(refText) || [])[1]?.trim() || "No pattern", + files: ((/- Files: (.+)/m.exec(refText) || [])[1] || "").split(',').map(f => f.trim()).filter(Boolean), + examples: (/- Examples: (.+)/m.exec(refText) || [])[1]?.trim() || "Follow general pattern" } - // Parse acceptance criteria - const acceptance = match[7].trim() - .split('\n') - .map(s => s.replace(/^- /, '')) - .filter(s => s.length > 0) + // Parse depends_on + const depsText = match[10].trim() + const depends_on = depsText === '[]' ? [] : depsText.replace(/[\[\]]/g, '').split(',').map(s => s.trim()).filter(Boolean) tasks.push({ - title: match[1].trim(), - file: match[2].trim(), - action: match[3].trim(), - description: match[4].trim(), - implementation: implementation, - reference: reference, - acceptance: acceptance + id: match[1].trim(), + title: match[2].trim(), + file: match[3].trim(), + action: match[4].trim(), + description: match[5].trim(), + modification_points: modPoints, + implementation: match[7].trim().split('\n').map(s => s.replace(/^\d+\. /, '')).filter(Boolean), + reference, + acceptance: match[9].trim().split('\n').map(s => s.replace(/^- /, '')).filter(Boolean), + depends_on }) } - return tasks } -const parsedResults = { - summary: extractSection("Implementation Summary"), - approach: extractSection("High-Level Approach"), - raw_tasks: extractStructuredTasks(cliOutput), - time_estimate: extractSection("Time Estimate"), - dependencies: extractSection("Dependencies") +// Parse flow control section +function extractFlowControl(cliOutput) { + const flowMatch = /## Flow Control\n\*\*Execution Order\*\*:\n((?:- .+?\n)+)/m.exec(cliOutput) + const exitMatch = /\*\*Exit Conditions\*\*:\n- Success: (.+?)\n- Failure: (.+)/m.exec(cliOutput) + + const execution_order = [] + if (flowMatch) { + flowMatch[1].trim().split('\n').forEach(line => { + const m = /- Phase (.+?): \[(.+?)\] \((.+?)\)/.exec(line) + if (m) execution_order.push({ phase: m[1], tasks: m[2].split(',').map(s => s.trim()), type: m[3].includes('independent') ? 'parallel' : 'sequential' }) + }) + } + + return { + execution_order, + exit_conditions: { success: exitMatch?.[1] || "All acceptance criteria met", failure: exitMatch?.[2] || "Critical task fails" } + } +} + +// Parse all sections +function parseCLIOutput(cliOutput) { + return { + summary: extractSection(cliOutput, "Implementation Summary"), + approach: extractSection(cliOutput, "High-Level Approach"), + raw_tasks: extractStructuredTasks(cliOutput), + flow_control: extractFlowControl(cliOutput), + time_estimate: extractSection(cliOutput, "Time Estimate") + } } ``` -**Validation & Enhancement**: +### Context Enrichment + ```javascript -// Validate and enhance tasks if CLI output is incomplete -function validateAndEnhanceTasks(rawTasks, explorationContext) { - return rawTasks.map(taskObj => { - // Validate required fields - const validated = { - title: taskObj.title || "Unnamed task", - file: taskObj.file || inferFileFromContext(taskObj, explorationContext), - action: taskObj.action || inferAction(taskObj.title), - description: taskObj.description || taskObj.title, - implementation: taskObj.implementation?.length > 0 - ? taskObj.implementation - : generateImplementationSteps(taskObj, explorationContext), - reference: taskObj.reference || inferReference(taskObj, explorationContext), - acceptance: taskObj.acceptance?.length > 0 - ? taskObj.acceptance - : generateAcceptanceCriteria(taskObj) +function buildEnrichedContext(explorationsContext, explorationAngles) { + const enriched = { relevant_files: [], patterns: [], dependencies: [], integration_points: [], constraints: [] } + + explorationAngles.forEach(angle => { + const exp = explorationsContext?.[angle] + if (exp) { + enriched.relevant_files.push(...(exp.relevant_files || [])) + enriched.patterns.push(exp.patterns || '') + enriched.dependencies.push(exp.dependencies || '') + enriched.integration_points.push(exp.integration_points || '') + enriched.constraints.push(exp.constraints || '') } - - return validated }) -} -// Helper functions for inference -function inferFileFromContext(taskObj, explorationContext) { - const relevantFiles = explorationContext?.relevant_files || [] - const titleLower = taskObj.title.toLowerCase() - const matchedFile = relevantFiles.find(f => - titleLower.includes(f.split('/').pop().split('.')[0].toLowerCase()) - ) - return matchedFile || "file-to-be-determined.ts" + enriched.relevant_files = [...new Set(enriched.relevant_files)] + return enriched +} +``` + +### Task Enhancement + +```javascript +function validateAndEnhanceTasks(rawTasks, enrichedContext) { + return rawTasks.map((task, idx) => ({ + id: task.id || `T${idx + 1}`, + title: task.title || "Unnamed task", + file: task.file || inferFile(task, enrichedContext), + action: task.action || inferAction(task.title), + description: task.description || task.title, + modification_points: task.modification_points?.length > 0 + ? task.modification_points + : [{ file: task.file, target: "main", change: task.description }], + implementation: task.implementation?.length >= 2 + ? task.implementation + : [`Analyze ${task.file}`, `Implement ${task.title}`, `Add error handling`], + reference: task.reference || { pattern: "existing patterns", files: enrichedContext.relevant_files.slice(0, 2), examples: "Follow existing structure" }, + acceptance: task.acceptance?.length >= 1 + ? task.acceptance + : [`${task.title} completed`, `Follows conventions`], + depends_on: task.depends_on || [] + })) } function inferAction(title) { - if (/create|add new|implement/i.test(title)) return "Create" - if (/update|modify|change/i.test(title)) return "Update" - if (/refactor/i.test(title)) return "Refactor" - if (/delete|remove/i.test(title)) return "Delete" - return "Implement" + const map = { create: "Create", update: "Update", implement: "Implement", refactor: "Refactor", delete: "Delete", config: "Configure", test: "Test", fix: "Fix" } + const match = Object.entries(map).find(([key]) => new RegExp(key, 'i').test(title)) + return match ? match[1] : "Implement" } -function generateImplementationSteps(taskObj, explorationContext) { - const patterns = explorationContext?.patterns || "" - return [ - `Analyze ${taskObj.file} structure and identify integration points`, - `Implement ${taskObj.title} following ${patterns || 'existing patterns'}`, - `Add error handling and validation`, - `Update related components if needed`, - `Verify implementation matches requirements` - ] +function inferFile(task, ctx) { + const files = ctx?.relevant_files || [] + return files.find(f => task.title.toLowerCase().includes(f.split('/').pop().split('.')[0].toLowerCase())) || "file-to-be-determined.ts" } +``` -function inferReference(taskObj, explorationContext) { - const patterns = explorationContext?.patterns || "existing patterns" - const relevantFiles = explorationContext?.relevant_files || [] +### Flow Control Inference + +```javascript +function inferFlowControl(tasks) { + const phases = [], scheduled = new Set() + let num = 1 + + while (scheduled.size < tasks.length) { + const ready = tasks.filter(t => !scheduled.has(t.id) && t.depends_on.every(d => scheduled.has(d))) + if (!ready.length) break + + const isParallel = ready.length > 1 && ready.every(t => !t.depends_on.length) + phases.push({ phase: `${isParallel ? 'parallel' : 'sequential'}-${num}`, tasks: ready.map(t => t.id), type: isParallel ? 'parallel' : 'sequential' }) + ready.forEach(t => scheduled.add(t.id)) + num++ + } + + return { execution_order: phases, exit_conditions: { success: "All acceptance criteria met", failure: "Critical task fails" } } +} +``` + +### planObject Generation + +```javascript +function generatePlanObject(parsed, enrichedContext, input) { + const tasks = validateAndEnhanceTasks(parsed.raw_tasks, enrichedContext) + const flow_control = parsed.flow_control?.execution_order?.length > 0 ? parsed.flow_control : inferFlowControl(tasks) + const focus_paths = [...new Set(tasks.flatMap(t => [t.file, ...t.modification_points.map(m => m.file)]).filter(Boolean))] return { - pattern: patterns.split('.')[0] || "Follow existing code structure", - files: relevantFiles.slice(0, 2), - examples: `Study the structure and methods in ${relevantFiles[0] || 'related files'}` + summary: parsed.summary || `Implementation plan for: ${input.task_description.slice(0, 100)}`, + approach: parsed.approach || "Step-by-step implementation", + tasks, + flow_control, + focus_paths, + estimated_time: parsed.time_estimate || `${tasks.length * 30} minutes`, + recommended_execution: input.complexity === "Low" ? "Agent" : "Codex", + complexity: input.complexity, + _metadata: { timestamp: new Date().toISOString(), source: "cli-lite-planning-agent", planning_mode: "agent-based", exploration_angles: input.explorationAngles || [], duration_seconds: Math.round((Date.now() - startTime) / 1000) } } } - -function generateAcceptanceCriteria(taskObj) { - return [ - `${taskObj.title} completed in ${taskObj.file}`, - `Implementation follows project conventions`, - `No breaking changes to existing functionality`, - `Code passes linting and type checks` - ] -} ``` -### 3. planObject Generation +### Error Handling -**Structure of planObject** (returned to lite-plan): ```javascript -{ - summary: string, // 2-3 sentence overview from CLI - approach: string, // High-level strategy from CLI - tasks: [ // Structured task objects (3-10 items) - { - title: string, // Task title (e.g., "Create AuthService") - file: string, // Target file path - action: string, // Action type: Create|Update|Implement|Refactor|Add|Delete - description: string, // What to implement (1-2 sentences) - implementation: string[], // Step-by-step how to do it (3-7 steps) - reference: { // What to reference - pattern: string, // Pattern name (e.g., "UserService pattern") - files: string[], // Reference file paths - examples: string // Specific guidance on what to copy/follow - }, - acceptance: string[] // Verification criteria (2-4 items) - } - ], - estimated_time: string, // Total time estimate from CLI - recommended_execution: string, // "Agent" | "Codex" based on complexity - complexity: string // "Low" | "Medium" | "High" (from input) -} -``` - -**Generation Logic**: -```javascript -const planObject = { - summary: parsedResults.summary || `Implementation plan for: ${task_description.slice(0, 100)}`, - - approach: parsedResults.approach || "Step-by-step implementation following existing patterns", - - tasks: validateAndEnhanceTasks(parsedResults.raw_tasks, explorationContext), - - estimated_time: parsedResults.time_estimate || estimateTimeFromTaskCount(parsedResults.raw_tasks.length), - - recommended_execution: mapComplexityToExecution(complexity), - - complexity: complexity // Pass through from input +// Fallback chain: Gemini → Qwen → degraded mode +try { + result = executeCLI("gemini", config) +} catch (error) { + if (error.code === 429 || error.code === 404) { + try { result = executeCLI("qwen", config) } + catch { return { status: "degraded", planObject: generateBasicPlan(task_description, enrichedContext) } } + } else throw error } -function mapComplexityToExecution(complexity) { - return complexity === "Low" ? "Agent" : "Codex" -} +function generateBasicPlan(taskDesc, ctx) { + const files = ctx?.relevant_files || [] + const tasks = [taskDesc].map((t, i) => ({ + id: `T${i + 1}`, title: t, file: files[i] || "tbd", action: "Implement", description: t, + modification_points: [{ file: files[i] || "tbd", target: "main", change: t }], + implementation: ["Analyze structure", "Implement feature", "Add validation"], + acceptance: ["Task completed", "Follows conventions"], depends_on: [] + })) -function estimateTimeFromTaskCount(taskCount) { - const avgMinutesPerTask = 30 - const totalMinutes = taskCount * avgMinutesPerTask - const hours = Math.floor(totalMinutes / 60) - const minutes = totalMinutes % 60 - - if (hours === 0) { - return `${minutes} minutes (${taskCount} tasks × ${avgMinutesPerTask}min avg)` + return { + summary: `Direct implementation: ${taskDesc}`, approach: "Step-by-step", tasks, + flow_control: { execution_order: [{ phase: "sequential-1", tasks: tasks.map(t => t.id), type: "sequential" }], exit_conditions: { success: "Done", failure: "Fails" } }, + focus_paths: files, estimated_time: "30 minutes", recommended_execution: "Agent", complexity: "Low", + _metadata: { timestamp: new Date().toISOString(), source: "cli-lite-planning-agent", planning_mode: "direct", exploration_angles: [], duration_seconds: 0 } } - return `${hours}h ${minutes}m (${taskCount} tasks × ${avgMinutesPerTask}min avg)` } ``` ## Quality Standards -### CLI Execution Standards -- **Timeout Management**: Use dynamic timeout (3600000ms = 60min for planning) -- **Fallback Chain**: Gemini → Qwen → degraded mode (if both fail) -- **Error Context**: Include full error details in failure reports -- **Output Preservation**: Optionally save raw CLI output for debugging - -### Task Object Standards - -**Completeness** - Each task must have all 7 required fields: -- **title**: Clear, concise task name -- **file**: Exact file path (from exploration.relevant_files when possible) -- **action**: One of: Create, Update, Implement, Refactor, Add, Delete -- **description**: 1-2 sentence explanation of what to implement -- **implementation**: 3-7 concrete, actionable steps explaining how to do it -- **reference**: Object with pattern, files[], and examples -- **acceptance**: 2-4 verification criteria - -**Implementation Quality** - Steps must be concrete, not conceptual: -- ✓ "Define AuthService class with constructor accepting UserRepository dependency" -- ✗ "Set up the authentication service" - -**Reference Specificity** - Cite actual files from exploration context: -- ✓ `{pattern: "UserService pattern", files: ["src/users/user.service.ts"], examples: "Follow constructor injection and async method patterns"}` -- ✗ `{pattern: "service pattern", files: [], examples: "follow patterns"}` - -**Acceptance Measurability** - Criteria must be verifiable: -- ✓ "AuthService class created with login(), logout(), validateToken() methods" -- ✗ "Service works correctly" - ### Task Validation -**Validation Function**: ```javascript -function validateTaskObject(task) { +function validateTask(task) { const errors = [] - - // Validate required fields - if (!task.title || task.title.trim().length === 0) { - errors.push("Missing title") - } - if (!task.file || task.file.trim().length === 0) { - errors.push("Missing file path") - } - if (!task.action || !['Create', 'Update', 'Implement', 'Refactor', 'Add', 'Delete'].includes(task.action)) { - errors.push(`Invalid action: ${task.action}`) - } - if (!task.description || task.description.trim().length === 0) { - errors.push("Missing description") - } - if (!task.implementation || task.implementation.length < 3) { - errors.push("Implementation must have at least 3 steps") - } - if (!task.reference || !task.reference.pattern) { - errors.push("Missing pattern reference") - } - if (!task.acceptance || task.acceptance.length < 2) { - errors.push("Acceptance criteria must have at least 2 items") - } - - // Check implementation quality - const hasConceptualSteps = task.implementation?.some(step => - /^(handle|manage|deal with|set up|work on)/i.test(step) - ) - if (hasConceptualSteps) { - errors.push("Implementation contains conceptual steps (should be concrete)") - } - - return { - valid: errors.length === 0, - errors: errors - } + if (!/^T\d+$/.test(task.id)) errors.push("Invalid task ID") + if (!task.title?.trim()) errors.push("Missing title") + if (!task.file?.trim()) errors.push("Missing file") + if (!['Create', 'Update', 'Implement', 'Refactor', 'Add', 'Delete', 'Configure', 'Test', 'Fix'].includes(task.action)) errors.push("Invalid action") + if (!task.implementation?.length >= 2) errors.push("Need 2+ implementation steps") + if (!task.acceptance?.length >= 1) errors.push("Need 1+ acceptance criteria") + if (task.depends_on?.some(d => !/^T\d+$/.test(d))) errors.push("Invalid dependency format") + if (task.acceptance?.some(a => /works correctly|good performance/i.test(a))) errors.push("Vague acceptance criteria") + return { valid: !errors.length, errors } } ``` -**Good vs Bad Examples**: -```javascript -// ❌ BAD (Incomplete, vague) -{ - title: "Add authentication", - file: "auth.ts", - action: "Add", - description: "Add auth", - implementation: [ - "Set up authentication", - "Handle login" - ], - reference: { - pattern: "service pattern", - files: [], - examples: "follow patterns" - }, - acceptance: ["It works"] -} +### Acceptance Criteria -// ✅ GOOD (Complete, specific, actionable) -{ - title: "Create AuthService", - file: "src/auth/auth.service.ts", - action: "Create", - description: "Implement authentication service with JWT token management for user login, logout, and token validation", - implementation: [ - "Define AuthService class with constructor accepting UserRepository and JwtUtil dependencies", - "Implement login(email, password) method: validate credentials against database, generate JWT access and refresh tokens on success", - "Implement logout(token) method: invalidate token in Redis store, clear user session", - "Implement validateToken(token) method: verify JWT signature using secret key, check expiration timestamp, return decoded user payload", - "Add error handling for invalid credentials, expired tokens, and database connection failures" - ], - reference: { - pattern: "UserService pattern", - files: ["src/users/user.service.ts", "src/utils/jwt.util.ts"], - examples: "Follow UserService constructor injection pattern with async methods. Use JwtUtil.generateToken() and JwtUtil.verifyToken() for token operations" - }, - acceptance: [ - "AuthService class created with login(), logout(), validateToken() methods", - "Methods follow UserService async/await pattern with try-catch error handling", - "JWT token generation uses JwtUtil with 1h access token and 7d refresh token expiry", - "All methods return typed responses (success/error objects)" - ] -} -``` +| ✓ Good | ✗ Bad | +|--------|-------| +| "3 methods: login(), logout(), validate()" | "Service works correctly" | +| "Response time < 200ms p95" | "Good performance" | +| "Covers 80% of edge cases" | "Properly implemented" | ## Key Reminders -**ALWAYS:** -- **Validate context package**: Ensure task_description present before CLI execution -- **Handle CLI errors gracefully**: Use fallback chain (Gemini → Qwen → degraded mode) -- **Parse CLI output structurally**: Extract all 7 task fields (title, file, action, description, implementation, reference, acceptance) -- **Validate task objects**: Each task must have all required fields with quality content -- **Generate complete planObject**: All fields populated with structured task objects -- **Return in-memory result**: No file writes unless debugging -- **Preserve exploration context**: Use relevant_files and patterns in task references -- **Ensure implementation concreteness**: Steps must be actionable, not conceptual -- **Cite specific references**: Reference actual files from exploration context +**ALWAYS**: +- Generate task IDs (T1, T2, T3...) +- Include depends_on (even if empty []) +- Quantify acceptance criteria +- Generate flow_control from dependencies +- Handle CLI errors with fallback chain -**NEVER:** -- Execute implementation directly (return plan, let lite-execute handle execution) -- Skip CLI planning (always run CLI even for simple tasks, unless degraded mode) -- Return vague task objects (validate all required fields) -- Use conceptual implementation steps ("set up", "handle", "manage") -- Modify files directly (planning only, no implementation) -- Exceed timeout limits (use configured timeout value) -- Return tasks with empty reference files (cite actual exploration files) -- Skip task validation (all task objects must pass quality checks) - -## Configuration & Examples - -### CLI Tool Configuration - -**Gemini Configuration**: -```javascript -{ - "tool": "gemini", - "model": "gemini-2.5-pro", // Auto-selected, no need to specify - "templates": { - "task-breakdown": "02-breakdown-task-steps.txt", - "architecture-planning": "01-plan-architecture-design.txt", - "component-design": "02-design-component-spec.txt" - }, - "timeout": 3600000 // 60 minutes -} -``` - -**Qwen Configuration (Fallback)**: -```javascript -{ - "tool": "qwen", - "model": "coder-model", // Auto-selected - "templates": { - "task-breakdown": "02-breakdown-task-steps.txt", - "architecture-planning": "01-plan-architecture-design.txt" - }, - "timeout": 3600000 // 60 minutes -} -``` - -### Example Execution - -**Input Context**: -```json -{ - "task_description": "Implement user authentication with JWT tokens", - "explorationContext": { - "project_structure": "Express.js REST API with TypeScript, layered architecture (routes → services → repositories)", - "relevant_files": [ - "src/users/user.service.ts", - "src/users/user.repository.ts", - "src/middleware/cors.middleware.ts", - "src/routes/api.ts" - ], - "patterns": "Service-Repository pattern used throughout. Services in src/{module}/{module}.service.ts, Repositories in src/{module}/{module}.repository.ts. Middleware follows function-based approach in src/middleware/", - "dependencies": "Express, TypeORM, bcrypt for password hashing", - "integration_points": "Auth service needs to integrate with existing user service and API routes", - "constraints": "Must use existing TypeORM entities, follow established error handling patterns" - }, - "clarificationContext": { - "token_expiry": "1 hour access token, 7 days refresh token", - "password_requirements": "Min 8 chars, must include number and special char" - }, - "complexity": "Medium", - "cli_config": { - "tool": "gemini", - "template": "02-breakdown-task-steps.txt", - "timeout": 3600000 - } -} -``` - -**Execution Summary**: -1. **Validate Input**: task_description present, explorationContext available -2. **Construct CLI Command**: Gemini with planning template and enriched context -3. **Execute CLI**: Gemini runs and returns structured plan (timeout: 60min) -4. **Parse Output**: Extract summary, approach, tasks (5 structured task objects), time estimate -5. **Enhance Tasks**: Validate all 7 fields per task, infer missing data from exploration context -6. **Generate planObject**: Return complete plan with 5 actionable tasks - -**Output planObject** (simplified): -```javascript -{ - summary: "Implement JWT-based authentication system with service layer, utilities, middleware, and route protection", - approach: "Follow existing Service-Repository pattern. Create AuthService following UserService structure, add JWT utilities, integrate with middleware stack, protect API routes", - tasks: [ - { - title: "Create AuthService", - file: "src/auth/auth.service.ts", - action: "Create", - description: "Implement authentication service with JWT token management for user login, logout, and token validation", - implementation: [ - "Define AuthService class with constructor accepting UserRepository and JwtUtil dependencies", - "Implement login(email, password) method: validate credentials, generate JWT tokens", - "Implement logout(token) method: invalidate token in Redis store", - "Implement validateToken(token) method: verify JWT signature and expiration", - "Add error handling for invalid credentials and expired tokens" - ], - reference: { - pattern: "UserService pattern", - files: ["src/users/user.service.ts"], - examples: "Follow UserService constructor injection pattern with async methods" - }, - acceptance: [ - "AuthService class created with login(), logout(), validateToken() methods", - "Methods follow UserService async/await pattern with try-catch error handling", - "JWT token generation uses 1h access token and 7d refresh token expiry", - "All methods return typed responses" - ] - } - // ... 4 more tasks (JWT utilities, auth middleware, route protection, tests) - ], - estimated_time: "3-4 hours (1h service + 30m utils + 1h middleware + 30m routes + 1h tests)", - recommended_execution: "Codex", - complexity: "Medium" -} -``` +**NEVER**: +- Execute implementation (return plan only) +- Use vague acceptance criteria +- Create circular dependencies +- Skip task validation diff --git a/.claude/commands/workflow/lite-execute.md b/.claude/commands/workflow/lite-execute.md index 39222787..b3cb44df 100644 --- a/.claude/commands/workflow/lite-execute.md +++ b/.claude/commands/workflow/lite-execute.md @@ -92,7 +92,7 @@ AskUserQuestion({ **Trigger**: User calls with file path -**Input**: Path to file containing task description or Enhanced Task JSON +**Input**: Path to file containing task description or plan.json **Step 1: Read and Detect Format** @@ -103,47 +103,30 @@ fileContent = Read(filePath) try { jsonData = JSON.parse(fileContent) - // Check if Enhanced Task JSON from lite-plan - if (jsonData.meta?.workflow === "lite-plan") { - // Extract plan data - planObject = { - summary: jsonData.context.plan.summary, - approach: jsonData.context.plan.approach, - tasks: jsonData.context.plan.tasks, - estimated_time: jsonData.meta.estimated_time, - recommended_execution: jsonData.meta.recommended_execution, - complexity: jsonData.meta.complexity - } - - // Extract multi-angle explorations - explorationsContext = jsonData.context.explorations || null - explorationAngles = jsonData.meta.exploration_angles || [] - explorationFiles = jsonData.context.exploration_files || [] - - clarificationContext = jsonData.context.clarifications || null - originalUserInput = jsonData.title - - isEnhancedTaskJson = true + // Check if plan.json from lite-plan session + if (jsonData.summary && jsonData.approach && jsonData.tasks) { + planObject = jsonData + originalUserInput = jsonData.summary + isPlanJson = true } else { - // Valid JSON but not Enhanced Task JSON - treat as plain text + // Valid JSON but not plan.json - treat as plain text originalUserInput = fileContent - isEnhancedTaskJson = false + isPlanJson = false } } catch { // Not valid JSON - treat as plain text prompt originalUserInput = fileContent - isEnhancedTaskJson = false + isPlanJson = false } ``` **Step 2: Create Execution Plan** -If `isEnhancedTaskJson === true`: -- Use extracted `planObject` directly -- Skip planning, use lite-plan's existing plan -- User still selects execution method and code review +If `isPlanJson === true`: +- Use `planObject` directly +- User selects execution method and code review -If `isEnhancedTaskJson === false`: +If `isPlanJson === false`: - Treat file content as prompt (same behavior as Mode 2) - Create simple execution plan from content @@ -368,7 +351,6 @@ ${result.notes ? `Notes: ${result.notes}` : ''} ).join('\n') || ''} ${executionContext.session.artifacts.explorations_manifest ? `- Manifest: ${executionContext.session.artifacts.explorations_manifest}` : ''} - Plan: ${executionContext.session.artifacts.plan} - - Task: ${executionContext.session.artifacts.task} Read exploration files for comprehensive context from multiple angles.` : ''} @@ -456,7 +438,6 @@ ${executionContext.session.artifacts.explorations?.map(exp => ).join('\n') || ''} ${executionContext.session.artifacts.explorations_manifest ? `- Manifest: ${executionContext.session.artifacts.explorations_manifest}` : ''} - Plan: ${executionContext.session.artifacts.plan} -- Task: ${executionContext.session.artifacts.task} Read exploration files for comprehensive architectural, pattern, and constraint details from multiple angles. ` : ''} @@ -490,58 +471,57 @@ Progress tracked at batch level (not individual task level). Icons: ⚡ (paralle **Skip Condition**: Only run if `codeReviewTool ≠ "Skip"` -**Review Focus**: Verify implementation against task.json acceptance criteria -- Read task.json from session artifacts for acceptance criteria +**Review Focus**: Verify implementation against plan acceptance criteria +- Read plan.json for task acceptance criteria - Check each acceptance criterion is fulfilled - Validate code quality and identify issues - Ensure alignment with planned approach **Operations**: -- Agent Review: Current agent performs direct review (read task.json for acceptance criteria) -- Gemini Review: Execute gemini CLI with review prompt (task.json in CONTEXT) -- Custom tool: Execute specified CLI tool (qwen, codex, etc.) with task.json reference +- Agent Review: Current agent performs direct review +- Gemini Review: Execute gemini CLI with review prompt +- Custom tool: Execute specified CLI tool (qwen, codex, etc.) **Unified Review Template** (All tools use same standard): **Review Criteria**: -- **Acceptance Criteria**: Verify each criterion from task.json `context.acceptance` +- **Acceptance Criteria**: Verify each criterion from plan.tasks[].acceptance - **Code Quality**: Analyze quality, identify issues, suggest improvements - **Plan Alignment**: Validate implementation matches planned approach **Shared Prompt Template** (used by all CLI tools): ``` -PURPOSE: Code review for implemented changes against task.json acceptance criteria -TASK: • Verify task.json acceptance criteria fulfillment • Analyze code quality • Identify issues • Suggest improvements • Validate plan adherence +PURPOSE: Code review for implemented changes against plan acceptance criteria +TASK: • Verify plan acceptance criteria fulfillment • Analyze code quality • Identify issues • Suggest improvements • Validate plan adherence MODE: analysis -CONTEXT: @**/* @{task.json} @{plan.json} [@{exploration.json}] | Memory: Review lite-execute changes against task.json requirements -EXPECTED: Quality assessment with acceptance criteria verification, issue identification, and recommendations. Explicitly check each acceptance criterion from task.json. -RULES: $(cat ~/.claude/workflows/cli-templates/prompts/analysis/02-review-code-quality.txt) | Focus on task.json acceptance criteria and plan adherence | analysis=READ-ONLY +CONTEXT: @**/* @{plan.json} [@{exploration.json}] | Memory: Review lite-execute changes against plan requirements +EXPECTED: Quality assessment with acceptance criteria verification, issue identification, and recommendations. Explicitly check each acceptance criterion from plan.json tasks. +RULES: $(cat ~/.claude/workflows/cli-templates/prompts/analysis/02-review-code-quality.txt) | Focus on plan acceptance criteria and plan adherence | analysis=READ-ONLY ``` **Tool-Specific Execution** (Apply shared prompt template above): ```bash # Method 1: Agent Review (current agent) -# - Read task.json: ${executionContext.session.artifacts.task} +# - Read plan.json: ${executionContext.session.artifacts.plan} # - Apply unified review criteria (see Shared Prompt Template) # - Report findings directly # Method 2: Gemini Review (recommended) gemini -p "[Shared Prompt Template with artifacts]" -# CONTEXT includes: @**/* @${task.json} @${plan.json} [@${exploration.json}] +# CONTEXT includes: @**/* @${plan.json} [@${exploration.json}] # Method 3: Qwen Review (alternative) qwen -p "[Shared Prompt Template with artifacts]" # Same prompt as Gemini, different execution engine # Method 4: Codex Review (autonomous) -codex --full-auto exec "[Verify task.json acceptance criteria at ${task.json}]" --skip-git-repo-check -s danger-full-access +codex --full-auto exec "[Verify plan acceptance criteria at ${plan.json}]" --skip-git-repo-check -s danger-full-access ``` **Implementation Note**: Replace `[Shared Prompt Template with artifacts]` placeholder with actual template content, substituting: -- `@{task.json}` → `@${executionContext.session.artifacts.task}` - `@{plan.json}` → `@${executionContext.session.artifacts.plan}` -- `[@{exploration.json}]` → `@${executionContext.session.artifacts.exploration}` (if exists) +- `[@{exploration.json}]` → exploration files from artifacts (if exists) ## Best Practices @@ -577,7 +557,9 @@ Passed from lite-plan via global variable: recommended_execution: string, complexity: string }, - explorationContext: {...} | null, + explorationsContext: {...} | null, // Multi-angle explorations + explorationAngles: string[], // List of exploration angles + explorationManifest: {...} | null, // Exploration manifest clarificationContext: {...} | null, executionMethod: "Agent" | "Codex" | "Auto", codeReviewTool: "Skip" | "Gemini Review" | "Agent Review" | string, @@ -588,9 +570,9 @@ Passed from lite-plan via global variable: id: string, // Session identifier: {taskSlug}-{shortTimestamp} folder: string, // Session folder path: .workflow/.lite-plan/{session-id} artifacts: { - exploration: string | null, // exploration.json path (if exploration performed) - plan: string, // plan.json path (always present) - task: string // task.json path (always exported) + explorations: [{angle, path}], // exploration-{angle}.json paths + explorations_manifest: string, // explorations-manifest.json path + plan: string // plan.json path (always present) } } } diff --git a/.claude/commands/workflow/lite-plan.md b/.claude/commands/workflow/lite-plan.md index 073d3840..93e8dae9 100644 --- a/.claude/commands/workflow/lite-plan.md +++ b/.claude/commands/workflow/lite-plan.md @@ -104,93 +104,110 @@ function estimateComplexity(taskDescription) { } const complexity = estimateComplexity(task_description) -const explorationCount = complexity === 'High' ? 4 : (complexity === 'Medium' ? 3 : 1) + +// Angle assignment based on task type (orchestrator decides, not agent) +const ANGLE_PRESETS = { + architecture: ['architecture', 'dependencies', 'modularity', 'integration-points'], + security: ['security', 'auth-patterns', 'dataflow', 'validation'], + performance: ['performance', 'bottlenecks', 'caching', 'data-access'], + bugfix: ['error-handling', 'dataflow', 'state-management', 'edge-cases'], + feature: ['patterns', 'integration-points', 'testing', 'dependencies'] +} + +function selectAngles(taskDescription, count) { + const text = taskDescription.toLowerCase() + let preset = 'feature' // default + + if (/refactor|architect|restructure|modular/.test(text)) preset = 'architecture' + else if (/security|auth|permission|access/.test(text)) preset = 'security' + else if (/performance|slow|optimi|cache/.test(text)) preset = 'performance' + else if (/fix|bug|error|issue|broken/.test(text)) preset = 'bugfix' + + return ANGLE_PRESETS[preset].slice(0, count) +} + +const selectedAngles = selectAngles(task_description, complexity === 'High' ? 4 : (complexity === 'Medium' ? 3 : 1)) console.log(` ## Exploration Plan Task Complexity: ${complexity} -Exploration Count: ${explorationCount} angle(s) +Selected Angles: ${selectedAngles.join(', ')} -Starting intelligent multi-angle exploration... +Launching ${selectedAngles.length} parallel explorations... `) ``` -**Launch Parallel Explorations** - Each agent chooses its own angle: +**Launch Parallel Explorations** - Orchestrator assigns angle to each agent: ```javascript -// Launch multiple cli-explore-agent tasks in parallel -const explorationTasks = [] +// Launch agents with pre-assigned angles +const explorationTasks = selectedAngles.map((angle, index) => + Task( + subagent_type="cli-explore-agent", + description=`Explore: ${angle}`, + prompt=` +## Task Objective +Execute **${angle}** exploration for task planning context. Analyze codebase from this specific angle to discover relevant structure, patterns, and constraints. -for (let i = 1; i <= explorationCount; i++) { - explorationTasks.push( - Task( - subagent_type="cli-explore-agent", - description=`Explore angle ${i}/${explorationCount}`, - prompt=` -**以解决任务为目标的智能探索** - 从不同角度分析代码库,为任务规划提供上下文。 +## Assigned Context +- **Exploration Angle**: ${angle} +- **Task Description**: ${task_description} +- **Exploration Index**: ${index + 1} of ${selectedAngles.length} +- **Output File**: ${sessionFolder}/exploration-${angle}.json -## Output Schema Reference -~/.claude/workflows/cli-templates/schemas/explore-json-schema.json +## MANDATORY FIRST STEPS +1. Run: ~/.claude/scripts/get_modules_by_depth.sh (project structure) +2. Run: rg -l "{keyword_from_task}" --type ts (locate relevant files) +3. Read: ~/.claude/workflows/cli-templates/schemas/explore-json-schema.json (output schema) -## Task Description -${task_description} +## Exploration Strategy (${angle} focus) -## Your Mission -You are exploration ${i} of ${explorationCount} parallel explorations. +**Step 1: Structural Scan** (Bash) +- get_modules_by_depth.sh → identify modules related to ${angle} +- find/rg → locate files relevant to ${angle} aspect +- Analyze imports/dependencies from ${angle} perspective -**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 +**Step 2: Semantic Analysis** (Gemini CLI) +- How does existing code handle ${angle} concerns? +- What patterns are used for ${angle}? +- Where would new code integrate from ${angle} viewpoint? -## Output File Naming -Choose a descriptive angle name (lowercase, no spaces, hyphen-separated if needed) -Examples: "architecture", "security", "dataflow", "auth-patterns", "error-handling" +**Step 3: Write Output** +- Consolidate ${angle} findings into JSON +- Identify ${angle}-specific clarification needs -Generate file: exploration-{your-chosen-angle}.json +## Expected Output -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" +**File**: ${sessionFolder}/exploration-${angle}.json -## 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} +**Required Fields** (all ${angle} focused): +- project_structure: Modules/architecture relevant to ${angle} +- relevant_files: Files affected from ${angle} perspective +- patterns: ${angle}-related patterns to follow +- dependencies: Dependencies relevant to ${angle} +- integration_points: Where to integrate from ${angle} viewpoint +- constraints: ${angle}-specific limitations/conventions +- clarification_needs: ${angle}-related ambiguities (with options array) +- _metadata.exploration_angle: "${angle}" -## 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 +## Success Criteria +- [ ] get_modules_by_depth.sh executed +- [ ] At least 3 relevant files identified with ${angle} rationale +- [ ] Patterns are actionable (code examples, not generic advice) +- [ ] Integration points include file:line locations +- [ ] Constraints are project-specific to ${angle} +- [ ] JSON follows schema exactly +- [ ] clarification_needs includes options array -Time Limit: 60 seconds - -**Remember**: Choose a unique, task-relevant angle. Don't duplicate other explorations' focus. +## Output +Write: ${sessionFolder}/exploration-${angle}.json +Return: 2-3 sentence summary of ${angle} findings ` - ) ) -} +) -// Execute all exploration tasks in parallel (single message, multiple tool calls) -console.log(`Launching ${explorationCount} parallel explorations...`) +// Execute all exploration tasks in parallel ``` **Auto-discover Generated Exploration Files**: @@ -442,11 +459,9 @@ AskUserQuestion({ ### Phase 5: Dispatch to Execution -**Step 5.1: Generate task.json** (by command, not agent) +**Step 5.1: Build executionContext** ```javascript -const taskId = `LP-${shortTimestamp}` - // Load manifest and all exploration files const manifest = JSON.parse(Read(`${sessionFolder}/explorations-manifest.json`)) const explorations = {} @@ -459,63 +474,9 @@ manifest.explorations.forEach(exp => { const plan = JSON.parse(Read(`${sessionFolder}/plan.json`)) -const taskJson = { - id: taskId, - title: task_description, - status: "pending", - - meta: { - type: "planning", - created_at: new Date().toISOString(), - complexity: plan.complexity, - estimated_time: plan.estimated_time, - recommended_execution: plan.recommended_execution, - workflow: "lite-plan", - session_id: sessionId, - session_folder: sessionFolder, - exploration_count: manifest.exploration_count, - exploration_angles: manifest.explorations.map(e => e.angle) - }, - - context: { - requirements: [task_description], - plan: { - summary: plan.summary, - approach: plan.approach, - tasks: plan.tasks - }, - - // 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, - - // 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) - } -} - -Write(`${sessionFolder}/task.json`, JSON.stringify(taskJson, null, 2)) -``` - -**Step 5.2: Store executionContext** - -```javascript executionContext = { planObject: plan, - explorationsContext: explorations, // Multiple explorations + explorationsContext: explorations, explorationAngles: manifest.explorations.map(e => e.angle), explorationManifest: manifest, clarificationContext: clarificationContext || null, @@ -531,14 +492,13 @@ executionContext = { path: exp.path })), explorations_manifest: `${sessionFolder}/explorations-manifest.json`, - plan: `${sessionFolder}/plan.json`, - task: `${sessionFolder}/task.json` + plan: `${sessionFolder}/plan.json` } } } ``` -**Step 5.3: Dispatch** +**Step 5.2: Dispatch** ```javascript SlashCommand(command="/workflow:lite-execute --in-memory") @@ -548,24 +508,22 @@ SlashCommand(command="/workflow:lite-execute --in-memory") ``` .workflow/.lite-plan/{task-slug}-{timestamp}/ -├── exploration-{angle1}.json # Exploration angle 1 (agent-decided) -├── exploration-{angle2}.json # Exploration angle 2 (agent-decided) +├── exploration-{angle1}.json # Exploration angle 1 +├── exploration-{angle2}.json # Exploration angle 2 ├── 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 +└── plan.json # Implementation plan ``` -**Example** (angles decided by agents): +**Example**: ``` .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 +└── plan.json ``` ## Error Handling diff --git a/.claude/templates/review-cycle-dashboard.html b/.claude/templates/review-cycle-dashboard.html index c5771a52..4ea9ac5d 100644 --- a/.claude/templates/review-cycle-dashboard.html +++ b/.claude/templates/review-cycle-dashboard.html @@ -579,6 +579,135 @@ text-transform: uppercase; } + /* Dimension Summary Table */ + .dimension-summary-section { + background-color: var(--bg-card); + padding: 25px; + border-radius: 8px; + box-shadow: var(--shadow); + margin-bottom: 30px; + } + + .dimension-summary-header { + font-size: 1.1rem; + font-weight: 600; + margin-bottom: 20px; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .dimension-summary-table { + width: 100%; + border-collapse: collapse; + } + + .dimension-summary-table th { + text-align: left; + padding: 12px 16px; + font-size: 0.75rem; + font-weight: 600; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; + border-bottom: 1px solid var(--border-color); + } + + .dimension-summary-table th:not(:first-child) { + text-align: center; + } + + .dimension-summary-table td { + padding: 16px; + border-bottom: 1px solid var(--border-color); + } + + .dimension-summary-table td:not(:first-child) { + text-align: center; + } + + .dimension-summary-table tr:last-child td { + border-bottom: none; + } + + .dimension-summary-table tr:hover { + background-color: var(--bg-primary); + } + + .dimension-name { + display: flex; + align-items: center; + gap: 10px; + font-weight: 500; + } + + .dimension-icon { + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 6px; + font-size: 0.9rem; + } + + .dimension-icon.security { background-color: rgba(239, 68, 68, 0.15); color: #ef4444; } + .dimension-icon.architecture { background-color: rgba(139, 92, 246, 0.15); color: #8b5cf6; } + .dimension-icon.quality { background-color: rgba(34, 197, 94, 0.15); color: #22c55e; } + .dimension-icon.action-items { background-color: rgba(59, 130, 246, 0.15); color: #3b82f6; } + .dimension-icon.performance { background-color: rgba(234, 179, 8, 0.15); color: #eab308; } + .dimension-icon.maintainability { background-color: rgba(236, 72, 153, 0.15); color: #ec4899; } + .dimension-icon.best-practices { background-color: rgba(249, 115, 22, 0.15); color: #f97316; } + + .count-badge { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 28px; + height: 28px; + padding: 0 8px; + border-radius: 14px; + font-size: 0.85rem; + font-weight: 600; + } + + .count-badge.critical { background-color: rgba(197, 48, 48, 0.2); color: var(--critical-color); } + .count-badge.high { background-color: rgba(245, 101, 101, 0.2); color: var(--high-color); } + .count-badge.medium { background-color: rgba(237, 137, 54, 0.2); color: var(--medium-color); } + .count-badge.low { background-color: rgba(72, 187, 120, 0.2); color: var(--low-color); } + .count-badge.total { background-color: var(--bg-primary); color: var(--text-primary); font-weight: 700; } + + .count-badge.zero { + background-color: transparent; + color: var(--text-secondary); + opacity: 0.5; + } + + .status-indicator { + display: inline-flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: 50%; + } + + .status-indicator.reviewed { + background-color: var(--success-color); + color: white; + } + + .status-indicator.pending { + background-color: var(--border-color); + color: var(--text-secondary); + } + + .status-indicator.in-progress { + background-color: var(--accent-color); + color: white; + animation: pulse 2s infinite; + } + /* Progress Indicator */ .progress-section { background-color: var(--bg-card); @@ -1116,6 +1245,27 @@ + +
+
Findings by Dimension
+ + + + + + + + + + + + + + + +
DimensionCriticalHighMediumLowTotalStatus
+
+
@@ -1881,6 +2031,9 @@ } }); + // Update dimension summary table + updateDimensionSummary(); + renderFindings(); } catch (error) { console.error('Error loading final results:', error); @@ -1895,6 +2048,89 @@ document.getElementById('lowCount').textContent = distribution.low || 0; } + // Dimension summary table configuration + const dimensionConfig = { + 'security': { icon: '🔒', label: 'Security' }, + 'architecture': { icon: '🏛', label: 'Architecture' }, + 'quality': { icon: '✅', label: 'Quality' }, + 'action-items': { icon: '📋', label: 'Action-Items' }, + 'performance': { icon: '⚡', label: 'Performance' }, + 'maintainability': { icon: '🔧', label: 'Maintainability' }, + 'best-practices': { icon: '📚', label: 'Best-Practices' } + }; + + // Update dimension summary table + function updateDimensionSummary() { + const tbody = document.getElementById('dimensionSummaryBody'); + if (!tbody) return; + + // Get all dimension names from config + const dimensions = Object.keys(dimensionConfig); + + // Calculate counts per dimension + const dimensionStats = {}; + dimensions.forEach(dim => { + dimensionStats[dim] = { critical: 0, high: 0, medium: 0, low: 0, total: 0, reviewed: false }; + }); + + // Aggregate findings by dimension + allFindings.forEach(finding => { + const dim = finding.dimension; + if (dimensionStats[dim]) { + const severity = finding.severity.toLowerCase(); + if (dimensionStats[dim][severity] !== undefined) { + dimensionStats[dim][severity]++; + } + dimensionStats[dim].total++; + } + }); + + // Check reviewed status from reviewState + if (reviewState && reviewState.dimensions_reviewed) { + reviewState.dimensions_reviewed.forEach(dim => { + if (dimensionStats[dim]) { + dimensionStats[dim].reviewed = true; + } + }); + } + + // Generate table rows + const rows = dimensions.map(dim => { + const config = dimensionConfig[dim]; + const stats = dimensionStats[dim]; + const hasFindings = stats.total > 0; + + // Create count badge with appropriate styling + const createCountBadge = (count, severity) => { + const zeroClass = count === 0 ? ' zero' : ''; + return `${count}`; + }; + + // Status indicator + const statusClass = stats.reviewed ? 'reviewed' : 'pending'; + const statusIcon = stats.reviewed ? '✓' : '○'; + + return ` + + +
+
${config.icon}
+ ${config.label} +
+ + ${createCountBadge(stats.critical, 'critical')} + ${createCountBadge(stats.high, 'high')} + ${createCountBadge(stats.medium, 'medium')} + ${createCountBadge(stats.low, 'low')} + ${stats.total} + ${statusIcon} + + `; + }).join(''); + + tbody.innerHTML = rows; + } + // Filter functions function filterByDimension(dimension) { currentFilters.dimension = dimension; diff --git a/.claude/workflows/cli-templates/schemas/plan-json-schema.json b/.claude/workflows/cli-templates/schemas/plan-json-schema.json index 652bfb42..6fecbcb3 100644 --- a/.claude/workflows/cli-templates/schemas/plan-json-schema.json +++ b/.claude/workflows/cli-templates/schemas/plan-json-schema.json @@ -23,12 +23,17 @@ }, "tasks": { "type": "array", - "minItems": 3, + "minItems": 1, "maxItems": 10, "items": { "type": "object", - "required": ["title", "file", "action", "description", "implementation", "reference", "acceptance"], + "required": ["id", "title", "file", "action", "description", "implementation", "acceptance"], "properties": { + "id": { + "type": "string", + "pattern": "^T[0-9]+$", + "description": "Task identifier (T1, T2, T3...)" + }, "title": { "type": "string", "description": "Task title (action verb + target)" @@ -39,23 +44,44 @@ }, "action": { "type": "string", - "enum": ["Create", "Update", "Implement", "Refactor", "Add", "Delete", "Configure", "Test"], + "enum": ["Create", "Update", "Implement", "Refactor", "Add", "Delete", "Configure", "Test", "Fix"], "description": "Primary action type" }, "description": { "type": "string", "description": "What to implement (1-2 sentences)" }, + "modification_points": { + "type": "array", + "items": { + "type": "object", + "required": ["file", "target", "change"], + "properties": { + "file": { + "type": "string", + "description": "File path" + }, + "target": { + "type": "string", + "description": "Function/class/line range (e.g., 'validateToken:45-60')" + }, + "change": { + "type": "string", + "description": "Brief description of change" + } + } + }, + "description": "Precise modification points with file:target:change format" + }, "implementation": { "type": "array", "items": {"type": "string"}, - "minItems": 3, + "minItems": 2, "maxItems": 7, "description": "Step-by-step implementation guide" }, "reference": { "type": "object", - "required": ["pattern", "files", "examples"], "properties": { "pattern": { "type": "string", @@ -71,18 +97,74 @@ "description": "Specific guidance or example references" } }, - "description": "Reference materials for implementation" + "description": "Reference materials for implementation (optional)" }, "acceptance": { "type": "array", "items": {"type": "string"}, - "minItems": 2, + "minItems": 1, "maxItems": 4, - "description": "Verification criteria for task completion" + "description": "Verification criteria (quantified, testable)" + }, + "depends_on": { + "type": "array", + "items": { + "type": "string", + "pattern": "^T[0-9]+$" + }, + "description": "Task IDs this task depends on (e.g., ['T1', 'T2'])" } } }, - "description": "Structured task breakdown (3-10 tasks)" + "description": "Structured task breakdown (1-10 tasks)" + }, + "flow_control": { + "type": "object", + "properties": { + "execution_order": { + "type": "array", + "items": { + "type": "object", + "properties": { + "phase": { + "type": "string", + "description": "Phase name (e.g., 'parallel-1', 'sequential-1')" + }, + "tasks": { + "type": "array", + "items": {"type": "string"}, + "description": "Task IDs in this phase" + }, + "type": { + "type": "string", + "enum": ["parallel", "sequential"], + "description": "Execution type" + } + } + }, + "description": "Ordered execution phases" + }, + "exit_conditions": { + "type": "object", + "properties": { + "success": { + "type": "string", + "description": "Condition for successful completion" + }, + "failure": { + "type": "string", + "description": "Condition that indicates failure" + } + }, + "description": "Conditions for workflow termination" + } + }, + "description": "Execution flow control (optional, auto-inferred from depends_on if not provided)" + }, + "focus_paths": { + "type": "array", + "items": {"type": "string"}, + "description": "Key file paths affected by this plan (aggregated from tasks)" }, "estimated_time": { "type": "string", @@ -100,7 +182,7 @@ }, "_metadata": { "type": "object", - "required": ["timestamp", "source", "planning_mode"], + "required": ["timestamp", "source"], "properties": { "timestamp": { "type": "string", @@ -117,6 +199,11 @@ "enum": ["direct", "agent-based"], "description": "Planning execution mode" }, + "exploration_angles": { + "type": "array", + "items": {"type": "string"}, + "description": "Exploration angles used for context" + }, "duration_seconds": { "type": "integer", "description": "Planning duration in seconds"