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
**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)
}
}
}

View File

@@ -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

View File

@@ -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 @@
</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 -->
<div class="dimension-tabs" id="dimensionTabs">
<button class="tab active" data-dimension="all" onclick="filterByDimension('all')">All Findings</button>
@@ -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 `<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
function filterByDimension(dimension) {
currentFilters.dimension = dimension;

View File

@@ -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"