feat: Add CodexLens Manager Page with tabbed interface for managing CodexLens features

feat: Implement ConflictTab component to display conflict resolution decisions in session detail

feat: Create ImplPlanTab component to show implementation plan with modal viewer in session detail

feat: Develop ReviewTab component to display review findings by dimension in session detail

test: Add end-to-end tests for CodexLens Manager functionality including navigation, tab switching, and settings validation
This commit is contained in:
catlog22
2026-02-01 17:45:38 +08:00
parent 8dc115a894
commit d46406df4a
79 changed files with 11819 additions and 2455 deletions

View File

@@ -148,6 +148,8 @@ User Input → Quick Context Gather → ccw cli (Gemini/Qwen/Codex)
// - Read error file if path provided
// - Extract error patterns from description
// - Identify likely affected files (basic grep)
// Note: CLI mode does not generate status.json (lightweight)
```
2. **Execute CLI Analysis** (Phase 3)
@@ -299,6 +301,27 @@ User Input → Session Init → /workflow:debug-with-file
flags: { hotfix, autoYes }
}
Write(`${sessionFolder}/mode-config.json`, JSON.stringify(modeConfig, null, 2))
// Initialize status.json for hook tracking
const state = {
session_id: sessionId,
mode: "debug",
status: "running",
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
bug_description: bug_description,
command_chain: [
{ index: 0, command: "Phase 1: Debug & Analysis", status: "running" },
{ index: 1, command: "Phase 2: Apply Fix from Debug Findings", status: "pending" },
{ index: 2, command: "Phase 3: Generate & Execute Tests", status: "pending" },
{ index: 3, command: "Phase 4: Generate Report", status: "pending" }
],
current_index: 0
}
Write(`${sessionFolder}/status.json`, JSON.stringify(state, null, 2))
// Output session ID for hook matching
console.log(`📋 Session Started: ${sessionId}`)
```
2. **Start Debug** (Phase 3)
@@ -373,12 +396,38 @@ User Input → Session Init → /workflow:test-fix-gen
1. **Session Initialization** (Phase 2)
```javascript
const sessionId = `CCWD-${bugSlug}-${dateStr}`
const sessionFolder = `.workflow/.ccw-debug/${sessionId}`
bash(`mkdir -p ${sessionFolder}`)
const modeConfig = {
mode: "test",
original_input: bug_description,
timestamp: getUtc8ISOString(),
flags: { hotfix, autoYes }
}
Write(`${sessionFolder}/mode-config.json`, JSON.stringify(modeConfig, null, 2))
// Initialize status.json for hook tracking
const state = {
session_id: sessionId,
mode: "test",
status: "running",
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
bug_description: bug_description,
command_chain: [
{ index: 0, command: "Phase 1: Generate Tests", status: "running" },
{ index: 1, command: "Phase 2: Execute & Fix Tests", status: "pending" },
{ index: 2, command: "Phase 3: Final Validation", status: "pending" },
{ index: 3, command: "Phase 4: Generate Report", status: "pending" }
],
current_index: 0
}
Write(`${sessionFolder}/status.json`, JSON.stringify(state, null, 2))
// Output session ID for hook matching
console.log(`📋 Session Started: ${sessionId}`)
```
2. **Generate Tests** (Phase 3)
@@ -439,8 +488,32 @@ User Input → Session Init → Parallel execution:
**Execution Steps**:
1. **Parallel Execution** (Phase 3)
1. **Session Initialization & Parallel Execution** (Phase 2-3)
```javascript
const sessionId = `CCWD-${bugSlug}-${dateStr}`
const sessionFolder = `.workflow/.ccw-debug/${sessionId}`
bash(`mkdir -p ${sessionFolder}`)
// Initialize status.json for hook tracking
const state = {
session_id: sessionId,
mode: "bidirectional",
status: "running",
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
bug_description: bug_description,
command_chain: [
{ index: 0, command: "Phase 1: Parallel Debug & Test", status: "running" },
{ index: 1, command: "Phase 2: Merge Findings", status: "pending" },
{ index: 2, command: "Phase 3: Generate Report", status: "pending" }
],
current_index: 0
}
Write(`${sessionFolder}/status.json`, JSON.stringify(state, null, 2))
// Output session ID for hook matching
console.log(`📋 Session Started: ${sessionId}`)
// Start debug
const debugTask = Skill(skill="workflow:debug-with-file", args=`"${bug_description}"`)
@@ -579,18 +652,24 @@ Arguments:
### Session State Management
**Status JSON Location**: `.workflow/.ccw-debug/{session_id}/status.json`
**Status JSON Structure**:
```json
{
"session_id": "CCWD-login-timeout-2025-01-27",
"mode": "debug|test|bidirectional",
"mode": "debug|test|bidirectional|cli",
"status": "running|completed|failed|paused",
"phases": {
"phase_1": { "status": "completed", "timestamp": "..." },
"phase_2": { "status": "in_progress", "timestamp": "..." },
"phase_3": { "status": "pending" },
"phase_4": { "status": "pending" },
"phase_5": { "status": "pending" }
},
"created_at": "2025-01-27T10:30:00Z",
"updated_at": "2025-01-27T10:35:00Z",
"bug_description": "User login timeout after 30 seconds",
"command_chain": [
{ "index": 0, "command": "Phase 1: Debug & Analysis", "status": "completed" },
{ "index": 1, "command": "Phase 2: Apply Fix from Debug Findings", "status": "in_progress" },
{ "index": 2, "command": "Phase 3: Generate & Execute Tests", "status": "pending" },
{ "index": 3, "command": "Phase 4: Generate Report", "status": "pending" }
],
"current_index": 1,
"sub_sessions": {
"debug_session": "DBG-...",
"test_session": "WFS-test-..."
@@ -603,6 +682,13 @@ Arguments:
}
```
**Session ID Output**: When session starts, ccw-debug outputs:
```
📋 Session Started: CCWD-login-timeout-2025-01-27
```
This output is captured by hooks for status.json path matching.
---
## Mode Selection Logic

View File

@@ -327,49 +327,107 @@ async function getUserConfirmation(chain) {
---
### Phase 4: Setup TODO Tracking
### Phase 4: Setup TODO Tracking & Status File
```javascript
function setupTodoTracking(chain, workflow) {
function setupTodoTracking(chain, workflow, analysis) {
const sessionId = `ccw-${Date.now()}`;
const stateDir = `.workflow/.ccw/${sessionId}`;
Bash(`mkdir -p "${stateDir}"`);
const todos = chain.map((step, i) => ({
content: `CCW:${workflow}: [${i + 1}/${chain.length}] ${step.cmd}`,
status: i === 0 ? 'in_progress' : 'pending',
activeForm: `Executing ${step.cmd}`
}));
TodoWrite({ todos });
// Initialize status.json for hook tracking
const state = {
session_id: sessionId,
workflow: workflow,
status: 'running',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
analysis: analysis,
command_chain: chain.map((step, idx) => ({
index: idx,
command: step.cmd,
status: idx === 0 ? 'running' : 'pending'
})),
current_index: 0
};
Write(`${stateDir}/status.json`, JSON.stringify(state, null, 2));
return { sessionId, stateDir, state };
}
```
**Output**: `-> CCW:rapid: [1/3] /workflow:lite-plan | CCW:rapid: [2/3] /workflow:lite-execute | ...`
**Output**:
- TODO: `-> CCW:rapid: [1/3] /workflow:lite-plan | CCW:rapid: [2/3] /workflow:lite-execute | ...`
- Status File: `.workflow/.ccw/{session_id}/status.json`
---
### Phase 5: Execute Command Chain
```javascript
async function executeCommandChain(chain, workflow) {
async function executeCommandChain(chain, workflow, trackingState) {
let previousResult = null;
const { sessionId, stateDir, state } = trackingState;
for (let i = 0; i < chain.length; i++) {
try {
// Update status: mark current as running
state.command_chain[i].status = 'running';
state.current_index = i;
state.updated_at = new Date().toISOString();
Write(`${stateDir}/status.json`, JSON.stringify(state, null, 2));
const fullCommand = assembleCommand(chain[i], previousResult);
const result = await Skill({ skill: fullCommand });
previousResult = { ...result, success: true };
// Update status: mark current as completed, next as running
state.command_chain[i].status = 'completed';
if (i + 1 < chain.length) {
state.command_chain[i + 1].status = 'running';
}
state.updated_at = new Date().toISOString();
Write(`${stateDir}/status.json`, JSON.stringify(state, null, 2));
updateTodoStatus(i, chain.length, workflow, 'completed');
} catch (error) {
// Update status on error
state.command_chain[i].status = 'failed';
state.status = 'error';
state.updated_at = new Date().toISOString();
Write(`${stateDir}/status.json`, JSON.stringify(state, null, 2));
const action = await handleError(chain[i], error, i);
if (action === 'retry') {
state.command_chain[i].status = 'pending';
state.status = 'running';
i--; // Retry
} else if (action === 'abort') {
state.status = 'failed';
Write(`${stateDir}/status.json`, JSON.stringify(state, null, 2));
return { success: false, error: error.message };
}
// 'skip' - continue
state.status = 'running';
}
}
return { success: true, completed: chain.length };
// Mark workflow as completed
state.status = 'completed';
state.updated_at = new Date().toISOString();
Write(`${stateDir}/status.json`, JSON.stringify(state, null, 2));
return { success: true, completed: chain.length, sessionId };
}
// Assemble full command with session/plan parameters
@@ -434,16 +492,19 @@ Phase 3: User Confirmation (optional)
|-- Show pipeline visualization
+-- Allow adjustment
|
Phase 4: Setup TODO Tracking
+-- Create todos with CCW prefix
Phase 4: Setup TODO Tracking & Status File
|-- Create todos with CCW prefix
+-- Initialize .workflow/.ccw/{session_id}/status.json
|
Phase 5: Execute Command Chain
|-- For each command:
| |-- Update status.json (current=running)
| |-- Assemble full command
| |-- Execute via Skill
| |-- Update status.json (current=completed, next=running)
| |-- Update TODO status
| +-- Handle errors (retry/skip/abort)
+-- Return workflow result
+-- Mark status.json as completed
```
---
@@ -482,7 +543,9 @@ Phase 5: Execute Command Chain
## State Management
**TodoWrite-Based Tracking**: All execution state tracked via TodoWrite with `CCW:` prefix.
### Dual Tracking System
**1. TodoWrite-Based Tracking** (UI Display): All execution state tracked via TodoWrite with `CCW:` prefix.
```javascript
// Initial state
@@ -500,7 +563,57 @@ todos = [
];
```
**vs ccw-coordinator**: Extensive state.json with task_id, status transitions, hook callbacks.
**2. Status.json Tracking**: Persistent state file for workflow monitoring.
**Location**: `.workflow/.ccw/{session_id}/status.json`
**Structure**:
```json
{
"session_id": "ccw-1706123456789",
"workflow": "rapid",
"status": "running|completed|failed|error",
"created_at": "2025-02-01T10:30:00Z",
"updated_at": "2025-02-01T10:35:00Z",
"analysis": {
"goal": "Add user authentication",
"scope": ["auth"],
"constraints": [],
"task_type": "feature",
"complexity": "medium"
},
"command_chain": [
{
"index": 0,
"command": "/workflow:lite-plan",
"status": "completed"
},
{
"index": 1,
"command": "/workflow:lite-execute",
"status": "running"
},
{
"index": 2,
"command": "/workflow:test-cycle-execute",
"status": "pending"
}
],
"current_index": 1
}
```
**Status Values**:
- `running`: Workflow executing commands
- `completed`: All commands finished
- `failed`: User aborted or unrecoverable error
- `error`: Command execution failed (during error handling)
**Command Status Values**:
- `pending`: Not started
- `running`: Currently executing
- `completed`: Successfully finished
- `failed`: Execution failed
---
@@ -527,20 +640,6 @@ todos = [
---
## Type Comparison: ccw vs ccw-coordinator
| Aspect | ccw | ccw-coordinator |
|--------|-----|-----------------|
| **Type** | Main process (Skill) | External CLI (ccw cli + hook callbacks) |
| **Execution** | Synchronous blocking | Async background with hook completion |
| **Workflow** | Auto intent-based selection | Manual chain building |
| **Intent Analysis** | 5-phase clarity check | 3-phase requirement analysis |
| **State** | TodoWrite only (in-memory) | state.json + checkpoint/resume |
| **Error Handling** | Retry/skip/abort (interactive) | Retry/skip/abort (via AskUser) |
| **Use Case** | Auto workflow for any task | Manual orchestration, large chains |
---
## Usage
```bash

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff