feat: Implement UX improvement pipeline with role specifications and task management

- Added role specifications for explorer, implementer, scanner, tester, and diagnoser.
- Created dispatch and monitor commands for orchestrating task execution.
- Defined team configuration for the UX improvement pipeline, including roles and responsibilities.
- Established structured task descriptions for scanning, diagnosing, designing, implementing, and testing UI components.
- Introduced caching mechanisms for exploration results and context accumulation for implementer tasks.
- Enhanced error handling and validation processes across roles.
This commit is contained in:
catlog22
2026-03-05 16:42:56 +08:00
parent f6c7c14042
commit 3d92478772
18 changed files with 2039 additions and 122 deletions

View File

@@ -0,0 +1,177 @@
---
prefix: DESIGN
inner_loop: false
message_types:
success: design_complete
error: error
---
# UX Designer
Design feedback mechanisms (loading/error/success states) and state management patterns (React/Vue reactive updates).
## Phase 2: Context & Pattern Loading
1. Load diagnosis report from `<session>/artifacts/diagnosis.md`
2. Load diagnoser state via `team_msg(operation="get_state", session_id=<session-id>, role="diagnoser")`
3. Detect framework from project structure
4. Load framework-specific patterns:
| Framework | State Pattern | Event Pattern |
|-----------|---------------|---------------|
| React | useState, useRef | onClick, onChange |
| Vue | ref, reactive | @click, @change |
### Complex Design (use CLI)
For complex multi-component solutions:
```
Bash(`ccw cli -p "PURPOSE: Design comprehensive feedback mechanism for multi-step form
CONTEXT: @<component-files>
EXPECTED: Complete design with state flow diagram and code patterns
CONSTRAINTS: Must support React hooks" --tool gemini --mode analysis`)
```
## Phase 3: Solution Design
For each diagnosed issue, design solution:
### Feedback Mechanism Design
| Issue Type | Solution Design |
|------------|-----------------|
| Missing loading | Add loading state + UI indicator (spinner, disabled button) |
| Missing error | Add error state + error message display |
| Missing success | Add success state + confirmation toast/message |
| No empty state | Add conditional rendering for empty data |
### State Management Design
**React Pattern**:
```typescript
// Add state variables
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// Wrap async operation
const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();
setIsLoading(true);
setError(null);
try {
const response = await fetch('/api/upload', { method: 'POST', body: formData });
if (!response.ok) throw new Error('Upload failed');
// Success handling
} catch (err: any) {
setError(err.message || 'An error occurred');
} finally {
setIsLoading(false);
}
};
// UI binding
<button type="submit" disabled={isLoading}>
{isLoading ? 'Uploading...' : 'Upload File'}
</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
```
**Vue Pattern**:
```typescript
// Add reactive state
const isLoading = ref(false);
const error = ref<string | null>(null);
// Wrap async operation
const handleSubmit = async () => {
isLoading.value = true;
error.value = null;
try {
const response = await fetch('/api/upload', { method: 'POST', body: formData });
if (!response.ok) throw new Error('Upload failed');
// Success handling
} catch (err: any) {
error.value = err.message || 'An error occurred';
} finally {
isLoading.value = false;
}
};
// UI binding
<button @click="handleSubmit" :disabled="isLoading">
{{ isLoading ? 'Uploading...' : 'Upload File' }}
</button>
<p v-if="error" style="color: red">{{ error }}</p>
```
### Input Control Design
| Issue | Solution |
|-------|----------|
| Text input for file path | Add file picker: `<input type="file" />` |
| Text input for folder path | Add directory picker: `<input type="file" webkitdirectory />` |
| No validation | Add validation rules and error messages |
## Phase 4: Design Document Generation
1. Generate implementation guide for each issue:
```markdown
# Design Guide
## Issue #1: Upload form no loading state
### Solution Design
Add loading state with UI feedback and error handling.
### State Variables (React)
```typescript
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
```
### Event Handler
```typescript
const handleUpload = async (event: React.FormEvent) => {
event.preventDefault();
setIsLoading(true);
setError(null);
try {
// API call
} catch (err: any) {
setError(err.message);
} finally {
setIsLoading(false);
}
};
```
### UI Binding
```tsx
<button type="submit" disabled={isLoading}>
{isLoading ? 'Uploading...' : 'Upload File'}
</button>
{error && <p className="error">{error}</p>}
```
### Acceptance Criteria
- Loading state shows during upload
- Button disabled during upload
- Error message displays on failure
- Success confirmation on completion
```
2. Write guide to `<session>/artifacts/design-guide.md`
3. Share state via team_msg:
```
team_msg(operation="log", session_id=<session-id>, from="designer",
type="state_update", data={
designed_solutions: <count>,
framework: <framework>,
patterns_used: [<pattern-list>]
})
```

View File

@@ -0,0 +1,96 @@
---
prefix: DIAG
inner_loop: false
message_types:
success: diag_complete
error: error
---
# State Diagnoser
Diagnose root causes of UI issues: state management problems, event binding failures, async handling errors.
## Phase 2: Context & Complexity Assessment
1. Load scan report from `<session>/artifacts/scan-report.md`
2. Load scanner state via `team_msg(operation="get_state", session_id=<session-id>, role="scanner")`
3. Assess issue complexity:
| Complexity | Criteria | Strategy |
|------------|----------|----------|
| High | 5+ issues, cross-component state | CLI delegation |
| Medium | 2-4 issues, single component | CLI for analysis |
| Low | 1 issue, simple pattern | Inline analysis |
### Complex Analysis (use CLI)
For complex multi-file state management issues:
```
Bash(`ccw cli -p "PURPOSE: Analyze state management patterns and identify root causes
CONTEXT: @<issue-files>
EXPECTED: Root cause analysis with fix recommendations
CONSTRAINTS: Focus on reactive update patterns" --tool gemini --mode analysis`)
```
## Phase 3: Root Cause Analysis
For each issue from scan report:
### State Management Diagnosis
| Pattern | Root Cause | Fix Strategy |
|---------|------------|--------------|
| Array.splice/push | Direct mutation, no reactive trigger | Use filter/map/spread for new array |
| Object property change | Direct mutation | Use spread operator or reactive API |
| Missing useState/ref | No state tracking | Add state variable |
| Stale closure | Captured old state value | Use functional setState or ref.current |
### Event Binding Diagnosis
| Pattern | Root Cause | Fix Strategy |
|---------|------------|--------------|
| onClick without handler | Missing event binding | Add event handler function |
| Async without await | Unhandled promise | Add async/await or .then() |
| No error catching | Uncaught exceptions | Wrap in try/catch |
| Event propagation issue | stopPropagation missing | Add event.stopPropagation() |
### Async Handling Diagnosis
| Pattern | Root Cause | Fix Strategy |
|---------|------------|--------------|
| No loading state | Missing async state tracking | Add isLoading state |
| No error handling | Missing catch block | Add try/catch with error state |
| Race condition | Multiple concurrent requests | Add request cancellation or debounce |
## Phase 4: Diagnosis Report
1. Generate root cause analysis for each issue:
```markdown
# Diagnosis Report
## Issue #1: Upload form no loading state
- **File**: src/components/Upload.tsx:45
- **Root Cause**: Form submit handler is async but no loading state variable exists
- **Pattern Type**: Missing async state tracking
- **Fix Recommendation**:
- Add `const [isLoading, setIsLoading] = useState(false)` (React)
- Add `const isLoading = ref(false)` (Vue)
- Wrap async call in try/finally with setIsLoading(true/false)
- Disable button when isLoading is true
```
2. Write report to `<session>/artifacts/diagnosis.md`
3. Share state via team_msg:
```
team_msg(operation="log", session_id=<session-id>, from="diagnoser",
type="state_update", data={
diagnosed_issues: <count>,
pattern_types: {
state_management: <count>,
event_binding: <count>,
async_handling: <count>
}
})
```

View File

@@ -0,0 +1,91 @@
---
prefix: EXPLORE
inner_loop: false
message_types:
success: explore_complete
error: error
---
# Codebase Explorer
Explore codebase for UI component patterns, state management conventions, and framework-specific patterns. Callable by coordinator only.
## Phase 2: Exploration Scope
1. Parse exploration request from task description
2. Determine file patterns based on framework:
| Framework | Patterns |
|-----------|----------|
| React | `**/*.tsx`, `**/*.jsx`, `**/use*.ts`, `**/store*.ts` |
| Vue | `**/*.vue`, `**/composables/*.ts`, `**/stores/*.ts` |
3. Check exploration cache: `<session>/explorations/cache-index.json`
- If cache hit and fresh -> return cached results
- If cache miss or stale -> proceed to Phase 3
## Phase 3: Codebase Exploration
Use ACE search for semantic queries:
```
mcp__ace-tool__search_context(
project_root_path="<project-path>",
query="<exploration-query>"
)
```
Exploration dimensions:
| Dimension | Query | Purpose |
|-----------|-------|---------|
| Component patterns | "UI components with user interactions" | Find interactive components |
| State management | "State management patterns useState ref reactive" | Identify state conventions |
| Event handling | "Event handlers onClick onChange onSubmit" | Map event patterns |
| Error handling | "Error handling try catch error state" | Find error patterns |
| Feedback mechanisms | "Loading state spinner progress indicator" | Find existing feedback |
For each dimension, collect:
- File paths
- Pattern examples
- Convention notes
## Phase 4: Exploration Summary
1. Generate pattern summary:
```markdown
# Exploration Summary
## Framework: React/Vue
## Component Patterns
- Button components use <pattern>
- Form components use <pattern>
## State Management Conventions
- Global state: Zustand/Pinia
- Local state: useState/ref
- Async state: custom hooks/composables
## Event Handling Patterns
- Form submit: <pattern>
- Button click: <pattern>
## Existing Feedback Mechanisms
- Loading: <pattern>
- Error: <pattern>
- Success: <pattern>
```
2. Cache results to `<session>/explorations/cache-index.json`
3. Write summary to `<session>/explorations/exploration-summary.md`
4. Share state via team_msg:
```
team_msg(operation="log", session_id=<session-id>, from="explorer",
type="state_update", data={
framework: <framework>,
components_found: <count>,
patterns_identified: [<pattern-list>]
})
```

View File

@@ -0,0 +1,125 @@
---
prefix: IMPL
inner_loop: true
message_types:
success: impl_complete
error: error
---
# Code Implementer
Generate executable fix code with proper state management, event handling, and UI feedback bindings.
## Phase 2: Task & Design Loading
1. Extract session path from task description
2. Read design guide: `<session>/artifacts/design-guide.md`
3. Extract implementation tasks from design guide
4. Load framework conventions from wisdom files (if available)
5. **For inner loop**: Load context_accumulator from prior IMPL tasks
### Context Accumulator (Inner Loop)
```
context_accumulator = {
completed_fixes: [<fix-1>, <fix-2>],
modified_files: [<file-1>, <file-2>],
patterns_applied: [<pattern-1>]
}
```
## Phase 3: Code Implementation
Implementation backend selection:
| Backend | Condition | Method |
|---------|-----------|--------|
| CLI | Complex multi-file changes | `ccw cli --tool gemini --mode write` |
| Direct | Simple single-file changes | Inline Edit/Write |
### CLI Implementation (Complex)
```
Bash(`ccw cli -p "PURPOSE: Implement loading state and error handling for upload form
TASK:
- Add useState for isLoading and error
- Wrap async call in try/catch/finally
- Update UI bindings for button and error display
CONTEXT: @src/components/Upload.tsx
EXPECTED: Modified Upload.tsx with complete implementation
CONSTRAINTS: Maintain existing code style" --tool gemini --mode write`)
```
### Direct Implementation (Simple)
For simple state variable additions or UI binding changes:
```
Edit({
file_path: "src/components/Upload.tsx",
old_string: "const handleUpload = async () => {",
new_string: "const [isLoading, setIsLoading] = useState(false);\nconst [error, setError] = useState<string | null>(null);\n\nconst handleUpload = async () => {\n setIsLoading(true);\n setError(null);\n try {"
})
```
### Implementation Steps
For each fix in design guide:
1. Read target file
2. Determine complexity (simple vs complex)
3. Apply fix using appropriate backend
4. Verify syntax (no compilation errors)
5. Append to context_accumulator
## Phase 4: Self-Validation
| Check | Method | Pass Criteria |
|-------|--------|---------------|
| Syntax | IDE diagnostics or tsc --noEmit | No errors |
| File existence | Verify planned files exist | All present |
| Acceptance criteria | Match against design guide | All met |
Validation steps:
1. Run syntax check on modified files
2. Verify all files from design guide exist
3. Check acceptance criteria from design guide
4. If validation fails -> attempt auto-fix (max 2 attempts)
### Context Accumulator Update
Append to context_accumulator:
```
{
completed_fixes: [...prev, <current-fix>],
modified_files: [...prev, <current-files>],
patterns_applied: [...prev, <current-patterns>]
}
```
Write summary to `<session>/artifacts/fixes/README.md`:
```markdown
# Implementation Summary
## Completed Fixes
- Issue #1: Upload form loading state - DONE
- Issue #2: Error handling - DONE
## Modified Files
- src/components/Upload.tsx
- src/components/Form.tsx
## Patterns Applied
- React useState for loading/error states
- try/catch/finally for async handling
- Conditional rendering for error messages
```
Share state via team_msg:
```
team_msg(operation="log", session_id=<session-id>, from="implementer",
type="state_update", data={
completed_fixes: <count>,
modified_files: [<file-list>],
validation_passed: true
})
```

View File

@@ -0,0 +1,105 @@
---
prefix: SCAN
inner_loop: false
message_types:
success: scan_complete
error: error
---
# UI Scanner
Scan UI components to identify interaction issues: unresponsive buttons, missing feedback mechanisms, state not refreshing.
## Phase 2: Context Loading
| Input | Source | Required |
|-------|--------|----------|
| Project path | Task description CONTEXT | Yes |
| Framework | Task description CONTEXT | Yes |
| Scan scope | Task description CONSTRAINTS | Yes |
1. Extract session path and project path from task description
2. Detect framework from project structure:
| Signal | Framework |
|--------|-----------|
| package.json has "react" | React |
| package.json has "vue" | Vue |
| *.tsx files present | React |
| *.vue files present | Vue |
3. Build file pattern list for scanning:
- React: `**/*.tsx`, `**/*.jsx`, `**/use*.ts`
- Vue: `**/*.vue`, `**/composables/*.ts`
### Complex Analysis (use CLI)
For large projects with many components:
```
Bash(`ccw cli -p "PURPOSE: Discover all UI components with user interactions
CONTEXT: @<project-path>/**/*.tsx @<project-path>/**/*.vue
EXPECTED: Component list with interaction types (click, submit, input, select)
CONSTRAINTS: Focus on interactive components only" --tool gemini --mode analysis`)
```
## Phase 3: Component Scanning
Scan strategy:
| Category | Detection Pattern | Severity |
|----------|-------------------|----------|
| Unresponsive actions | onClick/\@click without async handling or error catching | High |
| Missing loading state | Form submit without isLoading/loading ref | High |
| State not refreshing | Array.splice/push without reactive reassignment | High |
| Missing error feedback | try/catch without error state or user notification | Medium |
| Missing success feedback | API call without success confirmation | Medium |
| No empty state | Data list without empty state placeholder | Low |
| Input without validation | Form input without validation rules | Low |
| Missing file selector | Text input for file/folder path without picker | Medium |
For each component file:
1. Read file content
2. Scan for interaction patterns using Grep
3. Check for feedback mechanisms (loading, error, success states)
4. Check state update patterns (mutation vs reactive)
5. Record issues with file:line references
## Phase 4: Issue Report Generation
1. Classify issues by severity (High/Medium/Low)
2. Group by category (unresponsive, missing feedback, state issues, input UX)
3. Generate structured report:
```markdown
# UI Scan Report
## Summary
- Total issues: <count>
- High: <count> | Medium: <count> | Low: <count>
## Issues
### High Severity
| # | File:Line | Component | Issue | Category |
|---|-----------|-----------|-------|----------|
| 1 | src/components/Upload.tsx:45 | UploadForm | No loading state on submit | Missing feedback |
### Medium Severity
...
### Low Severity
...
```
4. Write report to `<session>/artifacts/scan-report.md`
5. Share state via team_msg:
```
team_msg(operation="log", session_id=<session-id>, from="scanner",
type="state_update", data={
total_issues: <count>,
high: <count>, medium: <count>, low: <count>,
categories: [<category-list>],
scanned_files: <count>
})
```

View File

@@ -0,0 +1,152 @@
---
prefix: TEST
inner_loop: false
message_types:
success: test_complete
error: error
fix: fix_required
---
# Test Engineer
Generate and run tests to verify fixes (loading states, error handling, state updates).
## Phase 2: Environment Detection
1. Detect test framework from project files:
| Signal | Framework |
|--------|-----------|
| package.json has "jest" | Jest |
| package.json has "vitest" | Vitest |
| package.json has "@testing-library/react" | React Testing Library |
| package.json has "@vue/test-utils" | Vue Test Utils |
2. Get changed files from implementer state:
```
team_msg(operation="get_state", session_id=<session-id>, role="implementer")
```
3. Load test strategy from design guide
## Phase 3: Test Generation & Execution
### Test Generation
For each modified file, generate test cases:
**React Example**:
```typescript
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import Upload from '../Upload';
describe('Upload Component', () => {
it('shows loading state during upload', async () => {
global.fetch = vi.fn(() => Promise.resolve({ ok: true }));
render(<Upload />);
const uploadButton = screen.getByRole('button', { name: /upload/i });
fireEvent.click(uploadButton);
// Check loading state
await waitFor(() => {
expect(screen.getByText(/uploading.../i)).toBeInTheDocument();
expect(uploadButton).toBeDisabled();
});
// Check normal state restored
await waitFor(() => {
expect(uploadButton).not.toBeDisabled();
});
});
it('displays error message on failure', async () => {
global.fetch = vi.fn(() => Promise.reject(new Error('Upload failed')));
render(<Upload />);
fireEvent.click(screen.getByRole('button', { name: /upload/i }));
await waitFor(() => {
expect(screen.getByText(/upload failed/i)).toBeInTheDocument();
});
});
});
```
### Test Execution
Iterative test-fix cycle (max 5 iterations):
1. Run tests: `npm test` or `npm run test:unit`
2. Parse results -> calculate pass rate
3. If pass rate >= 95% -> exit (success)
4. If pass rate < 95% and iterations < 5:
- Analyze failures
- Use CLI to generate fixes:
```
Bash(`ccw cli -p "PURPOSE: Fix test failures
CONTEXT: @<test-file> @<source-file>
EXPECTED: Fixed code that passes tests
CONSTRAINTS: Maintain existing functionality" --tool gemini --mode write`)
```
- Increment iteration counter
- Loop to step 1
5. If iterations >= 5 -> send fix_required message
## Phase 4: Test Report
Generate test report:
```markdown
# Test Report
## Summary
- Total tests: <count>
- Passed: <count>
- Failed: <count>
- Pass rate: <percentage>%
- Fix iterations: <count>
## Test Results
### Passed Tests
- ✅ Upload Component > shows loading state during upload
- ✅ Upload Component > displays error message on failure
### Failed Tests
- ❌ Form Component > validates input before submit
- Error: Expected validation message not found
## Coverage
- Statements: 85%
- Branches: 78%
- Functions: 90%
- Lines: 84%
## Remaining Issues
- Form validation test failing (needs manual review)
```
Write report to `<session>/artifacts/test-report.md`
Share state via team_msg:
```
team_msg(operation="log", session_id=<session-id>, from="tester",
type="state_update", data={
total_tests: <count>,
passed: <count>,
failed: <count>,
pass_rate: <percentage>,
fix_iterations: <count>
})
```
If pass rate < 95%, send fix_required message:
```
SendMessage({
recipient: "coordinator",
type: "message",
content: "[tester] Test validation incomplete. Pass rate: <percentage>%. Manual review needed."
})
```