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.

This commit is contained in:
catlog22
2025-11-26 11:31:15 +08:00
parent fec5d9a605
commit 247db0d041
5 changed files with 759 additions and 824 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -92,7 +92,7 @@ AskUserQuestion({
**Trigger**: User calls with file path **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** **Step 1: Read and Detect Format**
@@ -103,47 +103,30 @@ fileContent = Read(filePath)
try { try {
jsonData = JSON.parse(fileContent) jsonData = JSON.parse(fileContent)
// Check if Enhanced Task JSON from lite-plan // Check if plan.json from lite-plan session
if (jsonData.meta?.workflow === "lite-plan") { if (jsonData.summary && jsonData.approach && jsonData.tasks) {
// Extract plan data planObject = jsonData
planObject = { originalUserInput = jsonData.summary
summary: jsonData.context.plan.summary, isPlanJson = true
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
} else { } else {
// Valid JSON but not Enhanced Task JSON - treat as plain text // Valid JSON but not plan.json - treat as plain text
originalUserInput = fileContent originalUserInput = fileContent
isEnhancedTaskJson = false isPlanJson = false
} }
} catch { } catch {
// Not valid JSON - treat as plain text prompt // Not valid JSON - treat as plain text prompt
originalUserInput = fileContent originalUserInput = fileContent
isEnhancedTaskJson = false isPlanJson = false
} }
``` ```
**Step 2: Create Execution Plan** **Step 2: Create Execution Plan**
If `isEnhancedTaskJson === true`: If `isPlanJson === true`:
- Use extracted `planObject` directly - Use `planObject` directly
- Skip planning, use lite-plan's existing plan - User selects execution method and code review
- User still selects execution method and code review
If `isEnhancedTaskJson === false`: If `isPlanJson === false`:
- Treat file content as prompt (same behavior as Mode 2) - Treat file content as prompt (same behavior as Mode 2)
- Create simple execution plan from content - Create simple execution plan from content
@@ -368,7 +351,6 @@ ${result.notes ? `Notes: ${result.notes}` : ''}
).join('\n') || ''} ).join('\n') || ''}
${executionContext.session.artifacts.explorations_manifest ? `- Manifest: ${executionContext.session.artifacts.explorations_manifest}` : ''} ${executionContext.session.artifacts.explorations_manifest ? `- Manifest: ${executionContext.session.artifacts.explorations_manifest}` : ''}
- Plan: ${executionContext.session.artifacts.plan} - Plan: ${executionContext.session.artifacts.plan}
- Task: ${executionContext.session.artifacts.task}
Read exploration files for comprehensive context from multiple angles.` : ''} Read exploration files for comprehensive context from multiple angles.` : ''}
@@ -456,7 +438,6 @@ ${executionContext.session.artifacts.explorations?.map(exp =>
).join('\n') || ''} ).join('\n') || ''}
${executionContext.session.artifacts.explorations_manifest ? `- Manifest: ${executionContext.session.artifacts.explorations_manifest}` : ''} ${executionContext.session.artifacts.explorations_manifest ? `- Manifest: ${executionContext.session.artifacts.explorations_manifest}` : ''}
- Plan: ${executionContext.session.artifacts.plan} - Plan: ${executionContext.session.artifacts.plan}
- Task: ${executionContext.session.artifacts.task}
Read exploration files for comprehensive architectural, pattern, and constraint details from multiple angles. 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"` **Skip Condition**: Only run if `codeReviewTool ≠ "Skip"`
**Review Focus**: Verify implementation against task.json acceptance criteria **Review Focus**: Verify implementation against plan acceptance criteria
- Read task.json from session artifacts for acceptance criteria - Read plan.json for task acceptance criteria
- Check each acceptance criterion is fulfilled - Check each acceptance criterion is fulfilled
- Validate code quality and identify issues - Validate code quality and identify issues
- Ensure alignment with planned approach - Ensure alignment with planned approach
**Operations**: **Operations**:
- Agent Review: Current agent performs direct review (read task.json for acceptance criteria) - Agent Review: Current agent performs direct review
- Gemini Review: Execute gemini CLI with review prompt (task.json in CONTEXT) - Gemini Review: Execute gemini CLI with review prompt
- Custom tool: Execute specified CLI tool (qwen, codex, etc.) with task.json reference - Custom tool: Execute specified CLI tool (qwen, codex, etc.)
**Unified Review Template** (All tools use same standard): **Unified Review Template** (All tools use same standard):
**Review Criteria**: **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 - **Code Quality**: Analyze quality, identify issues, suggest improvements
- **Plan Alignment**: Validate implementation matches planned approach - **Plan Alignment**: Validate implementation matches planned approach
**Shared Prompt Template** (used by all CLI tools): **Shared Prompt Template** (used by all CLI tools):
``` ```
PURPOSE: Code review for implemented changes against task.json acceptance criteria PURPOSE: Code review for implemented changes against plan acceptance criteria
TASK: • Verify task.json acceptance criteria fulfillment • Analyze code quality • Identify issues • Suggest improvements • Validate plan adherence TASK: • Verify plan acceptance criteria fulfillment • Analyze code quality • Identify issues • Suggest improvements • Validate plan adherence
MODE: analysis MODE: analysis
CONTEXT: @**/* @{task.json} @{plan.json} [@{exploration.json}] | Memory: Review lite-execute changes against task.json requirements 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 task.json. 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 task.json acceptance criteria and plan adherence | analysis=READ-ONLY 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): **Tool-Specific Execution** (Apply shared prompt template above):
```bash ```bash
# Method 1: Agent Review (current agent) # 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) # - Apply unified review criteria (see Shared Prompt Template)
# - Report findings directly # - Report findings directly
# Method 2: Gemini Review (recommended) # Method 2: Gemini Review (recommended)
gemini -p "[Shared Prompt Template with artifacts]" 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) # Method 3: Qwen Review (alternative)
qwen -p "[Shared Prompt Template with artifacts]" qwen -p "[Shared Prompt Template with artifacts]"
# Same prompt as Gemini, different execution engine # Same prompt as Gemini, different execution engine
# Method 4: Codex Review (autonomous) # 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: **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}` - `@{plan.json}``@${executionContext.session.artifacts.plan}`
- `[@{exploration.json}]``@${executionContext.session.artifacts.exploration}` (if exists) - `[@{exploration.json}]`exploration files from artifacts (if exists)
## Best Practices ## Best Practices
@@ -577,7 +557,9 @@ Passed from lite-plan via global variable:
recommended_execution: string, recommended_execution: string,
complexity: string complexity: string
}, },
explorationContext: {...} | null, explorationsContext: {...} | null, // Multi-angle explorations
explorationAngles: string[], // List of exploration angles
explorationManifest: {...} | null, // Exploration manifest
clarificationContext: {...} | null, clarificationContext: {...} | null,
executionMethod: "Agent" | "Codex" | "Auto", executionMethod: "Agent" | "Codex" | "Auto",
codeReviewTool: "Skip" | "Gemini Review" | "Agent Review" | string, codeReviewTool: "Skip" | "Gemini Review" | "Agent Review" | string,
@@ -588,9 +570,9 @@ Passed from lite-plan via global variable:
id: string, // Session identifier: {taskSlug}-{shortTimestamp} id: string, // Session identifier: {taskSlug}-{shortTimestamp}
folder: string, // Session folder path: .workflow/.lite-plan/{session-id} folder: string, // Session folder path: .workflow/.lite-plan/{session-id}
artifacts: { artifacts: {
exploration: string | null, // exploration.json path (if exploration performed) explorations: [{angle, path}], // exploration-{angle}.json paths
plan: string, // plan.json path (always present) explorations_manifest: string, // explorations-manifest.json path
task: string // task.json path (always exported) plan: string // plan.json path (always present)
} }
} }
} }

View File

@@ -104,93 +104,110 @@ function estimateComplexity(taskDescription) {
} }
const complexity = estimateComplexity(task_description) 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(` console.log(`
## Exploration Plan ## Exploration Plan
Task Complexity: ${complexity} 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 ```javascript
// Launch multiple cli-explore-agent tasks in parallel // Launch agents with pre-assigned angles
const explorationTasks = [] 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++) { ## Assigned Context
explorationTasks.push( - **Exploration Angle**: ${angle}
Task( - **Task Description**: ${task_description}
subagent_type="cli-explore-agent", - **Exploration Index**: ${index + 1} of ${selectedAngles.length}
description=`Explore angle ${i}/${explorationCount}`, - **Output File**: ${sessionFolder}/exploration-${angle}.json
prompt=`
**以解决任务为目标的智能探索** - 从不同角度分析代码库,为任务规划提供上下文。
## Output Schema Reference ## MANDATORY FIRST STEPS
~/.claude/workflows/cli-templates/schemas/explore-json-schema.json 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 ## Exploration Strategy (${angle} focus)
${task_description}
## Your Mission **Step 1: Structural Scan** (Bash)
You are exploration ${i} of ${explorationCount} parallel explorations. - 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: **Step 2: Semantic Analysis** (Gemini CLI)
- Choose different angles from what other explorations might cover - How does existing code handle ${angle} concerns?
- Focus on aspects critical for task success - What patterns are used for ${angle}?
- Examples: architecture, security, dataflow, patterns, performance, dependencies, testing, error-handling, state-management, etc. - Where would new code integrate from ${angle} viewpoint?
- Be creative and task-driven - not limited to examples above
## Output File Naming **Step 3: Write Output**
Choose a descriptive angle name (lowercase, no spaces, hyphen-separated if needed) - Consolidate ${angle} findings into JSON
Examples: "architecture", "security", "dataflow", "auth-patterns", "error-handling" - Identify ${angle}-specific clarification needs
Generate file: exploration-{your-chosen-angle}.json ## Expected Output
Example angles based on task type: **File**: ${sessionFolder}/exploration-${angle}.json
- Architecture refactoring → "architecture", "modularity", "dependencies"
- Security feature → "security", "auth-patterns", "dataflow"
- Performance fix → "performance", "bottlenecks", "caching"
- Bug fix → "error-handling", "dataflow", "state-management"
## Requirements **Required Fields** (all ${angle} focused):
Generate exploration-{angle}.json with: - project_structure: Modules/architecture relevant to ${angle}
- project_structure: Architecture and module organization relevant to your angle - relevant_files: Files affected from ${angle} perspective
- relevant_files: File paths to be affected - patterns: ${angle}-related patterns to follow
- patterns: Code patterns relevant to your angle - dependencies: Dependencies relevant to ${angle}
- dependencies: Dependencies relevant to your angle - integration_points: Where to integrate from ${angle} viewpoint
- integration_points: Integration points from your angle's viewpoint - constraints: ${angle}-specific limitations/conventions
- constraints: Constraints related to your angle - clarification_needs: ${angle}-related ambiguities (with options array)
- clarification_needs: Ambiguities requiring user input - _metadata.exploration_angle: "${angle}"
- _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 ## Success Criteria
1. Decide your unique exploration angle based on task needs - [ ] get_modules_by_depth.sh executed
2. Structural scan: get_modules_by_depth.sh, find, rg (focused on your angle) - [ ] At least 3 relevant files identified with ${angle} rationale
3. Semantic analysis: Use Gemini for patterns/architecture specific to your angle - [ ] Patterns are actionable (code examples, not generic advice)
4. Write JSON: Write('${sessionFolder}/exploration-{your-angle}.json', jsonContent) - [ ] Integration points include file:line locations
5. Return: Brief summary stating your chosen angle and key findings - [ ] Constraints are project-specific to ${angle}
- [ ] JSON follows schema exactly
- [ ] clarification_needs includes options array
Time Limit: 60 seconds ## Output
Write: ${sessionFolder}/exploration-${angle}.json
**Remember**: Choose a unique, task-relevant angle. Don't duplicate other explorations' focus. Return: 2-3 sentence summary of ${angle} findings
` `
)
) )
} )
// Execute all exploration tasks in parallel (single message, multiple tool calls) // Execute all exploration tasks in parallel
console.log(`Launching ${explorationCount} parallel explorations...`)
``` ```
**Auto-discover Generated Exploration Files**: **Auto-discover Generated Exploration Files**:
@@ -442,11 +459,9 @@ AskUserQuestion({
### Phase 5: Dispatch to Execution ### Phase 5: Dispatch to Execution
**Step 5.1: Generate task.json** (by command, not agent) **Step 5.1: Build executionContext**
```javascript ```javascript
const taskId = `LP-${shortTimestamp}`
// Load manifest and all exploration files // Load manifest and all exploration files
const manifest = JSON.parse(Read(`${sessionFolder}/explorations-manifest.json`)) const manifest = JSON.parse(Read(`${sessionFolder}/explorations-manifest.json`))
const explorations = {} const explorations = {}
@@ -459,63 +474,9 @@ manifest.explorations.forEach(exp => {
const plan = JSON.parse(Read(`${sessionFolder}/plan.json`)) 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 = { executionContext = {
planObject: plan, planObject: plan,
explorationsContext: explorations, // Multiple explorations explorationsContext: explorations,
explorationAngles: manifest.explorations.map(e => e.angle), explorationAngles: manifest.explorations.map(e => e.angle),
explorationManifest: manifest, explorationManifest: manifest,
clarificationContext: clarificationContext || null, clarificationContext: clarificationContext || null,
@@ -531,14 +492,13 @@ executionContext = {
path: exp.path path: exp.path
})), })),
explorations_manifest: `${sessionFolder}/explorations-manifest.json`, explorations_manifest: `${sessionFolder}/explorations-manifest.json`,
plan: `${sessionFolder}/plan.json`, plan: `${sessionFolder}/plan.json`
task: `${sessionFolder}/task.json`
} }
} }
} }
``` ```
**Step 5.3: Dispatch** **Step 5.2: Dispatch**
```javascript ```javascript
SlashCommand(command="/workflow:lite-execute --in-memory") SlashCommand(command="/workflow:lite-execute --in-memory")
@@ -548,24 +508,22 @@ SlashCommand(command="/workflow:lite-execute --in-memory")
``` ```
.workflow/.lite-plan/{task-slug}-{timestamp}/ .workflow/.lite-plan/{task-slug}-{timestamp}/
├── exploration-{angle1}.json # Exploration angle 1 (agent-decided) ├── exploration-{angle1}.json # Exploration angle 1
├── exploration-{angle2}.json # Exploration angle 2 (agent-decided) ├── exploration-{angle2}.json # Exploration angle 2
├── exploration-{angle3}.json # Exploration angle 3 (if applicable) ├── exploration-{angle3}.json # Exploration angle 3 (if applicable)
├── exploration-{angle4}.json # Exploration angle 4 (if applicable) ├── exploration-{angle4}.json # Exploration angle 4 (if applicable)
├── explorations-manifest.json # Exploration index ├── explorations-manifest.json # Exploration index
── plan.json # Implementation plan ── plan.json # Implementation plan
└── task.json # Task definition with multi-exploration refs
``` ```
**Example** (angles decided by agents): **Example**:
``` ```
.workflow/.lite-plan/implement-jwt-refresh-2025-11-25-14-30-25/ .workflow/.lite-plan/implement-jwt-refresh-2025-11-25-14-30-25/
├── exploration-architecture.json ├── exploration-architecture.json
├── exploration-auth-patterns.json ├── exploration-auth-patterns.json
├── exploration-security.json ├── exploration-security.json
├── explorations-manifest.json ├── explorations-manifest.json
── plan.json ── plan.json
└── task.json
``` ```
## Error Handling ## Error Handling

View File

@@ -579,6 +579,135 @@
text-transform: uppercase; 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 Indicator */
.progress-section { .progress-section {
background-color: var(--bg-card); background-color: var(--bg-card);
@@ -1116,6 +1245,27 @@
</div> </div>
</div> </div>
<!-- Dimension Summary Table -->
<div class="dimension-summary-section">
<div class="dimension-summary-header">Findings by Dimension</div>
<table class="dimension-summary-table">
<thead>
<tr>
<th>Dimension</th>
<th>Critical</th>
<th>High</th>
<th>Medium</th>
<th>Low</th>
<th>Total</th>
<th>Status</th>
</tr>
</thead>
<tbody id="dimensionSummaryBody">
<!-- Populated by JavaScript -->
</tbody>
</table>
</div>
<!-- Dimension Tabs --> <!-- Dimension Tabs -->
<div class="dimension-tabs" id="dimensionTabs"> <div class="dimension-tabs" id="dimensionTabs">
<button class="tab active" data-dimension="all" onclick="filterByDimension('all')">All Findings</button> <button class="tab active" data-dimension="all" onclick="filterByDimension('all')">All Findings</button>
@@ -1881,6 +2031,9 @@
} }
}); });
// Update dimension summary table
updateDimensionSummary();
renderFindings(); renderFindings();
} catch (error) { } catch (error) {
console.error('Error loading final results:', error); console.error('Error loading final results:', error);
@@ -1895,6 +2048,89 @@
document.getElementById('lowCount').textContent = distribution.low || 0; 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 `<span class="count-badge ${severity}${zeroClass}">${count}</span>`;
};
// Status indicator
const statusClass = stats.reviewed ? 'reviewed' : 'pending';
const statusIcon = stats.reviewed ? '✓' : '○';
return `
<tr onclick="filterByDimension('${dim}')" style="cursor: pointer;">
<td>
<div class="dimension-name">
<div class="dimension-icon ${dim}">${config.icon}</div>
<span>${config.label}</span>
</div>
</td>
<td>${createCountBadge(stats.critical, 'critical')}</td>
<td>${createCountBadge(stats.high, 'high')}</td>
<td>${createCountBadge(stats.medium, 'medium')}</td>
<td>${createCountBadge(stats.low, 'low')}</td>
<td><span class="count-badge total">${stats.total}</span></td>
<td><span class="status-indicator ${statusClass}">${statusIcon}</span></td>
</tr>
`;
}).join('');
tbody.innerHTML = rows;
}
// Filter functions // Filter functions
function filterByDimension(dimension) { function filterByDimension(dimension) {
currentFilters.dimension = dimension; currentFilters.dimension = dimension;

View File

@@ -23,12 +23,17 @@
}, },
"tasks": { "tasks": {
"type": "array", "type": "array",
"minItems": 3, "minItems": 1,
"maxItems": 10, "maxItems": 10,
"items": { "items": {
"type": "object", "type": "object",
"required": ["title", "file", "action", "description", "implementation", "reference", "acceptance"], "required": ["id", "title", "file", "action", "description", "implementation", "acceptance"],
"properties": { "properties": {
"id": {
"type": "string",
"pattern": "^T[0-9]+$",
"description": "Task identifier (T1, T2, T3...)"
},
"title": { "title": {
"type": "string", "type": "string",
"description": "Task title (action verb + target)" "description": "Task title (action verb + target)"
@@ -39,23 +44,44 @@
}, },
"action": { "action": {
"type": "string", "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": "Primary action type"
}, },
"description": { "description": {
"type": "string", "type": "string",
"description": "What to implement (1-2 sentences)" "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": { "implementation": {
"type": "array", "type": "array",
"items": {"type": "string"}, "items": {"type": "string"},
"minItems": 3, "minItems": 2,
"maxItems": 7, "maxItems": 7,
"description": "Step-by-step implementation guide" "description": "Step-by-step implementation guide"
}, },
"reference": { "reference": {
"type": "object", "type": "object",
"required": ["pattern", "files", "examples"],
"properties": { "properties": {
"pattern": { "pattern": {
"type": "string", "type": "string",
@@ -71,18 +97,74 @@
"description": "Specific guidance or example references" "description": "Specific guidance or example references"
} }
}, },
"description": "Reference materials for implementation" "description": "Reference materials for implementation (optional)"
}, },
"acceptance": { "acceptance": {
"type": "array", "type": "array",
"items": {"type": "string"}, "items": {"type": "string"},
"minItems": 2, "minItems": 1,
"maxItems": 4, "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": { "estimated_time": {
"type": "string", "type": "string",
@@ -100,7 +182,7 @@
}, },
"_metadata": { "_metadata": {
"type": "object", "type": "object",
"required": ["timestamp", "source", "planning_mode"], "required": ["timestamp", "source"],
"properties": { "properties": {
"timestamp": { "timestamp": {
"type": "string", "type": "string",
@@ -117,6 +199,11 @@
"enum": ["direct", "agent-based"], "enum": ["direct", "agent-based"],
"description": "Planning execution mode" "description": "Planning execution mode"
}, },
"exploration_angles": {
"type": "array",
"items": {"type": "string"},
"description": "Exploration angles used for context"
},
"duration_seconds": { "duration_seconds": {
"type": "integer", "type": "integer",
"description": "Planning duration in seconds" "description": "Planning duration in seconds"