feat: Review Session增加Fix进度跟踪卡片,移除独立Dashboard模板

- 新增Fix Progress跟踪卡片(走马灯样式)显示修复进度
- 添加/api/file端点支持读取fix-plan.json
- 移除review-fix/module-cycle/session-cycle中的独立dashboard生成
- 删除废弃的workflow-dashboard.html和review-cycle-dashboard.html模板
- 统一使用ccw view命令查看进度

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
catlog22
2025-12-07 21:41:43 +08:00
parent cb78758839
commit ac626e5895
10 changed files with 2616 additions and 3989 deletions

View File

@@ -46,8 +46,7 @@ Automated fix orchestrator with **two-phase architecture**: AI-powered planning
1. **Intelligent Planning**: AI-powered analysis identifies optimal grouping and execution strategy
2. **Multi-stage Coordination**: Supports complex parallel + serial execution with dependency management
3. **Conservative Safety**: Mandatory test verification with automatic rollback on failure
4. **Real-time Visibility**: Dashboard shows planning progress, stage timeline, and active agents
5. **Resume Support**: Checkpoint-based recovery for interrupted sessions
4. **Resume Support**: Checkpoint-based recovery for interrupted sessions
### Orchestrator Boundary (CRITICAL)
- **ONLY command** for automated review finding fixes
@@ -59,14 +58,14 @@ Automated fix orchestrator with **two-phase architecture**: AI-powered planning
```
Phase 1: Discovery & Initialization
└─ Validate export file, create fix session structure, initialize state files → Generate fix-dashboard.html
└─ Validate export file, create fix session structure, initialize state files
Phase 2: Planning Coordination (@cli-planning-agent)
├─ Analyze findings for patterns and dependencies
├─ Group by file + dimension + root cause similarity
├─ Determine execution strategy (parallel/serial/hybrid)
├─ Generate fix timeline with stages
└─ Output: fix-plan.json (dashboard auto-polls for status)
└─ Output: fix-plan.json
Phase 3: Execution Orchestration (Stage-based)
For each timeline stage:
@@ -198,12 +197,10 @@ if (result.passRate < 100%) {
- Session creation: Generate fix-session-id (`fix-{timestamp}`)
- Directory structure: Create `{review-dir}/fixes/{fix-session-id}/` with subdirectories
- State files: Initialize active-fix-session.json (session marker)
- Dashboard generation: Create fix-dashboard.html from template (see Dashboard Generation below)
- TodoWrite initialization: Set up 4-phase tracking
**Phase 2: Planning Coordination**
- Launch @cli-planning-agent with findings data and project context
- Monitor planning progress (dashboard shows "Planning fixes..." indicator)
- Validate fix-plan.json output (schema conformance, includes metadata with session status)
- Load plan into memory for execution phase
- TodoWrite update: Mark planning complete, start execution
@@ -216,7 +213,6 @@ if (result.passRate < 100%) {
- Assign agent IDs (agents update their fix-progress-{N}.json)
- Handle agent failures gracefully (mark group as failed, continue)
- Advance to next stage only when current stage complete
- Dashboard polls and aggregates fix-progress-{N}.json files for display
**Phase 4: Completion & Aggregation**
- Collect final status from all fix-progress-{N}.json files
@@ -224,7 +220,7 @@ if (result.passRate < 100%) {
- Update fix-history.json with new session entry
- Remove active-fix-session.json
- TodoWrite completion: Mark all phases done
- Output summary to user with dashboard link
- Output summary to user
**Phase 5: Session Completion (Optional)**
- If all findings fixed successfully (no failures):
@@ -234,53 +230,12 @@ if (result.passRate < 100%) {
- Output: "Some findings failed. Review fix-summary.md before completing session."
- Do NOT auto-complete session
### Dashboard Generation
**MANDATORY**: Dashboard MUST be generated from template during Phase 1 initialization
**Template Location**: `~/.claude/templates/fix-dashboard.html`
**⚠️ POST-GENERATION**: Orchestrator and agents MUST NOT read/write/modify fix-dashboard.html after creation
**Generation Steps**:
```bash
# 1. Copy template to fix session directory
cp ~/.claude/templates/fix-dashboard.html ${sessionDir}/fixes/${fixSessionId}/fix-dashboard.html
# 2. Replace SESSION_ID placeholder
sed -i "s|{{SESSION_ID}}|${sessionId}|g" ${sessionDir}/fixes/${fixSessionId}/fix-dashboard.html
# 3. Replace REVIEW_DIR placeholder
sed -i "s|{{REVIEW_DIR}}|${reviewDir}|g" ${sessionDir}/fixes/${fixSessionId}/fix-dashboard.html
# 4. Start local server and output dashboard URL
cd ${sessionDir}/fixes/${fixSessionId} && python -m http.server 8766 --bind 127.0.0.1 &
echo "🔧 Fix Dashboard: http://127.0.0.1:8766/fix-dashboard.html"
echo " (Press Ctrl+C to stop server when done)"
```
**Dashboard Features**:
- Real-time progress tracking via JSON polling (3-second interval)
- Stage timeline visualization with parallel/serial execution modes
- Active groups and agents monitoring
- Flow control steps tracking for each agent
- Fix history drawer with session summaries
- Consumes new JSON structure (fix-plan.json with metadata + fix-progress-{N}.json)
**JSON Consumption**:
- `fix-plan.json`: Reads metadata field for session info, timeline stages, groups configuration
- `fix-progress-{N}.json`: Polls all progress files to aggregate real-time status
- `active-fix-session.json`: Detects active session on load
- `fix-history.json`: Loads historical fix sessions
### Output File Structure
```
.workflow/active/WFS-{session-id}/.review/
├── fix-export-{timestamp}.json # Exported findings (input)
└── fixes/{fix-session-id}/
├── fix-dashboard.html # Interactive dashboard (generated once, auto-polls JSON)
├── fix-plan.json # Planning agent output (execution plan with metadata)
├── fix-progress-1.json # Group 1 progress (planning agent init → agent updates)
├── fix-progress-2.json # Group 2 progress (planning agent init → agent updates)
@@ -291,10 +246,8 @@ echo " (Press Ctrl+C to stop server when done)"
```
**File Producers**:
- **Orchestrator**: `fix-dashboard.html` (generated once from template during Phase 1)
- **Planning Agent**: `fix-plan.json` (with metadata), all `fix-progress-*.json` (initial state)
- **Execution Agents**: Update assigned `fix-progress-{N}.json` in real-time
- **Dashboard (Browser)**: Reads `fix-plan.json` + all `fix-progress-*.json`, aggregates in-memory every 3 seconds via JavaScript polling
### Agent Invocation Template
@@ -347,7 +300,7 @@ For each group (G1, G2, G3, ...), generate fix-progress-{N}.json following templ
- Flow control: Empty implementation_approach array
- Errors: Empty array
**CRITICAL**: Ensure complete template structure for Dashboard consumption - all fields must be present.
**CRITICAL**: Ensure complete template structure - all fields must be present.
## Analysis Requirements
@@ -419,7 +372,7 @@ Task({
description: `Fix ${group.findings.length} issues: ${group.group_name}`,
prompt: `
## Task Objective
Execute fixes for code review findings in group ${group.group_id}. Update progress file in real-time with flow control tracking for dashboard visibility.
Execute fixes for code review findings in group ${group.group_id}. Update progress file in real-time with flow control tracking.
## Assignment
- Group ID: ${group.group_id}
@@ -549,7 +502,6 @@ When all findings processed:
### Progress File Updates
- **MUST update after every significant action** (before/after each step)
- **Dashboard polls every 3 seconds** - ensure writes are atomic
- **Always maintain complete structure** - never write partial updates
- **Use ISO 8601 timestamps** - e.g., "2025-01-25T14:36:00Z"
@@ -638,9 +590,17 @@ TodoWrite({
1. **Trust AI Planning**: Planning agent's grouping and execution strategy are based on dependency analysis
2. **Conservative Approach**: Test verification is mandatory - no fixes kept without passing tests
3. **Parallel Efficiency**: Default 3 concurrent agents balances speed and resource usage
4. **Monitor Dashboard**: Real-time stage timeline and agent status provide execution visibility
5. **Resume Support**: Fix sessions can resume from checkpoints after interruption
6. **Manual Review**: Always review failed fixes manually - may require architectural changes
7. **Incremental Fixing**: Start with small batches (5-10 findings) before large-scale fixes
4. **Resume Support**: Fix sessions can resume from checkpoints after interruption
5. **Manual Review**: Always review failed fixes manually - may require architectural changes
6. **Incremental Fixing**: Start with small batches (5-10 findings) before large-scale fixes
## Related Commands
### View Fix Progress
Use `ccw view` to open the workflow dashboard in browser:
```bash
ccw view
```

View File

@@ -51,14 +51,12 @@ Independent multi-dimensional code review orchestrator with **hybrid parallel-it
2. **Session-Integrated**: Review results tracked within workflow session for unified management
3. **Comprehensive Coverage**: Same 7 specialized dimensions as session review
4. **Intelligent Prioritization**: Automatic identification of critical issues and cross-cutting concerns
5. **Real-time Visibility**: JSON-based progress tracking with interactive HTML dashboard
6. **Unified Archive**: Review results archived with session for historical reference
5. **Unified Archive**: Review results archived with session for historical reference
### Orchestrator Boundary (CRITICAL)
- **ONLY command** for independent multi-dimensional module review
- Manages: dimension coordination, aggregation, iteration control, progress tracking
- Delegates: Code exploration and analysis to @cli-explore-agent, dimension-specific reviews via Deep Scan mode
- **⚠️ DASHBOARD CONSTRAINT**: Dashboard is generated ONCE during Phase 1 initialization. After initialization, orchestrator and agents MUST NOT read, write, or modify dashboard.html - it remains static for user interaction only.
## How It Works
@@ -66,7 +64,7 @@ Independent multi-dimensional code review orchestrator with **hybrid parallel-it
```
Phase 1: Discovery & Initialization
└─ Resolve file patterns, validate paths, initialize state, create output structure → Generate dashboard.html
└─ Resolve file patterns, validate paths, initialize state, create output structure
Phase 2: Parallel Reviews (for each dimension)
├─ Launch 7 review agents simultaneously
@@ -90,7 +88,7 @@ Phase 4: Iterative Deep-Dive (optional)
└─ Loop until no critical findings OR max iterations
Phase 5: Completion
└─ Finalize review-progress.json → Output dashboard path
└─ Finalize review-progress.json
```
### Agent Roles
@@ -219,37 +217,9 @@ done
**Step 4: Initialize Review State**
- State initialization: Create `review-state.json` with metadata, dimensions, max_iterations, resolved_files (merged metadata + state)
- Progress tracking: Create `review-progress.json` for dashboard polling
- Progress tracking: Create `review-progress.json` for progress tracking
**Step 5: Dashboard Generation**
**Constraints**:
- **MANDATORY**: Dashboard MUST be generated from template: `~/.claude/templates/review-cycle-dashboard.html`
- **PROHIBITED**: Direct creation or custom generation without template
- **POST-GENERATION**: Orchestrator and agents MUST NOT read/write/modify dashboard.html after creation
**Generation Commands** (3 independent steps):
```bash
# Step 1: Copy template to output location
cp ~/.claude/templates/review-cycle-dashboard.html ${sessionDir}/.review/dashboard.html
# Step 2: Replace SESSION_ID placeholder
sed -i "s|{{SESSION_ID}}|${sessionId}|g" ${sessionDir}/.review/dashboard.html
# Step 3: Replace REVIEW_TYPE placeholder
sed -i "s|{{REVIEW_TYPE}}|module|g" ${sessionDir}/.review/dashboard.html
# Step 4: Replace REVIEW_DIR placeholder
sed -i "s|{{REVIEW_DIR}}|${reviewDir}|g" ${sessionDir}/.review/dashboard.html
# Output: Start local server and output dashboard URL
# Use Python HTTP server (available on most systems)
cd ${sessionDir}/.review && python -m http.server 8765 --bind 127.0.0.1 &
echo "📊 Dashboard: http://127.0.0.1:8765/dashboard.html"
echo " (Press Ctrl+C to stop server when done)"
```
**Step 6: TodoWrite Initialization**
**Step 5: TodoWrite Initialization**
- Set up progress tracking with hierarchical structure
- Mark Phase 1 completed, Phase 2 in_progress
@@ -280,7 +250,6 @@ echo " (Press Ctrl+C to stop server when done)"
- Finalize review-progress.json with completion statistics
- Update review-state.json with completion_time and phase=complete
- TodoWrite completion: Mark all tasks done
- Output: Dashboard path to user
@@ -301,12 +270,11 @@ echo " (Press Ctrl+C to stop server when done)"
├── iterations/ # Deep-dive results
│ ├── iteration-1-finding-{uuid}.json
│ └── iteration-2-finding-{uuid}.json
── reports/ # Human-readable reports
├── security-analysis.md
├── security-cli-output.txt
├── deep-dive-1-{uuid}.md
└── ...
└── dashboard.html # Interactive dashboard (primary output)
── reports/ # Human-readable reports
├── security-analysis.md
├── security-cli-output.txt
├── deep-dive-1-{uuid}.md
└── ...
```
**Session Context**:
@@ -772,23 +740,25 @@ TodoWrite({
3. **Use Glob Wisely**: `src/auth/**` is more efficient than `src/**` with lots of irrelevant files
4. **Trust Aggregation Logic**: Auto-selection based on proven heuristics
5. **Monitor Logs**: Check reports/ directory for CLI analysis insights
6. **Dashboard Polling**: Refresh every 5 seconds for real-time updates
7. **Export Results**: Use dashboard export for external tracking tools
## Related Commands
### View Review Progress
Use `ccw view` to open the review dashboard in browser:
```bash
ccw view
```
### Automated Fix Workflow
After completing a module review, use the dashboard to select findings and export them for automated fixing:
After completing a module review, use the generated findings JSON for automated fixing:
```bash
# Step 1: Complete review (this command)
/workflow:review-module-cycle src/auth/**
# Step 2: Open dashboard, select findings, and export
# Dashboard generates: fix-export-{timestamp}.json
# Step 3: Run automated fixes
/workflow:review-fix .workflow/active/WFS-{session-id}/.review/fix-export-{timestamp}.json
# Step 2: Run automated fixes using dimension findings
/workflow:review-fix .workflow/active/WFS-{session-id}/.review/
```
See `/workflow:review-fix` for automated fixing with smart grouping, parallel execution, and test verification.

View File

@@ -45,13 +45,11 @@ Session-based multi-dimensional code review orchestrator with **hybrid parallel-
1. **Comprehensive Coverage**: 7 specialized dimensions analyze all quality aspects simultaneously
2. **Intelligent Prioritization**: Automatic identification of critical issues and cross-cutting concerns
3. **Actionable Insights**: Deep-dive iterations provide step-by-step remediation plans
4. **Real-time Visibility**: JSON-based progress tracking with interactive HTML dashboard
### Orchestrator Boundary (CRITICAL)
- **ONLY command** for comprehensive multi-dimensional review
- Manages: dimension coordination, aggregation, iteration control, progress tracking
- Delegates: Code exploration and analysis to @cli-explore-agent, dimension-specific reviews via Deep Scan mode
- **⚠️ DASHBOARD CONSTRAINT**: Dashboard is generated ONCE during Phase 1 initialization. After initialization, orchestrator and agents MUST NOT read, write, or modify dashboard.html - it remains static for user interaction only.
## How It Works
@@ -59,7 +57,7 @@ Session-based multi-dimensional code review orchestrator with **hybrid parallel-
```
Phase 1: Discovery & Initialization
└─ Validate session, initialize state, create output structure → Generate dashboard.html
└─ Validate session, initialize state, create output structure
Phase 2: Parallel Reviews (for each dimension)
├─ Launch 7 review agents simultaneously
@@ -83,7 +81,7 @@ Phase 4: Iterative Deep-Dive (optional)
└─ Loop until no critical findings OR max iterations
Phase 5: Completion
└─ Finalize review-progress.json → Output dashboard path
└─ Finalize review-progress.json
```
### Agent Roles
@@ -199,36 +197,9 @@ git log --since="${sessionCreatedAt}" --name-only --pretty=format: | sort -u
**Step 5: Initialize Review State**
- State initialization: Create `review-state.json` with metadata, dimensions, max_iterations (merged metadata + state)
- Progress tracking: Create `review-progress.json` for dashboard polling
- Progress tracking: Create `review-progress.json` for progress tracking
**Step 6: Dashboard Generation**
**Constraints**:
- **MANDATORY**: Dashboard MUST be generated from template: `~/.claude/templates/review-cycle-dashboard.html`
- **PROHIBITED**: Direct creation or custom generation without template
- **POST-GENERATION**: Orchestrator and agents MUST NOT read/write/modify dashboard.html after creation
**Generation Commands** (3 independent steps):
```bash
# Step 1: Copy template to output location
cp ~/.claude/templates/review-cycle-dashboard.html ${sessionDir}/.review/dashboard.html
# Step 2: Replace SESSION_ID placeholder
sed -i "s|{{SESSION_ID}}|${sessionId}|g" ${sessionDir}/.review/dashboard.html
# Step 3: Replace REVIEW_TYPE placeholder
sed -i "s|{{REVIEW_TYPE}}|session|g" ${sessionDir}/.review/dashboard.html
# Step 4: Replace REVIEW_DIR placeholder
sed -i "s|{{REVIEW_DIR}}|${reviewDir}|g" ${sessionDir}/.review/dashboard.html
# Output: Start local server and output dashboard URL
cd ${sessionDir}/.review && python -m http.server 8765 --bind 127.0.0.1 &
echo "📊 Dashboard: http://127.0.0.1:8765/dashboard.html"
echo " (Press Ctrl+C to stop server when done)"
```
**Step 7: TodoWrite Initialization**
**Step 6: TodoWrite Initialization**
- Set up progress tracking with hierarchical structure
- Mark Phase 1 completed, Phase 2 in_progress
@@ -259,7 +230,6 @@ echo " (Press Ctrl+C to stop server when done)"
- Finalize review-progress.json with completion statistics
- Update review-state.json with completion_time and phase=complete
- TodoWrite completion: Mark all tasks done
- Output: Dashboard path to user
@@ -280,12 +250,11 @@ echo " (Press Ctrl+C to stop server when done)"
├── iterations/ # Deep-dive results
│ ├── iteration-1-finding-{uuid}.json
│ └── iteration-2-finding-{uuid}.json
── reports/ # Human-readable reports
├── security-analysis.md
├── security-cli-output.txt
├── deep-dive-1-{uuid}.md
└── ...
└── dashboard.html # Interactive dashboard (primary output)
── reports/ # Human-readable reports
├── security-analysis.md
├── security-cli-output.txt
├── deep-dive-1-{uuid}.md
└── ...
```
**Session Context**:
@@ -782,23 +751,25 @@ TodoWrite({
2. **Parallel Execution**: ~60 minutes for full initial review (7 dimensions)
3. **Trust Aggregation Logic**: Auto-selection based on proven heuristics
4. **Monitor Logs**: Check reports/ directory for CLI analysis insights
5. **Dashboard Polling**: Refresh every 5 seconds for real-time updates
6. **Export Results**: Use dashboard export for external tracking tools
## Related Commands
### View Review Progress
Use `ccw view` to open the review dashboard in browser:
```bash
ccw view
```
### Automated Fix Workflow
After completing a review, use the dashboard to select findings and export them for automated fixing:
After completing a review, use the generated findings JSON for automated fixing:
```bash
# Step 1: Complete review (this command)
/workflow:review-session-cycle
# Step 2: Open dashboard, select findings, and export
# Dashboard generates: fix-export-{timestamp}.json
# Step 3: Run automated fixes
/workflow:review-fix .workflow/active/WFS-{session-id}/.review/fix-export-{timestamp}.json
# Step 2: Run automated fixes using dimension findings
/workflow:review-fix .workflow/active/WFS-{session-id}/.review/
```
See `/workflow:review-fix` for automated fixing with smart grouping, parallel execution, and test verification.

View File

@@ -1,352 +0,0 @@
---
name: workflow:status
description: Generate on-demand views for project overview and workflow tasks with optional task-id filtering for detailed view
argument-hint: "[optional: --project|task-id|--validate|--dashboard]"
---
# Workflow Status Command (/workflow:status)
## Overview
Generates on-demand views from project and session data. Supports multiple modes:
1. **Project Overview** (`--project`): Shows completed features and project statistics
2. **Workflow Tasks** (default): Shows current session task progress
3. **HTML Dashboard** (`--dashboard`): Generates interactive HTML task board with active and archived sessions
No synchronization needed - all views are calculated from current JSON state.
## Usage
```bash
/workflow:status # Show current workflow session overview
/workflow:status --project # Show project-level feature registry
/workflow:status impl-1 # Show specific task details
/workflow:status --validate # Validate workflow integrity
/workflow:status --dashboard # Generate HTML dashboard board
```
## Execution Process
```
Input Parsing:
└─ Decision (mode detection):
├─ --project flag → Project Overview Mode
├─ --dashboard flag → Dashboard Mode
├─ task-id argument → Task Details Mode
└─ No flags → Workflow Session Mode (default)
Project Overview Mode:
├─ Check project.json exists
├─ Read project data
├─ Parse and display overview + features
└─ Show recent archived sessions
Workflow Session Mode (default):
├─ Find active session
├─ Load session data
├─ Scan task files
└─ Display task progress
Dashboard Mode:
├─ Collect active sessions
├─ Collect archived sessions
├─ Generate HTML from template
└─ Write dashboard.html
```
## Implementation Flow
### Mode Selection
**Check for --project flag**:
- If `--project` flag present → Execute **Project Overview Mode**
- Otherwise → Execute **Workflow Session Mode** (default)
## Project Overview Mode
### Step 1: Check Project State
```bash
bash(test -f .workflow/project.json && echo "EXISTS" || echo "NOT_FOUND")
```
**If NOT_FOUND**:
```
No project state found.
Run /workflow:session:start to initialize project.
```
### Step 2: Read Project Data
```bash
bash(cat .workflow/project.json)
```
### Step 3: Parse and Display
**Data Processing**:
```javascript
const projectData = JSON.parse(Read('.workflow/project.json'));
const features = projectData.features || [];
const stats = projectData.statistics || {};
const overview = projectData.overview || null;
// Sort features by implementation date (newest first)
const sortedFeatures = features.sort((a, b) =>
new Date(b.implemented_at) - new Date(a.implemented_at)
);
```
**Output Format** (with extended overview):
```
## Project: ${projectData.project_name}
Initialized: ${projectData.initialized_at}
${overview ? `
### Overview
${overview.description}
**Technology Stack**:
${overview.technology_stack.languages.map(l => `- ${l.name}${l.primary ? ' (primary)' : ''}: ${l.file_count} files`).join('\n')}
Frameworks: ${overview.technology_stack.frameworks.join(', ')}
**Architecture**:
Style: ${overview.architecture.style}
Patterns: ${overview.architecture.patterns.join(', ')}
**Key Components** (${overview.key_components.length}):
${overview.key_components.map(c => `- ${c.name} (${c.path})\n ${c.description}`).join('\n')}
---
` : ''}
### Completed Features (${stats.total_features})
${sortedFeatures.map(f => `
- ${f.title} (${f.timeline?.implemented_at || f.implemented_at})
${f.description}
Tags: ${f.tags?.join(', ') || 'none'}
Session: ${f.traceability?.session_id || f.session_id}
Archive: ${f.traceability?.archive_path || 'unknown'}
${f.traceability?.commit_hash ? `Commit: ${f.traceability.commit_hash}` : ''}
`).join('\n')}
### Project Statistics
- Total Features: ${stats.total_features}
- Total Sessions: ${stats.total_sessions}
- Last Updated: ${stats.last_updated}
### Quick Access
- View session details: /workflow:status
- Archive query: jq '.archives[] | select(.session_id == "SESSION_ID")' .workflow/archives/manifest.json
- Documentation: .workflow/docs/${projectData.project_name}/
### Query Commands
# Find by tag
cat .workflow/project.json | jq '.features[] | select(.tags[] == "auth")'
# View archive
cat ${feature.traceability.archive_path}/IMPL_PLAN.md
# List all tags
cat .workflow/project.json | jq -r '.features[].tags[]' | sort -u
```
**Empty State**:
```
## Project: ${projectData.project_name}
Initialized: ${projectData.initialized_at}
No features completed yet.
Complete your first workflow session to add features:
1. /workflow:plan "feature description"
2. /workflow:execute
3. /workflow:session:complete
```
### Step 4: Show Recent Sessions (Optional)
```bash
# List 5 most recent archived sessions
bash(ls -1t .workflow/archives/WFS-* 2>/dev/null | head -5 | xargs -I {} basename {})
```
**Output**:
```
### Recent Sessions
- WFS-auth-system (archived)
- WFS-payment-flow (archived)
- WFS-user-dashboard (archived)
Use /workflow:session:complete to archive current session.
```
## Workflow Session Mode (Default)
### Step 1: Find Active Session
```bash
find .workflow/active/ -name "WFS-*" -type d 2>/dev/null | head -1
```
### Step 2: Load Session Data
```bash
cat .workflow/active/WFS-session/workflow-session.json
```
### Step 3: Scan Task Files
```bash
find .workflow/active/WFS-session/.task/ -name "*.json" -type f 2>/dev/null
```
### Step 4: Generate Task Status
```bash
cat .workflow/active/WFS-session/.task/impl-1.json | jq -r '.status'
```
### Step 5: Count Task Progress
```bash
find .workflow/active/WFS-session/.task/ -name "*.json" -type f | wc -l
find .workflow/active/WFS-session/.summaries/ -name "*.md" -type f 2>/dev/null | wc -l
```
### Step 6: Display Overview
```markdown
# Workflow Overview
**Session**: WFS-session-name
**Progress**: 3/8 tasks completed
## Active Tasks
- [IN PROGRESS] impl-1: Current task in progress
- [ ] impl-2: Next pending task
## Completed Tasks
- [COMPLETED] impl-0: Setup completed
```
## Dashboard Mode (HTML Board)
### Step 1: Check for --dashboard flag
```bash
# If --dashboard flag present → Execute Dashboard Mode
```
### Step 2: Collect Workflow Data
**Collect Active Sessions**:
```bash
# Find all active sessions
find .workflow/active/ -name "WFS-*" -type d 2>/dev/null
# For each active session, read metadata and tasks
for session in $(find .workflow/active/ -name "WFS-*" -type d 2>/dev/null); do
cat "$session/workflow-session.json"
find "$session/.task/" -name "*.json" -type f 2>/dev/null
done
```
**Collect Archived Sessions**:
```bash
# Find all archived sessions
find .workflow/archives/ -name "WFS-*" -type d 2>/dev/null
# Read manifest if exists
cat .workflow/archives/manifest.json 2>/dev/null
# For each archived session, read metadata
for archive in $(find .workflow/archives/ -name "WFS-*" -type d 2>/dev/null); do
cat "$archive/workflow-session.json" 2>/dev/null
# Count completed tasks
find "$archive/.task/" -name "*.json" -type f 2>/dev/null | wc -l
done
```
### Step 3: Process and Structure Data
**Build data structure for dashboard**:
```javascript
const dashboardData = {
activeSessions: [],
archivedSessions: [],
generatedAt: new Date().toISOString()
};
// Process active sessions
for each active_session in active_sessions:
const sessionData = JSON.parse(Read(active_session/workflow-session.json));
const tasks = [];
// Load all tasks for this session
for each task_file in find(active_session/.task/*.json):
const taskData = JSON.parse(Read(task_file));
tasks.push({
task_id: taskData.task_id,
title: taskData.title,
status: taskData.status,
type: taskData.type
});
dashboardData.activeSessions.push({
session_id: sessionData.session_id,
project: sessionData.project,
status: sessionData.status,
created_at: sessionData.created_at || sessionData.initialized_at,
tasks: tasks
});
// Process archived sessions
for each archived_session in archived_sessions:
const sessionData = JSON.parse(Read(archived_session/workflow-session.json));
const taskCount = bash(find archived_session/.task/*.json | wc -l);
dashboardData.archivedSessions.push({
session_id: sessionData.session_id,
project: sessionData.project,
archived_at: sessionData.completed_at || sessionData.archived_at,
taskCount: parseInt(taskCount),
archive_path: archived_session
});
```
### Step 4: Generate HTML from Template
**Load template and inject data**:
```javascript
// Read the HTML template
const template = Read("~/.claude/templates/workflow-dashboard.html");
// Prepare data for injection
const dataJson = JSON.stringify(dashboardData, null, 2);
// Replace placeholder with actual data
const htmlContent = template.replace('{{WORKFLOW_DATA}}', dataJson);
// Ensure .workflow directory exists
bash(mkdir -p .workflow);
```
### Step 5: Write HTML File
```bash
# Write the generated HTML to .workflow/dashboard.html
Write({
file_path: ".workflow/dashboard.html",
content: htmlContent
})
```
### Step 6: Display Success Message
```markdown
Dashboard generated successfully!
Location: .workflow/dashboard.html
Open in browser:
file://$(pwd)/.workflow/dashboard.html
Features:
- 📊 Active sessions overview
- 📦 Archived sessions history
- 🔍 Search and filter
- 📈 Progress tracking
- 🎨 Dark/light theme
Refresh data: Re-run /workflow:status --dashboard
```

File diff suppressed because it is too large Load Diff

View File

@@ -1,664 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Workflow Dashboard - Task Board</title>
<style>
:root {
--bg-primary: #f5f7fa;
--bg-secondary: #ffffff;
--bg-card: #ffffff;
--text-primary: #1a202c;
--text-secondary: #718096;
--border-color: #e2e8f0;
--accent-color: #4299e1;
--success-color: #48bb78;
--warning-color: #ed8936;
--danger-color: #f56565;
--shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
[data-theme="dark"] {
--bg-primary: #1a202c;
--bg-secondary: #2d3748;
--bg-card: #2d3748;
--text-primary: #f7fafc;
--text-secondary: #a0aec0;
--border-color: #4a5568;
--shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px 0 rgba(0, 0, 0, 0.2);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
transition: background-color 0.3s, color 0.3s;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
header {
background-color: var(--bg-secondary);
box-shadow: var(--shadow);
padding: 20px;
margin-bottom: 30px;
border-radius: 8px;
}
h1 {
font-size: 2rem;
margin-bottom: 10px;
color: var(--accent-color);
}
.header-controls {
display: flex;
gap: 15px;
flex-wrap: wrap;
align-items: center;
margin-top: 15px;
}
.search-box {
flex: 1;
min-width: 250px;
position: relative;
}
.search-box input {
width: 100%;
padding: 10px 15px;
border: 1px solid var(--border-color);
border-radius: 6px;
background-color: var(--bg-primary);
color: var(--text-primary);
font-size: 0.95rem;
}
.filter-group {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 0.9rem;
font-weight: 500;
transition: all 0.2s;
background-color: var(--bg-card);
color: var(--text-primary);
border: 1px solid var(--border-color);
}
.btn:hover {
transform: translateY(-1px);
box-shadow: var(--shadow);
}
.btn.active {
background-color: var(--accent-color);
color: white;
border-color: var(--accent-color);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.stat-card {
background-color: var(--bg-card);
padding: 20px;
border-radius: 8px;
box-shadow: var(--shadow);
transition: transform 0.2s;
}
.stat-card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.stat-value {
font-size: 2rem;
font-weight: bold;
color: var(--accent-color);
}
.stat-label {
color: var(--text-secondary);
font-size: 0.9rem;
margin-top: 5px;
}
.section {
margin-bottom: 40px;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.section-title {
font-size: 1.5rem;
font-weight: 600;
}
.sessions-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 20px;
}
.session-card {
background-color: var(--bg-card);
border-radius: 8px;
box-shadow: var(--shadow);
padding: 20px;
transition: all 0.3s;
}
.session-card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-lg);
}
.session-header {
display: flex;
justify-content: space-between;
align-items: start;
margin-bottom: 15px;
}
.session-title {
font-size: 1.2rem;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 5px;
}
.session-status {
padding: 4px 12px;
border-radius: 12px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.status-active {
background-color: #c6f6d5;
color: #22543d;
}
.status-archived {
background-color: #e2e8f0;
color: #4a5568;
}
[data-theme="dark"] .status-active {
background-color: #22543d;
color: #c6f6d5;
}
[data-theme="dark"] .status-archived {
background-color: #4a5568;
color: #e2e8f0;
}
.session-meta {
display: flex;
gap: 15px;
font-size: 0.85rem;
color: var(--text-secondary);
margin-bottom: 15px;
}
.progress-bar {
width: 100%;
height: 8px;
background-color: var(--bg-primary);
border-radius: 4px;
overflow: hidden;
margin: 15px 0;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--accent-color), var(--success-color));
transition: width 0.3s;
}
.tasks-list {
margin-top: 15px;
}
.task-item {
display: flex;
align-items: center;
padding: 10px;
margin-bottom: 8px;
background-color: var(--bg-primary);
border-radius: 6px;
border-left: 3px solid var(--border-color);
transition: all 0.2s;
}
.task-item:hover {
transform: translateX(4px);
}
.task-item.completed {
border-left-color: var(--success-color);
opacity: 0.8;
}
.task-item.in_progress {
border-left-color: var(--warning-color);
}
.task-item.pending {
border-left-color: var(--text-secondary);
}
.task-checkbox {
width: 20px;
height: 20px;
border-radius: 50%;
border: 2px solid var(--border-color);
margin-right: 12px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.task-item.completed .task-checkbox {
background-color: var(--success-color);
border-color: var(--success-color);
}
.task-item.completed .task-checkbox::after {
content: '✓';
color: white;
font-size: 0.8rem;
font-weight: bold;
}
.task-item.in_progress .task-checkbox {
border-color: var(--warning-color);
background-color: var(--warning-color);
}
.task-item.in_progress .task-checkbox::after {
content: '⟳';
color: white;
font-size: 0.9rem;
}
.task-title {
flex: 1;
font-size: 0.9rem;
}
.task-id {
font-size: 0.75rem;
color: var(--text-secondary);
font-family: monospace;
margin-left: 10px;
}
.empty-state {
text-align: center;
padding: 60px 20px;
color: var(--text-secondary);
}
.empty-state-icon {
font-size: 4rem;
margin-bottom: 20px;
opacity: 0.5;
}
.theme-toggle {
position: fixed;
bottom: 30px;
right: 30px;
width: 60px;
height: 60px;
border-radius: 50%;
background-color: var(--accent-color);
color: white;
border: none;
cursor: pointer;
font-size: 1.5rem;
box-shadow: var(--shadow-lg);
transition: all 0.3s;
z-index: 1000;
}
.theme-toggle:hover {
transform: scale(1.1);
}
@media (max-width: 768px) {
.sessions-grid {
grid-template-columns: 1fr;
}
.stats-grid {
grid-template-columns: repeat(2, 1fr);
}
h1 {
font-size: 1.5rem;
}
.header-controls {
flex-direction: column;
align-items: stretch;
}
.search-box {
width: 100%;
}
}
.badge {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 0.75rem;
font-weight: 500;
margin-left: 8px;
}
.badge-count {
background-color: var(--accent-color);
color: white;
}
.session-footer {
margin-top: 15px;
padding-top: 15px;
border-top: 1px solid var(--border-color);
font-size: 0.85rem;
color: var(--text-secondary);
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>🚀 Workflow Dashboard</h1>
<p style="color: var(--text-secondary);">Task Board - Active and Archived Sessions</p>
<div class="header-controls">
<div class="search-box">
<input type="text" id="searchInput" placeholder="🔍 Search tasks or sessions..." />
</div>
<div class="filter-group">
<button class="btn active" data-filter="all">All</button>
<button class="btn" data-filter="active">Active</button>
<button class="btn" data-filter="archived">Archived</button>
</div>
</div>
</header>
<div class="stats-grid">
<div class="stat-card">
<div class="stat-value" id="totalSessions">0</div>
<div class="stat-label">Total Sessions</div>
</div>
<div class="stat-card">
<div class="stat-value" id="activeSessions">0</div>
<div class="stat-label">Active Sessions</div>
</div>
<div class="stat-card">
<div class="stat-value" id="totalTasks">0</div>
<div class="stat-label">Total Tasks</div>
</div>
<div class="stat-card">
<div class="stat-value" id="completedTasks">0</div>
<div class="stat-label">Completed Tasks</div>
</div>
</div>
<div class="section" id="activeSectionContainer">
<div class="section-header">
<h2 class="section-title">📋 Active Sessions</h2>
</div>
<div class="sessions-grid" id="activeSessions"></div>
</div>
<div class="section" id="archivedSectionContainer">
<div class="section-header">
<h2 class="section-title">📦 Archived Sessions</h2>
</div>
<div class="sessions-grid" id="archivedSessions"></div>
</div>
</div>
<button class="theme-toggle" id="themeToggle">🌙</button>
<script>
// Workflow data will be injected here
const workflowData = {{WORKFLOW_DATA}};
// Theme management
function initTheme() {
const savedTheme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-theme', savedTheme);
updateThemeIcon(savedTheme);
}
function toggleTheme() {
const currentTheme = document.documentElement.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', newTheme);
localStorage.setItem('theme', newTheme);
updateThemeIcon(newTheme);
}
function updateThemeIcon(theme) {
document.getElementById('themeToggle').textContent = theme === 'dark' ? '☀️' : '🌙';
}
// Statistics calculation
function updateStatistics() {
const stats = {
totalSessions: workflowData.activeSessions.length + workflowData.archivedSessions.length,
activeSessions: workflowData.activeSessions.length,
totalTasks: 0,
completedTasks: 0
};
workflowData.activeSessions.forEach(session => {
stats.totalTasks += session.tasks.length;
stats.completedTasks += session.tasks.filter(t => t.status === 'completed').length;
});
workflowData.archivedSessions.forEach(session => {
stats.totalTasks += session.taskCount || 0;
stats.completedTasks += session.taskCount || 0;
});
document.getElementById('totalSessions').textContent = stats.totalSessions;
document.getElementById('activeSessions').textContent = stats.activeSessions;
document.getElementById('totalTasks').textContent = stats.totalTasks;
document.getElementById('completedTasks').textContent = stats.completedTasks;
}
// Render session card
function createSessionCard(session, isActive) {
const card = document.createElement('div');
card.className = 'session-card';
card.dataset.sessionType = isActive ? 'active' : 'archived';
const completedTasks = isActive
? session.tasks.filter(t => t.status === 'completed').length
: (session.taskCount || 0);
const totalTasks = isActive ? session.tasks.length : (session.taskCount || 0);
const progress = totalTasks > 0 ? (completedTasks / totalTasks * 100) : 0;
let tasksHtml = '';
if (isActive && session.tasks.length > 0) {
tasksHtml = `
<div class="tasks-list">
${session.tasks.map(task => `
<div class="task-item ${task.status}">
<div class="task-checkbox"></div>
<div class="task-title">${task.title || 'Untitled Task'}</div>
<span class="task-id">${task.task_id || ''}</span>
</div>
`).join('')}
</div>
`;
}
card.innerHTML = `
<div class="session-header">
<div>
<h3 class="session-title">${session.session_id || 'Unknown Session'}</h3>
<div style="color: var(--text-secondary); font-size: 0.9rem; margin-top: 5px;">
${session.project || ''}
</div>
</div>
<span class="session-status ${isActive ? 'status-active' : 'status-archived'}">
${isActive ? 'Active' : 'Archived'}
</span>
</div>
<div class="session-meta">
<span>📅 ${session.created_at || session.archived_at || 'N/A'}</span>
<span>📊 ${completedTasks}/${totalTasks} tasks</span>
</div>
${totalTasks > 0 ? `
<div class="progress-bar">
<div class="progress-fill" style="width: ${progress}%"></div>
</div>
<div style="text-align: center; font-size: 0.85rem; color: var(--text-secondary);">
${Math.round(progress)}% Complete
</div>
` : ''}
${tasksHtml}
${!isActive && session.archive_path ? `
<div class="session-footer">
📁 Archive: ${session.archive_path}
</div>
` : ''}
`;
return card;
}
// Render all sessions
function renderSessions(filter = 'all') {
const activeContainer = document.getElementById('activeSessions');
const archivedContainer = document.getElementById('archivedSessions');
activeContainer.innerHTML = '';
archivedContainer.innerHTML = '';
if (filter === 'all' || filter === 'active') {
if (workflowData.activeSessions.length === 0) {
activeContainer.innerHTML = `
<div class="empty-state">
<div class="empty-state-icon">📭</div>
<p>No active sessions</p>
</div>
`;
} else {
workflowData.activeSessions.forEach(session => {
activeContainer.appendChild(createSessionCard(session, true));
});
}
}
if (filter === 'all' || filter === 'archived') {
if (workflowData.archivedSessions.length === 0) {
archivedContainer.innerHTML = `
<div class="empty-state">
<div class="empty-state-icon">📦</div>
<p>No archived sessions</p>
</div>
`;
} else {
workflowData.archivedSessions.forEach(session => {
archivedContainer.appendChild(createSessionCard(session, false));
});
}
}
// Show/hide sections
document.getElementById('activeSectionContainer').style.display =
(filter === 'all' || filter === 'active') ? 'block' : 'none';
document.getElementById('archivedSectionContainer').style.display =
(filter === 'all' || filter === 'archived') ? 'block' : 'none';
}
// Search functionality
function setupSearch() {
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('input', (e) => {
const query = e.target.value.toLowerCase();
const cards = document.querySelectorAll('.session-card');
cards.forEach(card => {
const text = card.textContent.toLowerCase();
card.style.display = text.includes(query) ? 'block' : 'none';
});
});
}
// Filter functionality
function setupFilters() {
const filterButtons = document.querySelectorAll('[data-filter]');
filterButtons.forEach(btn => {
btn.addEventListener('click', () => {
filterButtons.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
renderSessions(btn.dataset.filter);
});
});
}
// Initialize
document.addEventListener('DOMContentLoaded', () => {
initTheme();
updateStatistics();
renderSessions();
setupSearch();
setupFilters();
document.getElementById('themeToggle').addEventListener('click', toggleTheme);
});
</script>
</body>
</html>