mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
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:
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user