mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-07 16:41:06 +08:00
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:
177
.claude/skills/team-ux-improve/role-specs/designer.md
Normal file
177
.claude/skills/team-ux-improve/role-specs/designer.md
Normal 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>]
|
||||
})
|
||||
```
|
||||
96
.claude/skills/team-ux-improve/role-specs/diagnoser.md
Normal file
96
.claude/skills/team-ux-improve/role-specs/diagnoser.md
Normal 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>
|
||||
}
|
||||
})
|
||||
```
|
||||
91
.claude/skills/team-ux-improve/role-specs/explorer.md
Normal file
91
.claude/skills/team-ux-improve/role-specs/explorer.md
Normal 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>]
|
||||
})
|
||||
```
|
||||
125
.claude/skills/team-ux-improve/role-specs/implementer.md
Normal file
125
.claude/skills/team-ux-improve/role-specs/implementer.md
Normal 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
|
||||
})
|
||||
```
|
||||
105
.claude/skills/team-ux-improve/role-specs/scanner.md
Normal file
105
.claude/skills/team-ux-improve/role-specs/scanner.md
Normal 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>
|
||||
})
|
||||
```
|
||||
152
.claude/skills/team-ux-improve/role-specs/tester.md
Normal file
152
.claude/skills/team-ux-improve/role-specs/tester.md
Normal 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."
|
||||
})
|
||||
```
|
||||
Reference in New Issue
Block a user