mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-03-06 16:31:12 +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:
283
.claude/skills/team-ux-improve/SKILL.md
Normal file
283
.claude/skills/team-ux-improve/SKILL.md
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
---
|
||||||
|
name: team-ux-improve
|
||||||
|
description: Unified team skill for UX improvement. Systematically discovers and fixes UI/UX interaction issues including unresponsive buttons, missing feedback, and state refresh problems. Uses team-worker agent architecture with role-spec files for domain logic. Coordinator orchestrates pipeline, workers are team-worker agents. Triggers on "team ux improve".
|
||||||
|
allowed-tools: Agent, AskUserQuestion, Read, Write, Edit, Bash, Glob, Grep, TaskList, TaskGet, TaskUpdate, TaskCreate, TeamCreate, TeamDelete, SendMessage, mcp__ace-tool__search_context, mcp__ccw-tools__read_file, mcp__ccw-tools__write_file, mcp__ccw-tools__edit_file, mcp__ccw-tools__team_msg
|
||||||
|
---
|
||||||
|
|
||||||
|
# Team UX Improve
|
||||||
|
|
||||||
|
Unified team skill for systematically discovering and fixing UI/UX interaction issues. Built on **team-worker agent architecture** — all worker roles share a single agent definition with role-specific Phase 2-4 loaded from markdown specs.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
+-------------------------------------------------------------------+
|
||||||
|
| Skill(skill="team-ux-improve") |
|
||||||
|
| args="<project-path> [--framework react|vue]" |
|
||||||
|
+-------------------+-----------------------------------------------+
|
||||||
|
|
|
||||||
|
Orchestration Mode (auto -> coordinator)
|
||||||
|
|
|
||||||
|
Coordinator (inline)
|
||||||
|
Phase 0-5 orchestration
|
||||||
|
|
|
||||||
|
+-------+-------+-------+-------+-------+
|
||||||
|
v v v v v v
|
||||||
|
[team-worker agents, each loaded with a role-spec]
|
||||||
|
scanner diagnoser designer implementer tester
|
||||||
|
|
||||||
|
Utility Members (spawned by coordinator for utility work):
|
||||||
|
[explorer]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Role Router
|
||||||
|
|
||||||
|
This skill is **coordinator-only**. Workers do NOT invoke this skill — they are spawned as `team-worker` agents directly.
|
||||||
|
|
||||||
|
### Input Parsing
|
||||||
|
|
||||||
|
Parse `$ARGUMENTS`. No `--role` needed — always routes to coordinator.
|
||||||
|
|
||||||
|
### Role Registry
|
||||||
|
|
||||||
|
| Role | Spec | Task Prefix | Type | Inner Loop |
|
||||||
|
|------|------|-------------|------|------------|
|
||||||
|
| coordinator | [roles/coordinator/role.md](roles/coordinator/role.md) | (none) | orchestrator | - |
|
||||||
|
| scanner | [role-specs/scanner.md](role-specs/scanner.md) | SCAN-* | worker | false |
|
||||||
|
| diagnoser | [role-specs/diagnoser.md](role-specs/diagnoser.md) | DIAG-* | worker | false |
|
||||||
|
| designer | [role-specs/designer.md](role-specs/designer.md) | DESIGN-* | worker | false |
|
||||||
|
| implementer | [role-specs/implementer.md](role-specs/implementer.md) | IMPL-* | worker | true |
|
||||||
|
| tester | [role-specs/tester.md](role-specs/tester.md) | TEST-* | worker | false |
|
||||||
|
|
||||||
|
### Utility Member Registry
|
||||||
|
|
||||||
|
**⚠️ COORDINATOR ONLY**: Utility members can only be spawned by Coordinator. Workers CANNOT call Agent() to spawn utility members. Workers must use CLI tools instead.
|
||||||
|
|
||||||
|
| Utility Member | Spec | Callable By | Purpose |
|
||||||
|
|----------------|------|-------------|---------|
|
||||||
|
| explorer | [role-specs/explorer.md](role-specs/explorer.md) | **Coordinator only** | Explore codebase for UI component patterns, state management conventions, and framework-specific patterns |
|
||||||
|
|
||||||
|
### Worker Alternatives
|
||||||
|
|
||||||
|
Workers needing similar capabilities must use CLI tools:
|
||||||
|
|
||||||
|
| Capability | CLI Command | Example |
|
||||||
|
|------------|-------------|---------|
|
||||||
|
| Codebase exploration | `ccw cli --tool gemini --mode analysis` | Explore architecture patterns |
|
||||||
|
| Multi-perspective critique | Parallel CLI calls | Security + performance + quality reviews |
|
||||||
|
| Document generation | `ccw cli --tool gemini --mode write` | Generate implementation guide |
|
||||||
|
|
||||||
|
### Dispatch
|
||||||
|
|
||||||
|
Always route to coordinator. Coordinator reads `roles/coordinator/role.md` and executes its phases.
|
||||||
|
|
||||||
|
### Orchestration Mode
|
||||||
|
|
||||||
|
User provides project path and optional framework flag.
|
||||||
|
|
||||||
|
**Invocation**: `Skill(skill="team-ux-improve", args="<project-path> [--framework react|vue]")`
|
||||||
|
|
||||||
|
**Lifecycle**:
|
||||||
|
```
|
||||||
|
User provides project path
|
||||||
|
-> coordinator Phase 1-3: Requirement clarification -> TeamCreate -> Create task chain
|
||||||
|
-> coordinator Phase 4: spawn first batch workers (background) -> STOP
|
||||||
|
-> Worker (team-worker agent) executes -> SendMessage callback -> coordinator advances
|
||||||
|
-> Loop until pipeline complete -> Phase 5 report + completion action
|
||||||
|
```
|
||||||
|
|
||||||
|
**User Commands** (wake paused coordinator):
|
||||||
|
|
||||||
|
| Command | Action |
|
||||||
|
|---------|--------|
|
||||||
|
| `check` / `status` | Output execution status graph, no advancement |
|
||||||
|
| `resume` / `continue` | Check worker states, advance next step |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Command Execution Protocol
|
||||||
|
|
||||||
|
When coordinator needs to execute a command (dispatch, monitor):
|
||||||
|
|
||||||
|
1. **Read the command file**: `roles/coordinator/commands/<command-name>.md`
|
||||||
|
2. **Follow the workflow** defined in the command file (Phase 2-4 structure)
|
||||||
|
3. **Commands are inline execution guides** - NOT separate agents or subprocesses
|
||||||
|
4. **Execute synchronously** - complete the command workflow before proceeding
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
Phase 3 needs task dispatch
|
||||||
|
-> Read roles/coordinator/commands/dispatch.md
|
||||||
|
-> Execute Phase 2 (Context Loading)
|
||||||
|
-> Execute Phase 3 (Task Chain Creation)
|
||||||
|
-> Execute Phase 4 (Validation)
|
||||||
|
-> Continue to Phase 4
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Coordinator Spawn Template
|
||||||
|
|
||||||
|
### v5 Worker Spawn (all roles)
|
||||||
|
|
||||||
|
When coordinator spawns workers, use `team-worker` agent with role-spec path:
|
||||||
|
|
||||||
|
```
|
||||||
|
Agent({
|
||||||
|
subagent_type: "team-worker",
|
||||||
|
description: "Spawn <role> worker",
|
||||||
|
team_name: <team-name>,
|
||||||
|
name: "<role>",
|
||||||
|
run_in_background: true,
|
||||||
|
prompt: `## Role Assignment
|
||||||
|
role: <role>
|
||||||
|
role_spec: .claude/skills/team-ux-improve/role-specs/<role>.md
|
||||||
|
session: <session-folder>
|
||||||
|
session_id: <session-id>
|
||||||
|
team_name: <team-name>
|
||||||
|
requirement: <task-description>
|
||||||
|
inner_loop: <true|false>
|
||||||
|
|
||||||
|
Read role_spec file to load Phase 2-4 domain instructions.
|
||||||
|
Execute built-in Phase 1 (task discovery) -> role-spec Phase 2-4 -> built-in Phase 5 (report).`
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
**Inner Loop roles** (implementer): Set `inner_loop: true`. The team-worker agent handles the loop internally.
|
||||||
|
|
||||||
|
**Single-task roles** (scanner, diagnoser, designer, tester): Set `inner_loop: false`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pipeline Definitions
|
||||||
|
|
||||||
|
### Pipeline Diagram
|
||||||
|
|
||||||
|
```
|
||||||
|
scanner (SCAN) → diagnoser (DIAG) → designer (DESIGN) → implementer (IMPL) → tester (TEST)
|
||||||
|
|
||||||
|
Stage 1: UI Scanning
|
||||||
|
└─ scanner: Scan UI components for interaction issues
|
||||||
|
|
||||||
|
Stage 2: Root Cause Diagnosis
|
||||||
|
└─ diagnoser: Diagnose root causes of identified issues
|
||||||
|
|
||||||
|
Stage 3: Solution Design
|
||||||
|
└─ designer: Design feedback mechanisms and state management solutions
|
||||||
|
|
||||||
|
Stage 4: Code Implementation
|
||||||
|
└─ implementer: Generate fix code with proper state handling
|
||||||
|
|
||||||
|
Stage 5: Test Validation
|
||||||
|
└─ tester: Generate and run tests to verify fixes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cadence Control
|
||||||
|
|
||||||
|
**Beat model**: Event-driven, each beat = coordinator wake -> process -> spawn -> STOP.
|
||||||
|
|
||||||
|
```
|
||||||
|
Beat Cycle (single beat)
|
||||||
|
======================================================================
|
||||||
|
Event Coordinator Workers
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
callback/resume --> +- handleCallback -+
|
||||||
|
| mark completed |
|
||||||
|
| check pipeline |
|
||||||
|
+- handleSpawnNext -+
|
||||||
|
| find ready tasks |
|
||||||
|
| spawn workers ---+--> [team-worker scanner] Phase 1-5
|
||||||
|
| (parallel OK) --+--> [team-worker diagnoser] Phase 1-5
|
||||||
|
+- STOP (idle) -----+ |
|
||||||
|
|
|
||||||
|
callback <-----------------------------------------+
|
||||||
|
(next beat) SendMessage + TaskUpdate(completed)
|
||||||
|
======================================================================
|
||||||
|
|
||||||
|
Fast-Advance (skips coordinator for simple linear successors)
|
||||||
|
======================================================================
|
||||||
|
[Worker scanner] Phase 5 complete
|
||||||
|
+- 1 ready task? simple successor?
|
||||||
|
| --> spawn team-worker diagnoser directly
|
||||||
|
| --> log fast_advance to message bus (coordinator syncs on next wake)
|
||||||
|
+- complex case? --> SendMessage to coordinator
|
||||||
|
======================================================================
|
||||||
|
```
|
||||||
|
|
||||||
|
**Checkpoints**:
|
||||||
|
|
||||||
|
| Checkpoint | Trigger | Location | Behavior |
|
||||||
|
|------------|---------|----------|----------|
|
||||||
|
| Pipeline complete | All tasks completed | coordinator Phase 5 | Execute completion action |
|
||||||
|
|
||||||
|
### Task Metadata Registry
|
||||||
|
|
||||||
|
| Task ID | Role | Phase | Dependencies | Description |
|
||||||
|
|---------|------|-------|-------------|-------------|
|
||||||
|
| SCAN-001 | scanner | 2-4 | [] | Scan UI components for interaction issues |
|
||||||
|
| DIAG-001 | diagnoser | 2-4 | [SCAN-001] | Diagnose root causes of identified issues |
|
||||||
|
| DESIGN-001 | designer | 2-4 | [DIAG-001] | Design feedback mechanisms and state management solutions |
|
||||||
|
| IMPL-001 | implementer | 2-4 | [DESIGN-001] | Generate fix code with proper state handling |
|
||||||
|
| TEST-001 | tester | 2-4 | [IMPL-001] | Generate and run tests to verify fixes |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Completion Action
|
||||||
|
|
||||||
|
When the pipeline completes (all tasks done, coordinator Phase 5):
|
||||||
|
|
||||||
|
```
|
||||||
|
AskUserQuestion({
|
||||||
|
questions: [{
|
||||||
|
question: "Team pipeline complete. What would you like to do?",
|
||||||
|
header: "Completion",
|
||||||
|
multiSelect: false,
|
||||||
|
options: [
|
||||||
|
{ label: "Archive & Clean (Recommended)", description: "Archive session, clean up tasks and team resources" },
|
||||||
|
{ label: "Keep Active", description: "Keep session active for follow-up work or inspection" },
|
||||||
|
{ label: "Export Results", description: "Export deliverables to a specified location, then clean" }
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
| Choice | Action |
|
||||||
|
|--------|--------|
|
||||||
|
| Archive & Clean | Update session status="completed" -> TeamDelete(ux-improve) -> output final summary |
|
||||||
|
| Keep Active | Update session status="paused" -> output resume instructions: `Skill(skill="team-ux-improve", args="resume")` |
|
||||||
|
| Export Results | AskUserQuestion for target path -> copy deliverables -> Archive & Clean |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session Directory
|
||||||
|
|
||||||
|
```
|
||||||
|
.workflow/.team/ux-improve-<timestamp>/
|
||||||
|
├── .msg/
|
||||||
|
│ ├── messages.jsonl ← Messages + state_update audit log
|
||||||
|
│ └── meta.json ← Pipeline config + role state snapshot
|
||||||
|
├── artifacts/ ← Role deliverables
|
||||||
|
│ ├── scan-report.md ← scanner output
|
||||||
|
│ ├── diagnosis.md ← diagnoser output
|
||||||
|
│ ├── design-guide.md ← designer output
|
||||||
|
│ ├── fixes/ ← implementer output
|
||||||
|
│ └── test-report.md ← tester output
|
||||||
|
├── explorations/ ← explorer cache
|
||||||
|
│ └── cache-index.json
|
||||||
|
└── wisdom/ ← Knowledge base
|
||||||
|
├── ui-patterns.md
|
||||||
|
└── state-management.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Role spec file not found | Error with expected path (role-specs/<name>.md) |
|
||||||
|
| Command file not found | Fallback to inline execution in coordinator role.md |
|
||||||
|
| Utility member spec not found | Error with expected path (role-specs/explorer.md) |
|
||||||
|
| Fast-advance orphan detected | Coordinator resets task to pending on next check |
|
||||||
|
| team-worker agent unavailable | Error: requires .claude/agents/team-worker.md |
|
||||||
|
| Completion action timeout | Default to Keep Active |
|
||||||
|
| Framework detection fails | Prompt user for framework selection |
|
||||||
|
| No UI issues found | Complete with empty fix list |
|
||||||
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."
|
||||||
|
})
|
||||||
|
```
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
# Dispatch Command
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Create task chains based on execution mode. Generate structured task descriptions with PURPOSE/TASK/CONTEXT/EXPECTED/CONSTRAINTS format.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: Context Loading
|
||||||
|
|
||||||
|
| Input | Source | Required |
|
||||||
|
|-------|--------|----------|
|
||||||
|
| Session ID | coordinator Phase 2 | Yes |
|
||||||
|
| Project path | coordinator Phase 1 | Yes |
|
||||||
|
| Framework | coordinator Phase 1 | Yes |
|
||||||
|
| Pipeline mode | meta.json | Yes |
|
||||||
|
|
||||||
|
1. Load session ID from coordinator context
|
||||||
|
2. Load project path and framework from meta.json
|
||||||
|
3. Determine pipeline mode (standard)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3: Task Chain Creation
|
||||||
|
|
||||||
|
### Task Description Template
|
||||||
|
|
||||||
|
Every task description uses structured format for clarity:
|
||||||
|
|
||||||
|
```
|
||||||
|
TaskCreate({
|
||||||
|
subject: "<TASK-ID>",
|
||||||
|
owner: "<role>",
|
||||||
|
description: "PURPOSE: <what this task achieves> | Success: <measurable completion criteria>
|
||||||
|
TASK:
|
||||||
|
- <step 1: specific action>
|
||||||
|
- <step 2: specific action>
|
||||||
|
- <step 3: specific action>
|
||||||
|
CONTEXT:
|
||||||
|
- Session: <session-folder>
|
||||||
|
- Scope: <scope>
|
||||||
|
- Upstream artifacts: <artifact-1.md>, <artifact-2.md>
|
||||||
|
- Key files: <file1>, <file2> (if applicable)
|
||||||
|
- State: via team_msg(operation="get_state", role=<upstream-role>)
|
||||||
|
EXPECTED: <deliverable path> + <quality criteria>
|
||||||
|
CONSTRAINTS: <scope limits, focus areas>
|
||||||
|
---
|
||||||
|
InnerLoop: <true|false>
|
||||||
|
<additional-metadata-fields>",
|
||||||
|
blockedBy: [<dependency-list>],
|
||||||
|
status: "pending"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Standard Pipeline Tasks
|
||||||
|
|
||||||
|
**SCAN-001: UI Component Scanning**
|
||||||
|
```
|
||||||
|
TaskCreate({
|
||||||
|
subject: "SCAN-001",
|
||||||
|
owner: "scanner",
|
||||||
|
description: "PURPOSE: Scan UI components to identify interaction issues (unresponsive buttons, missing feedback, state not refreshing) | Success: Complete issue report with file:line references and severity classification
|
||||||
|
TASK:
|
||||||
|
- Detect framework (React/Vue) from project structure
|
||||||
|
- Scan UI components for interaction patterns using ACE search and file analysis
|
||||||
|
- Identify missing feedback mechanisms (loading states, error handling, success confirmation)
|
||||||
|
- Detect unresponsive actions (event binding issues, async handling problems)
|
||||||
|
- Check state update patterns (mutation vs reactive updates)
|
||||||
|
CONTEXT:
|
||||||
|
- Session: <session-folder>
|
||||||
|
- Scope: Project path: <project-path>, Framework: <framework>
|
||||||
|
- File patterns: **/*.tsx, **/*.vue, **/*.jsx
|
||||||
|
- Focus: UI components with user interactions
|
||||||
|
EXPECTED: artifacts/scan-report.md with structured issue list (severity: High/Medium/Low, file:line, description, category)
|
||||||
|
CONSTRAINTS: Focus on interaction issues only, exclude styling/layout problems
|
||||||
|
---
|
||||||
|
InnerLoop: false",
|
||||||
|
blockedBy: [],
|
||||||
|
status: "pending"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
**DIAG-001: Root Cause Diagnosis**
|
||||||
|
```
|
||||||
|
TaskCreate({
|
||||||
|
subject: "DIAG-001",
|
||||||
|
owner: "diagnoser",
|
||||||
|
description: "PURPOSE: Diagnose root causes of identified UI issues | Success: Complete diagnosis report with fix recommendations for each issue
|
||||||
|
TASK:
|
||||||
|
- Load scan report from artifacts/scan-report.md
|
||||||
|
- Analyze state management patterns (direct mutation vs reactive updates)
|
||||||
|
- Trace event binding and propagation
|
||||||
|
- Check async handling (promises, callbacks, error catching)
|
||||||
|
- Identify framework-specific anti-patterns
|
||||||
|
- Use CLI for complex multi-file analysis when needed
|
||||||
|
CONTEXT:
|
||||||
|
- Session: <session-folder>
|
||||||
|
- Scope: Issues from scan report
|
||||||
|
- Upstream artifacts: artifacts/scan-report.md
|
||||||
|
- State: via team_msg(operation="get_state", role="scanner")
|
||||||
|
EXPECTED: artifacts/diagnosis.md with root cause analysis (issue ID, root cause, pattern type, fix recommendation)
|
||||||
|
CONSTRAINTS: Focus on actionable root causes, provide specific fix strategies
|
||||||
|
---
|
||||||
|
InnerLoop: false",
|
||||||
|
blockedBy: ["SCAN-001"],
|
||||||
|
status: "pending"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
**DESIGN-001: Solution Design**
|
||||||
|
```
|
||||||
|
TaskCreate({
|
||||||
|
subject: "DESIGN-001",
|
||||||
|
owner: "designer",
|
||||||
|
description: "PURPOSE: Design feedback mechanisms and state management solutions for identified issues | Success: Complete implementation guide with code patterns and examples
|
||||||
|
TASK:
|
||||||
|
- Load diagnosis report from artifacts/diagnosis.md
|
||||||
|
- Design feedback mechanisms (loading/error/success states) for each issue
|
||||||
|
- Design state management patterns (useState/ref, reactive updates)
|
||||||
|
- Design input control improvements (file selectors, validation)
|
||||||
|
- Generate framework-specific code patterns (React/Vue)
|
||||||
|
- Use CLI for complex multi-component solutions when needed
|
||||||
|
CONTEXT:
|
||||||
|
- Session: <session-folder>
|
||||||
|
- Scope: Issues from diagnosis report
|
||||||
|
- Upstream artifacts: artifacts/diagnosis.md
|
||||||
|
- Framework: <framework>
|
||||||
|
- State: via team_msg(operation="get_state", role="diagnoser")
|
||||||
|
EXPECTED: artifacts/design-guide.md with implementation guide (issue ID, solution design, code patterns, state management examples, UI binding templates)
|
||||||
|
CONSTRAINTS: Solutions must be framework-appropriate, provide complete working examples
|
||||||
|
---
|
||||||
|
InnerLoop: false",
|
||||||
|
blockedBy: ["DIAG-001"],
|
||||||
|
status: "pending"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
**IMPL-001: Code Implementation**
|
||||||
|
```
|
||||||
|
TaskCreate({
|
||||||
|
subject: "IMPL-001",
|
||||||
|
owner: "implementer",
|
||||||
|
description: "PURPOSE: Generate fix code with proper state management, event handling, and UI feedback bindings | Success: All fixes implemented and validated
|
||||||
|
TASK:
|
||||||
|
- Load design guide from artifacts/design-guide.md
|
||||||
|
- Extract implementation tasks from design guide
|
||||||
|
- Generate fix code with proper state management (useState/ref)
|
||||||
|
- Add event handlers with error catching
|
||||||
|
- Implement UI feedback bindings (loading/error/success)
|
||||||
|
- Use CLI for complex multi-file changes, direct Edit/Write for simple changes
|
||||||
|
- Validate syntax and file existence after each fix
|
||||||
|
CONTEXT:
|
||||||
|
- Session: <session-folder>
|
||||||
|
- Scope: Fixes from design guide
|
||||||
|
- Upstream artifacts: artifacts/design-guide.md
|
||||||
|
- Framework: <framework>
|
||||||
|
- State: via team_msg(operation="get_state", role="designer")
|
||||||
|
- Context accumulator: Load from prior IMPL tasks (inner loop)
|
||||||
|
EXPECTED: artifacts/fixes/ directory with all fix files, implementation summary in artifacts/fixes/README.md
|
||||||
|
CONSTRAINTS: Maintain existing code style, ensure backward compatibility, validate all changes
|
||||||
|
---
|
||||||
|
InnerLoop: true",
|
||||||
|
blockedBy: ["DESIGN-001"],
|
||||||
|
status: "pending"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
**TEST-001: Test Validation**
|
||||||
|
```
|
||||||
|
TaskCreate({
|
||||||
|
subject: "TEST-001",
|
||||||
|
owner: "tester",
|
||||||
|
description: "PURPOSE: Generate and run tests to verify fixes (loading states, error handling, state updates) | Success: Pass rate >= 95%, all critical fixes validated
|
||||||
|
TASK:
|
||||||
|
- Detect test framework (Jest/Vitest) from project
|
||||||
|
- Get changed files from implementer state
|
||||||
|
- Load test strategy from design guide
|
||||||
|
- Generate test cases for loading states, error handling, state updates
|
||||||
|
- Run tests and parse results
|
||||||
|
- If pass rate < 95%, use CLI to generate fixes (max 5 iterations)
|
||||||
|
- Generate test report with pass/fail counts, coverage, fix iterations
|
||||||
|
CONTEXT:
|
||||||
|
- Session: <session-folder>
|
||||||
|
- Scope: Fixes from implementer
|
||||||
|
- Upstream artifacts: artifacts/fixes/, artifacts/design-guide.md
|
||||||
|
- Framework: <framework>
|
||||||
|
- State: via team_msg(operation="get_state", role="implementer")
|
||||||
|
EXPECTED: artifacts/test-report.md with test results (pass/fail counts, coverage metrics, fix iterations, remaining issues)
|
||||||
|
CONSTRAINTS: Pass rate threshold: 95%, max fix iterations: 5
|
||||||
|
---
|
||||||
|
InnerLoop: false",
|
||||||
|
blockedBy: ["IMPL-001"],
|
||||||
|
status: "pending"
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4: Validation
|
||||||
|
|
||||||
|
1. Verify all tasks created successfully
|
||||||
|
2. Check task dependency chain is valid (no cycles)
|
||||||
|
3. Verify all task owners match Role Registry
|
||||||
|
4. Confirm task prefixes match role frontmatter
|
||||||
|
5. Output task count and dependency graph
|
||||||
|
|
||||||
|
| Check | Pass Criteria |
|
||||||
|
|-------|---------------|
|
||||||
|
| Task count | 5 tasks created |
|
||||||
|
| Dependencies | Linear chain: SCAN → DIAG → DESIGN → IMPL → TEST |
|
||||||
|
| Owners | All owners in Role Registry |
|
||||||
|
| Prefixes | Match role frontmatter |
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
# Monitor Command
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Handle worker callbacks, status checks, pipeline advancement, and completion detection.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Handlers
|
||||||
|
|
||||||
|
### handleCallback
|
||||||
|
|
||||||
|
**Trigger**: Worker SendMessage with `[scanner]`, `[diagnoser]`, `[designer]`, `[implementer]`, or `[tester]` tag.
|
||||||
|
|
||||||
|
1. Parse worker role from message tag
|
||||||
|
2. Mark corresponding task as completed: `TaskUpdate({ taskId: <task-id>, status: "completed" })`
|
||||||
|
3. Log completion to message bus:
|
||||||
|
```
|
||||||
|
team_msg(operation="log", session_id=<session-id>, from="coordinator",
|
||||||
|
type="task_complete", data={ role: <role>, task_id: <task-id> })
|
||||||
|
```
|
||||||
|
4. Check if all tasks completed -> handleComplete
|
||||||
|
5. Otherwise -> handleSpawnNext
|
||||||
|
|
||||||
|
### handleCheck
|
||||||
|
|
||||||
|
**Trigger**: User "check" or "status" command.
|
||||||
|
|
||||||
|
1. Load TaskList
|
||||||
|
2. Build status graph:
|
||||||
|
```
|
||||||
|
Pipeline Status:
|
||||||
|
✅ SCAN-001 (scanner) - completed
|
||||||
|
✅ DIAG-001 (diagnoser) - completed
|
||||||
|
🔄 DESIGN-001 (designer) - in_progress
|
||||||
|
⏳ IMPL-001 (implementer) - pending [blocked by DESIGN-001]
|
||||||
|
⏳ TEST-001 (tester) - pending [blocked by IMPL-001]
|
||||||
|
```
|
||||||
|
3. Output status graph, do NOT advance pipeline
|
||||||
|
4. STOP
|
||||||
|
|
||||||
|
### handleResume
|
||||||
|
|
||||||
|
**Trigger**: User "resume" or "continue" command.
|
||||||
|
|
||||||
|
1. Load TaskList
|
||||||
|
2. Check for fast-advance orphans:
|
||||||
|
- Tasks with status "in_progress" but no active worker
|
||||||
|
- Reset orphans to "pending"
|
||||||
|
3. -> handleSpawnNext
|
||||||
|
|
||||||
|
### handleSpawnNext
|
||||||
|
|
||||||
|
**Trigger**: After handleCallback or handleResume.
|
||||||
|
|
||||||
|
1. Load TaskList
|
||||||
|
2. Find ready tasks:
|
||||||
|
- status = "pending"
|
||||||
|
- All blockedBy tasks have status "completed"
|
||||||
|
3. For each ready task:
|
||||||
|
- Extract role from task owner
|
||||||
|
- Extract inner_loop from task description metadata
|
||||||
|
- Spawn team-worker agent:
|
||||||
|
```
|
||||||
|
Agent({
|
||||||
|
subagent_type: "team-worker",
|
||||||
|
description: "Spawn <role> worker",
|
||||||
|
team_name: "ux-improve",
|
||||||
|
name: "<role>",
|
||||||
|
run_in_background: true,
|
||||||
|
prompt: `## Role Assignment
|
||||||
|
role: <role>
|
||||||
|
role_spec: .claude/skills/team-ux-improve/role-specs/<role>.md
|
||||||
|
session: <session-folder>
|
||||||
|
session_id: <session-id>
|
||||||
|
team_name: ux-improve
|
||||||
|
requirement: <task-description>
|
||||||
|
inner_loop: <inner-loop-value>
|
||||||
|
|
||||||
|
Read role_spec file to load Phase 2-4 domain instructions.
|
||||||
|
Execute built-in Phase 1 -> role-spec Phase 2-4 -> built-in Phase 5.`
|
||||||
|
})
|
||||||
|
```
|
||||||
|
4. STOP (wait for next callback)
|
||||||
|
|
||||||
|
### handleConsensus
|
||||||
|
|
||||||
|
**Trigger**: consensus_blocked message from worker.
|
||||||
|
|
||||||
|
Route by severity:
|
||||||
|
|
||||||
|
| Severity | Action |
|
||||||
|
|----------|--------|
|
||||||
|
| HIGH | Pause pipeline, AskUserQuestion for resolution |
|
||||||
|
| MEDIUM | Log warning, continue pipeline |
|
||||||
|
| LOW | Log info, continue pipeline |
|
||||||
|
|
||||||
|
### handleComplete
|
||||||
|
|
||||||
|
**Trigger**: All tasks have status "completed".
|
||||||
|
|
||||||
|
1. Verify all tasks completed via TaskList
|
||||||
|
2. Generate pipeline summary:
|
||||||
|
- Total tasks: 5
|
||||||
|
- Duration: <calculated>
|
||||||
|
- Deliverables: list artifact paths
|
||||||
|
3. Execute completion action (see coordinator Phase 5)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fast-Advance Detection
|
||||||
|
|
||||||
|
When handleCallback detects a completed task:
|
||||||
|
|
||||||
|
| Condition | Action |
|
||||||
|
|-----------|--------|
|
||||||
|
| Exactly 1 ready successor, simple linear | Worker already fast-advanced, log sync |
|
||||||
|
| Multiple ready successors | Coordinator spawns all |
|
||||||
|
| No ready successors, all done | -> handleComplete |
|
||||||
|
| No ready successors, some pending | Wait (blocked tasks) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Worker callback with unknown role | Log warning, ignore |
|
||||||
|
| Task not found for callback | Log error, check TaskList |
|
||||||
|
| Spawn fails | Mark task as failed, log error, try next ready task |
|
||||||
|
| All tasks failed | Report failure, execute completion action |
|
||||||
220
.claude/skills/team-ux-improve/roles/coordinator/role.md
Normal file
220
.claude/skills/team-ux-improve/roles/coordinator/role.md
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
# Coordinator Role
|
||||||
|
|
||||||
|
## Identity
|
||||||
|
|
||||||
|
- **Name**: coordinator
|
||||||
|
- **Type**: Orchestration
|
||||||
|
- **Responsibility**: Orchestrate UX improvement pipeline, spawn workers, monitor progress, handle completion
|
||||||
|
|
||||||
|
## Boundaries
|
||||||
|
|
||||||
|
### MUST
|
||||||
|
|
||||||
|
- Parse user requirements (project path, framework)
|
||||||
|
- Create team and session structure
|
||||||
|
- Generate task chain via dispatch.md
|
||||||
|
- Spawn team-worker agents with correct role-spec paths
|
||||||
|
- Monitor worker callbacks and advance pipeline
|
||||||
|
- Execute completion action when pipeline finishes
|
||||||
|
- Handle user commands (check, resume)
|
||||||
|
|
||||||
|
### MUST NOT
|
||||||
|
|
||||||
|
- Execute worker domain logic directly
|
||||||
|
- Skip completion action
|
||||||
|
- Spawn workers as general-purpose agents (must use team-worker)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Command Execution Protocol
|
||||||
|
|
||||||
|
When coordinator needs to execute a command (dispatch, monitor):
|
||||||
|
|
||||||
|
1. **Read the command file**: `roles/coordinator/commands/<command-name>.md`
|
||||||
|
2. **Follow the workflow** defined in the command file (Phase 2-4 structure)
|
||||||
|
3. **Commands are inline execution guides** - NOT separate agents or subprocesses
|
||||||
|
4. **Execute synchronously** - complete the command workflow before proceeding
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
Phase 3 needs task dispatch
|
||||||
|
-> Read roles/coordinator/commands/dispatch.md
|
||||||
|
-> Execute Phase 2 (Context Loading)
|
||||||
|
-> Execute Phase 3 (Task Chain Creation)
|
||||||
|
-> Execute Phase 4 (Validation)
|
||||||
|
-> Continue to Phase 4
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entry Router
|
||||||
|
|
||||||
|
When coordinator is invoked, detect invocation type:
|
||||||
|
|
||||||
|
| Detection | Condition | Handler |
|
||||||
|
|-----------|-----------|---------|
|
||||||
|
| Worker callback | Message contains `[scanner]`, `[diagnoser]`, etc. | -> handleCallback |
|
||||||
|
| Status check | Arguments contain "check" or "status" | -> handleCheck |
|
||||||
|
| Manual resume | Arguments contain "resume" or "continue" | -> handleResume |
|
||||||
|
| Interrupted session | Active/paused session exists | -> Phase 0 (Resume Check) |
|
||||||
|
| New session | None of above | -> Phase 1 (Requirement Clarification) |
|
||||||
|
|
||||||
|
For callback/check/resume: load `commands/monitor.md` and execute handler, then STOP.
|
||||||
|
|
||||||
|
### Router Implementation
|
||||||
|
|
||||||
|
1. **Load session context** (if exists):
|
||||||
|
- Scan `.workflow/.team/ux-improve-*/.msg/meta.json` for active/paused sessions
|
||||||
|
- If found, extract known worker roles from meta.json or SKILL.md Role Registry
|
||||||
|
|
||||||
|
2. **Parse $ARGUMENTS** for detection keywords
|
||||||
|
|
||||||
|
3. **Route to handler**:
|
||||||
|
- For monitor handlers: Read `commands/monitor.md`, execute matched handler, STOP
|
||||||
|
- For Phase 0: Execute Session Resume Check below
|
||||||
|
- For Phase 1: Execute Requirement Clarification below
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 0: Session Resume Check
|
||||||
|
|
||||||
|
**Trigger**: Interrupted session detected (active/paused session exists)
|
||||||
|
|
||||||
|
1. Load session meta.json
|
||||||
|
2. Audit TaskList -> reconcile session state vs task status
|
||||||
|
3. Reset in_progress tasks -> pending (interrupted tasks)
|
||||||
|
4. Check for fast-advance orphans (tasks spawned but not in TaskList)
|
||||||
|
5. AskUserQuestion: "Resume session <session-id>? [Yes/No/New]"
|
||||||
|
- Yes -> Phase 4 (coordination loop)
|
||||||
|
- No -> Archive old session -> Phase 1
|
||||||
|
- New -> Keep old session paused -> Phase 1
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1: Requirement Clarification
|
||||||
|
|
||||||
|
1. Parse $ARGUMENTS for project path and framework flag
|
||||||
|
2. If project path missing -> AskUserQuestion for path
|
||||||
|
3. If framework not specified -> detect from package.json or ask user
|
||||||
|
4. Validate project path exists
|
||||||
|
5. Store: project_path, framework (react|vue)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: Team Creation
|
||||||
|
|
||||||
|
1. Generate session ID: `ux-improve-<timestamp>`
|
||||||
|
2. Create session directory structure:
|
||||||
|
```
|
||||||
|
.workflow/.team/<session-id>/
|
||||||
|
├── .msg/
|
||||||
|
├── artifacts/
|
||||||
|
├── explorations/
|
||||||
|
└── wisdom/
|
||||||
|
```
|
||||||
|
3. TeamCreate(team_name="ux-improve")
|
||||||
|
4. Initialize meta.json with pipeline config:
|
||||||
|
```
|
||||||
|
team_msg(operation="log", session_id=<session-id>, from="coordinator",
|
||||||
|
type="state_update",
|
||||||
|
data={
|
||||||
|
pipeline_mode: "standard",
|
||||||
|
pipeline_stages: ["scan", "diagnose", "design", "implement", "test"],
|
||||||
|
project_path: <path>,
|
||||||
|
framework: <framework>
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3: Task Chain Creation
|
||||||
|
|
||||||
|
Delegate to dispatch.md:
|
||||||
|
|
||||||
|
1. Read `roles/coordinator/commands/dispatch.md`
|
||||||
|
2. Execute Phase 2 (Context Loading)
|
||||||
|
3. Execute Phase 3 (Task Chain Creation)
|
||||||
|
4. Execute Phase 4 (Validation)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4: Spawn-and-Stop Coordination
|
||||||
|
|
||||||
|
1. Find ready tasks (status=pending, no blockedBy or all blockedBy completed)
|
||||||
|
2. For each ready task:
|
||||||
|
- Extract role from task owner
|
||||||
|
- Spawn team-worker agent with role-spec path
|
||||||
|
- Use spawn template from SKILL.md
|
||||||
|
3. STOP (idle, wait for worker callbacks)
|
||||||
|
|
||||||
|
**Spawn template**:
|
||||||
|
```
|
||||||
|
Agent({
|
||||||
|
subagent_type: "team-worker",
|
||||||
|
description: "Spawn <role> worker",
|
||||||
|
team_name: "ux-improve",
|
||||||
|
name: "<role>",
|
||||||
|
run_in_background: true,
|
||||||
|
prompt: `## Role Assignment
|
||||||
|
role: <role>
|
||||||
|
role_spec: .claude/skills/team-ux-improve/role-specs/<role>.md
|
||||||
|
session: <session-folder>
|
||||||
|
session_id: <session-id>
|
||||||
|
team_name: ux-improve
|
||||||
|
requirement: <task-description>
|
||||||
|
inner_loop: <true|false>
|
||||||
|
|
||||||
|
Read role_spec file to load Phase 2-4 domain instructions.
|
||||||
|
Execute built-in Phase 1 (task discovery) -> role-spec Phase 2-4 -> built-in Phase 5 (report).`
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
**Inner loop roles**: implementer (inner_loop: true)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 5: Report + Completion Action
|
||||||
|
|
||||||
|
1. Load session state -> count completed tasks, duration
|
||||||
|
2. List deliverables with output paths:
|
||||||
|
- artifacts/scan-report.md
|
||||||
|
- artifacts/diagnosis.md
|
||||||
|
- artifacts/design-guide.md
|
||||||
|
- artifacts/fixes/
|
||||||
|
- artifacts/test-report.md
|
||||||
|
3. **Completion Action** (interactive mode):
|
||||||
|
|
||||||
|
```
|
||||||
|
AskUserQuestion({
|
||||||
|
questions: [{
|
||||||
|
question: "Team pipeline complete. What would you like to do?",
|
||||||
|
header: "Completion",
|
||||||
|
multiSelect: false,
|
||||||
|
options: [
|
||||||
|
{ label: "Archive & Clean (Recommended)", description: "Archive session, clean up tasks and team resources" },
|
||||||
|
{ label: "Keep Active", description: "Keep session active for follow-up work or inspection" },
|
||||||
|
{ label: "Export Results", description: "Export deliverables to a specified location, then clean" }
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Handle user choice:
|
||||||
|
|
||||||
|
| Choice | Steps |
|
||||||
|
|--------|-------|
|
||||||
|
| Archive & Clean | TaskList -> verify all completed -> update session status="completed" -> TeamDelete("ux-improve") -> output final summary with artifact paths |
|
||||||
|
| Keep Active | Update session status="paused" -> output: "Session paused. Resume with: Skill(skill='team-ux-improve', args='resume')" |
|
||||||
|
| Export Results | AskUserQuestion for target directory -> copy all artifacts -> Archive & Clean flow |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Scenario | Resolution |
|
||||||
|
|----------|------------|
|
||||||
|
| Project path invalid | Re-prompt user for valid path |
|
||||||
|
| Framework detection fails | AskUserQuestion for framework selection |
|
||||||
|
| Worker spawn fails | Log error, mark task as failed, continue with other tasks |
|
||||||
|
| TeamCreate fails | Error: cannot proceed without team |
|
||||||
|
| Completion action timeout (5 min) | Default to Keep Active |
|
||||||
181
.claude/skills/team-ux-improve/specs/team-config.json
Normal file
181
.claude/skills/team-ux-improve/specs/team-config.json
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
{
|
||||||
|
"version": "5.0.0",
|
||||||
|
"team_name": "ux-improve",
|
||||||
|
"team_display_name": "UX Improve",
|
||||||
|
"team_purpose": "Systematically discover and fix UI/UX interaction issues including unresponsive buttons, missing feedback, and state refresh problems",
|
||||||
|
"skill_name": "team-ux-improve",
|
||||||
|
"skill_path": ".claude/skills/team-ux-improve/",
|
||||||
|
"worker_agent": "team-worker",
|
||||||
|
"pipeline_type": "Standard",
|
||||||
|
"completion_action": "interactive",
|
||||||
|
"has_inline_discuss": false,
|
||||||
|
"has_shared_explore": true,
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"name": "coordinator",
|
||||||
|
"display_name": "Coordinator",
|
||||||
|
"type": "orchestrator",
|
||||||
|
"responsibility_type": "orchestration",
|
||||||
|
"role_spec": "roles/coordinator/role.md",
|
||||||
|
"task_prefix": null,
|
||||||
|
"inner_loop": false,
|
||||||
|
"allowed_tools": ["Agent", "AskUserQuestion", "Read", "Write", "Bash", "Glob", "Grep", "TaskList", "TaskGet", "TaskUpdate", "TaskCreate", "TeamCreate", "TeamDelete", "SendMessage", "mcp__ccw-tools__team_msg"],
|
||||||
|
"description": "Orchestrates the UX improvement pipeline, spawns workers, monitors progress"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "scanner",
|
||||||
|
"display_name": "UI Scanner",
|
||||||
|
"type": "worker",
|
||||||
|
"responsibility_type": "read_only_analysis",
|
||||||
|
"role_spec": "role-specs/scanner.md",
|
||||||
|
"task_prefix": "SCAN",
|
||||||
|
"inner_loop": false,
|
||||||
|
"allowed_tools": ["Read", "Grep", "Glob", "Bash", "mcp__ace-tool__search_context", "mcp__ccw-tools__read_file", "mcp__ccw-tools__team_msg", "TaskList", "TaskGet", "TaskUpdate", "SendMessage"],
|
||||||
|
"description": "Scans UI components to identify interaction issues (unresponsive buttons, missing feedback, state not refreshing)",
|
||||||
|
"frontmatter": {
|
||||||
|
"prefix": "SCAN",
|
||||||
|
"inner_loop": false,
|
||||||
|
"message_types": {
|
||||||
|
"success": "scan_complete",
|
||||||
|
"error": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "diagnoser",
|
||||||
|
"display_name": "State Diagnoser",
|
||||||
|
"type": "worker",
|
||||||
|
"responsibility_type": "orchestration",
|
||||||
|
"role_spec": "role-specs/diagnoser.md",
|
||||||
|
"task_prefix": "DIAG",
|
||||||
|
"inner_loop": false,
|
||||||
|
"allowed_tools": ["Read", "Grep", "Bash", "mcp__ace-tool__search_context", "mcp__ccw-tools__read_file", "mcp__ccw-tools__team_msg", "TaskList", "TaskGet", "TaskUpdate", "SendMessage"],
|
||||||
|
"description": "Diagnoses root causes of UI issues: state management problems, event binding failures, async handling errors",
|
||||||
|
"frontmatter": {
|
||||||
|
"prefix": "DIAG",
|
||||||
|
"inner_loop": false,
|
||||||
|
"message_types": {
|
||||||
|
"success": "diag_complete",
|
||||||
|
"error": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "designer",
|
||||||
|
"display_name": "UX Designer",
|
||||||
|
"type": "worker",
|
||||||
|
"responsibility_type": "orchestration",
|
||||||
|
"role_spec": "role-specs/designer.md",
|
||||||
|
"task_prefix": "DESIGN",
|
||||||
|
"inner_loop": false,
|
||||||
|
"allowed_tools": ["Read", "Write", "Bash", "mcp__ccw-tools__read_file", "mcp__ccw-tools__write_file", "mcp__ccw-tools__team_msg", "TaskList", "TaskGet", "TaskUpdate", "SendMessage"],
|
||||||
|
"description": "Designs feedback mechanisms (loading/error/success states) and state management patterns (React/Vue reactive updates)",
|
||||||
|
"frontmatter": {
|
||||||
|
"prefix": "DESIGN",
|
||||||
|
"inner_loop": false,
|
||||||
|
"message_types": {
|
||||||
|
"success": "design_complete",
|
||||||
|
"error": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "implementer",
|
||||||
|
"display_name": "Code Implementer",
|
||||||
|
"type": "worker",
|
||||||
|
"responsibility_type": "code_generation",
|
||||||
|
"role_spec": "role-specs/implementer.md",
|
||||||
|
"task_prefix": "IMPL",
|
||||||
|
"inner_loop": true,
|
||||||
|
"allowed_tools": ["Read", "Write", "Edit", "Bash", "mcp__ccw-tools__read_file", "mcp__ccw-tools__write_file", "mcp__ccw-tools__edit_file", "mcp__ccw-tools__team_msg", "TaskList", "TaskGet", "TaskUpdate", "SendMessage"],
|
||||||
|
"description": "Generates executable fix code with proper state management, event handling, and UI feedback bindings",
|
||||||
|
"frontmatter": {
|
||||||
|
"prefix": "IMPL",
|
||||||
|
"inner_loop": true,
|
||||||
|
"message_types": {
|
||||||
|
"success": "impl_complete",
|
||||||
|
"error": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tester",
|
||||||
|
"display_name": "Test Engineer",
|
||||||
|
"type": "worker",
|
||||||
|
"responsibility_type": "validation",
|
||||||
|
"role_spec": "role-specs/tester.md",
|
||||||
|
"task_prefix": "TEST",
|
||||||
|
"inner_loop": false,
|
||||||
|
"allowed_tools": ["Read", "Write", "Bash", "mcp__ccw-tools__read_file", "mcp__ccw-tools__write_file", "mcp__ccw-tools__team_msg", "TaskList", "TaskGet", "TaskUpdate", "SendMessage"],
|
||||||
|
"description": "Generates test cases to verify fixes (loading states, error handling, state updates)",
|
||||||
|
"frontmatter": {
|
||||||
|
"prefix": "TEST",
|
||||||
|
"inner_loop": false,
|
||||||
|
"message_types": {
|
||||||
|
"success": "test_complete",
|
||||||
|
"error": "error",
|
||||||
|
"fix": "fix_required"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"utility_members": [
|
||||||
|
{
|
||||||
|
"name": "explorer",
|
||||||
|
"display_name": "Codebase Explorer",
|
||||||
|
"role_spec": "role-specs/explorer.md",
|
||||||
|
"callable_by": "coordinator",
|
||||||
|
"purpose": "Explore codebase for UI component patterns, state management conventions, and framework-specific patterns",
|
||||||
|
"allowed_tools": ["Read", "Grep", "Glob", "Bash", "mcp__ace-tool__search_context", "mcp__ccw-tools__read_file", "mcp__ccw-tools__team_msg"],
|
||||||
|
"frontmatter": {
|
||||||
|
"prefix": "EXPLORE",
|
||||||
|
"inner_loop": false,
|
||||||
|
"message_types": {
|
||||||
|
"success": "explore_complete",
|
||||||
|
"error": "error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pipeline": {
|
||||||
|
"stages": [
|
||||||
|
{
|
||||||
|
"stage_id": 1,
|
||||||
|
"stage_name": "UI Scanning",
|
||||||
|
"roles": ["scanner"],
|
||||||
|
"dependencies": [],
|
||||||
|
"description": "Scan UI components for interaction issues"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage_id": 2,
|
||||||
|
"stage_name": "Root Cause Diagnosis",
|
||||||
|
"roles": ["diagnoser"],
|
||||||
|
"dependencies": ["scanner"],
|
||||||
|
"description": "Diagnose root causes of identified issues"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage_id": 3,
|
||||||
|
"stage_name": "Solution Design",
|
||||||
|
"roles": ["designer"],
|
||||||
|
"dependencies": ["diagnoser"],
|
||||||
|
"description": "Design feedback mechanisms and state management solutions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage_id": 4,
|
||||||
|
"stage_name": "Code Implementation",
|
||||||
|
"roles": ["implementer"],
|
||||||
|
"dependencies": ["designer"],
|
||||||
|
"description": "Generate fix code with proper state handling"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage_id": 5,
|
||||||
|
"stage_name": "Test Validation",
|
||||||
|
"roles": ["tester"],
|
||||||
|
"dependencies": ["implementer"],
|
||||||
|
"description": "Generate and run tests to verify fixes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"diagram": "scanner (SCAN) → diagnoser (DIAG) → designer (DESIGN) → implementer (IMPL) → tester (TEST)",
|
||||||
|
"fast_advance_eligible": ["scanner→diagnoser", "diagnoser→designer", "designer→implementer"]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
XCircle,
|
XCircle,
|
||||||
Loader2,
|
Loader2,
|
||||||
Info,
|
Info,
|
||||||
|
FolderOpen,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@@ -31,6 +32,7 @@ import { Textarea } from '@/components/ui/Textarea';
|
|||||||
import { Label } from '@/components/ui/Label';
|
import { Label } from '@/components/ui/Label';
|
||||||
import { validateSkillImport, createSkill } from '@/lib/api';
|
import { validateSkillImport, createSkill } from '@/lib/api';
|
||||||
import { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';
|
import { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore';
|
||||||
|
import { FloatingFileBrowser } from '@/components/terminal-dashboard/FloatingFileBrowser';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
export interface SkillCreateDialogProps {
|
export interface SkillCreateDialogProps {
|
||||||
@@ -58,7 +60,6 @@ export function SkillCreateDialog({ open, onOpenChange, onCreated, cliType = 'cl
|
|||||||
|
|
||||||
// Import mode state
|
// Import mode state
|
||||||
const [sourcePath, setSourcePath] = useState('');
|
const [sourcePath, setSourcePath] = useState('');
|
||||||
const [customName, setCustomName] = useState('');
|
|
||||||
const [validationResult, setValidationResult] = useState<ValidationResult | null>(null);
|
const [validationResult, setValidationResult] = useState<ValidationResult | null>(null);
|
||||||
const [isValidating, setIsValidating] = useState(false);
|
const [isValidating, setIsValidating] = useState(false);
|
||||||
|
|
||||||
@@ -68,16 +69,19 @@ export function SkillCreateDialog({ open, onOpenChange, onCreated, cliType = 'cl
|
|||||||
|
|
||||||
const [isCreating, setIsCreating] = useState(false);
|
const [isCreating, setIsCreating] = useState(false);
|
||||||
|
|
||||||
|
// File browser state
|
||||||
|
const [isFileBrowserOpen, setIsFileBrowserOpen] = useState(false);
|
||||||
|
|
||||||
const resetState = useCallback(() => {
|
const resetState = useCallback(() => {
|
||||||
setMode('import');
|
setMode('import');
|
||||||
setLocation('project');
|
setLocation('project');
|
||||||
setSourcePath('');
|
setSourcePath('');
|
||||||
setCustomName('');
|
|
||||||
setValidationResult(null);
|
setValidationResult(null);
|
||||||
setIsValidating(false);
|
setIsValidating(false);
|
||||||
setSkillName('');
|
setSkillName('');
|
||||||
setDescription('');
|
setDescription('');
|
||||||
setIsCreating(false);
|
setIsCreating(false);
|
||||||
|
setIsFileBrowserOpen(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleOpenChange = useCallback((open: boolean) => {
|
const handleOpenChange = useCallback((open: boolean) => {
|
||||||
@@ -122,7 +126,7 @@ export function SkillCreateDialog({ open, onOpenChange, onCreated, cliType = 'cl
|
|||||||
mode,
|
mode,
|
||||||
location,
|
location,
|
||||||
sourcePath: mode === 'import' ? sourcePath.trim() : undefined,
|
sourcePath: mode === 'import' ? sourcePath.trim() : undefined,
|
||||||
skillName: mode === 'import' ? (customName.trim() || undefined) : skillName.trim(),
|
skillName: mode === 'cli-generate' ? skillName.trim() : undefined,
|
||||||
description: mode === 'cli-generate' ? description.trim() : undefined,
|
description: mode === 'cli-generate' ? description.trim() : undefined,
|
||||||
generationType: mode === 'cli-generate' ? 'description' : undefined,
|
generationType: mode === 'cli-generate' ? 'description' : undefined,
|
||||||
projectPath,
|
projectPath,
|
||||||
@@ -142,7 +146,7 @@ export function SkillCreateDialog({ open, onOpenChange, onCreated, cliType = 'cl
|
|||||||
} finally {
|
} finally {
|
||||||
setIsCreating(false);
|
setIsCreating(false);
|
||||||
}
|
}
|
||||||
}, [mode, location, sourcePath, customName, skillName, description, validationResult, projectPath, handleOpenChange, onCreated, formatMessage]);
|
}, [mode, location, sourcePath, skillName, description, validationResult, projectPath, handleOpenChange, onCreated, formatMessage]);
|
||||||
|
|
||||||
const canCreate = mode === 'import'
|
const canCreate = mode === 'import'
|
||||||
? sourcePath.trim() && validationResult?.valid && !isCreating
|
? sourcePath.trim() && validationResult?.valid && !isCreating
|
||||||
@@ -250,6 +254,7 @@ export function SkillCreateDialog({ open, onOpenChange, onCreated, cliType = 'cl
|
|||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="sourcePath">{formatMessage({ id: 'skills.create.sourcePath' })}</Label>
|
<Label htmlFor="sourcePath">{formatMessage({ id: 'skills.create.sourcePath' })}</Label>
|
||||||
|
<div className="flex gap-2">
|
||||||
<Input
|
<Input
|
||||||
id="sourcePath"
|
id="sourcePath"
|
||||||
value={sourcePath}
|
value={sourcePath}
|
||||||
@@ -258,22 +263,19 @@ export function SkillCreateDialog({ open, onOpenChange, onCreated, cliType = 'cl
|
|||||||
setValidationResult(null);
|
setValidationResult(null);
|
||||||
}}
|
}}
|
||||||
placeholder={formatMessage({ id: 'skills.create.sourcePathPlaceholder' })}
|
placeholder={formatMessage({ id: 'skills.create.sourcePathPlaceholder' })}
|
||||||
className="font-mono text-sm"
|
className="font-mono text-sm flex-1"
|
||||||
/>
|
/>
|
||||||
<p className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.sourcePathHint' })}</p>
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => setIsFileBrowserOpen(true)}
|
||||||
|
title={formatMessage({ id: 'skills.create.browseFolder' })}
|
||||||
|
>
|
||||||
|
<FolderOpen className="w-4 h-4" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
<p className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.sourcePathHint' })}</p>
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="customName">
|
|
||||||
{formatMessage({ id: 'skills.create.customName' })}
|
|
||||||
<span className="text-muted-foreground ml-1">({formatMessage({ id: 'skills.create.customNameHint' })})</span>
|
|
||||||
</Label>
|
|
||||||
<Input
|
|
||||||
id="customName"
|
|
||||||
value={customName}
|
|
||||||
onChange={(e) => setCustomName(e.target.value)}
|
|
||||||
placeholder={formatMessage({ id: 'skills.create.customNamePlaceholder' })}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Validation Result */}
|
{/* Validation Result */}
|
||||||
@@ -401,6 +403,19 @@ export function SkillCreateDialog({ open, onOpenChange, onCreated, cliType = 'cl
|
|||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
||||||
|
{/* File Browser for selecting source folder */}
|
||||||
|
<FloatingFileBrowser
|
||||||
|
isOpen={isFileBrowserOpen}
|
||||||
|
onClose={() => setIsFileBrowserOpen(false)}
|
||||||
|
rootPath={projectPath}
|
||||||
|
onInsertPath={(path) => {
|
||||||
|
setSourcePath(path);
|
||||||
|
setValidationResult(null);
|
||||||
|
setIsFileBrowserOpen(false);
|
||||||
|
}}
|
||||||
|
initialSelectedPath={sourcePath || null}
|
||||||
|
/>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1340,11 +1340,30 @@ async function executeCliTool(
|
|||||||
export const schema: ToolSchema = {
|
export const schema: ToolSchema = {
|
||||||
name: 'cli_executor',
|
name: 'cli_executor',
|
||||||
description: `Execute external CLI tools (gemini/qwen/codex) with unified interface.
|
description: `Execute external CLI tools (gemini/qwen/codex) with unified interface.
|
||||||
Modes:
|
|
||||||
- analysis: Read-only operations (default)
|
**Required Parameters:**
|
||||||
- write: File modifications allowed
|
**tool** (string): CLI tool to execute - "gemini" | "qwen" | "codex".
|
||||||
- auto: Full autonomous operations (codex only)
|
**prompt** (string): Prompt to send to the CLI tool.
|
||||||
- review: Code review mode (codex uses 'codex review' subcommand, others accept but no operation change)`,
|
|
||||||
|
**Optional Parameters:**
|
||||||
|
*mode* (string): Execution mode (default: "analysis").
|
||||||
|
- "analysis": Read-only operations, no file modifications.
|
||||||
|
- "write": File modifications allowed.
|
||||||
|
- "auto": Full autonomous operations (codex only).
|
||||||
|
- "review": Code review mode (codex uses 'codex review' subcommand).
|
||||||
|
*model* (string): Model override (tool-specific, e.g., "gemini-2.5-pro").
|
||||||
|
*cd* (string): Working directory for execution.
|
||||||
|
*includeDirs* (string): Additional directories (comma-separated).
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
cli_executor(tool="gemini", prompt="Analyze the auth module")
|
||||||
|
cli_executor(tool="gemini", prompt="Fix the bug", mode="write")
|
||||||
|
cli_executor(tool="codex", prompt="Review changes", mode="review")
|
||||||
|
cli_executor(tool="qwen", prompt="Implement feature", mode="write", cd="src/auth")
|
||||||
|
|
||||||
|
**Mode-Tool Compatibility:**
|
||||||
|
- gemini/qwen: analysis, write
|
||||||
|
- codex: analysis, write, auto, review`,
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
@@ -588,27 +588,60 @@ async function execute(params: Params): Promise<OperationResult> {
|
|||||||
// Tool schema for MCP
|
// Tool schema for MCP
|
||||||
export const schema: ToolSchema = {
|
export const schema: ToolSchema = {
|
||||||
name: 'core_memory',
|
name: 'core_memory',
|
||||||
description: `Core memory management for strategic context.
|
description: `Core memory management for strategic context. Choose an operation and provide its required parameters.
|
||||||
|
|
||||||
Usage:
|
**Operations & Required Parameters:**
|
||||||
core_memory(operation="list") # List all memories
|
|
||||||
core_memory(operation="list", tags=["auth","api"]) # List memories with specific tags
|
|
||||||
core_memory(operation="import", text="important context") # Import text as new memory
|
|
||||||
core_memory(operation="export", id="CMEM-xxx") # Export memory as plain text
|
|
||||||
core_memory(operation="summary", id="CMEM-xxx") # Generate AI summary
|
|
||||||
core_memory(operation="embed", source_id="CMEM-xxx") # Generate embeddings for memory
|
|
||||||
core_memory(operation="search", query="authentication") # Search memories semantically
|
|
||||||
core_memory(operation="embed_status") # Check embedding status
|
|
||||||
core_memory(operation="extract") # Trigger batch memory extraction (V2)
|
|
||||||
core_memory(operation="extract_status") # Check extraction pipeline status
|
|
||||||
core_memory(operation="consolidate") # Trigger memory consolidation (V2)
|
|
||||||
core_memory(operation="consolidate_status") # Check consolidation status
|
|
||||||
core_memory(operation="jobs") # List all V2 pipeline jobs
|
|
||||||
|
|
||||||
Path parameter (highest priority):
|
* **list**: List all memories.
|
||||||
core_memory(operation="list", path="/path/to/project") # Use specific project path
|
* *limit* (number): Max results (default: 100).
|
||||||
|
* *tags* (array): Filter by tags (AND logic).
|
||||||
|
* *path* (string): Project path (overrides auto-detection).
|
||||||
|
|
||||||
Memory IDs use format: CMEM-YYYYMMDD-HHMMSS`,
|
* **import**: Import text as new memory.
|
||||||
|
* **text** (string, **REQUIRED**): Content to import.
|
||||||
|
* *path* (string): Project path.
|
||||||
|
|
||||||
|
* **export**: Export memory as plain text.
|
||||||
|
* **id** (string, **REQUIRED**): Memory ID (e.g., CMEM-20260305-120000).
|
||||||
|
* *path* (string): Project path.
|
||||||
|
|
||||||
|
* **summary**: Generate AI summary for a memory.
|
||||||
|
* **id** (string, **REQUIRED**): Memory ID.
|
||||||
|
* *tool* (string): AI tool for summary ("gemini" or "qwen", default: "gemini").
|
||||||
|
* *path* (string): Project path.
|
||||||
|
|
||||||
|
* **search**: Search memories semantically.
|
||||||
|
* **query** (string, **REQUIRED**): Search query.
|
||||||
|
* *top_k* (number): Max results (default: 10).
|
||||||
|
* *min_score* (number): Min similarity score (default: 0.3).
|
||||||
|
* *source_type* (string): Filter by type ("core_memory" | "workflow" | "cli_history").
|
||||||
|
* *path* (string): Project path.
|
||||||
|
|
||||||
|
* **embed**: Generate embeddings for memory chunks.
|
||||||
|
* *source_id* (string): Specific memory to embed (optional, embeds all if omitted).
|
||||||
|
* *batch_size* (number): Batch size (default: 8).
|
||||||
|
* *force* (boolean): Force re-embedding (default: false).
|
||||||
|
* *path* (string): Project path.
|
||||||
|
|
||||||
|
* **embed_status**: Check embedding status. (No required params)
|
||||||
|
|
||||||
|
* **extract**: Trigger batch memory extraction (V2, fire-and-forget).
|
||||||
|
* *max_sessions* (number): Max sessions to process.
|
||||||
|
* *path* (string): Project path.
|
||||||
|
|
||||||
|
* **extract_status**: Check extraction pipeline status. (No required params)
|
||||||
|
|
||||||
|
* **consolidate**: Trigger memory consolidation (V2, fire-and-forget).
|
||||||
|
* *path* (string): Project path.
|
||||||
|
|
||||||
|
* **consolidate_status**: Check consolidation status. (No required params)
|
||||||
|
|
||||||
|
* **jobs**: List all V2 pipeline jobs.
|
||||||
|
* *kind* (string): Filter by job kind (e.g., "extraction", "consolidation").
|
||||||
|
* *status_filter* (string): Filter by status ("pending" | "running" | "done" | "error").
|
||||||
|
* *path* (string): Project path.
|
||||||
|
|
||||||
|
**Memory ID Format:** CMEM-YYYYMMDD-HHMMSS (e.g., CMEM-20260305-143022)`,
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
@@ -454,32 +454,37 @@ function executeLineMode(content: string, params: LineModeParams): LineModeResul
|
|||||||
// Tool schema for MCP
|
// Tool schema for MCP
|
||||||
export const schema: ToolSchema = {
|
export const schema: ToolSchema = {
|
||||||
name: 'edit_file',
|
name: 'edit_file',
|
||||||
description: `Edit file using two modes: "update" for text replacement (default) and "line" for line-based operations.
|
description: `Edit file using ONE of two modes. Provide parameters for only ONE mode - mixing modes causes validation error.
|
||||||
|
|
||||||
**Update Mode** (default):
|
**Mode 1: update** (default) - Text replacement
|
||||||
- Use oldText/newText for single replacement OR edits for multiple replacements
|
**path** (string, **REQUIRED**): File path to edit.
|
||||||
- Parameters: oldText, newText, replaceAll, dryRun
|
**oldText** (string, **REQUIRED** if not using edits): Text to find and replace.
|
||||||
- Cannot use line mode parameters (operation, line, end_line, text)
|
**newText** (string, **REQUIRED** if using oldText): Replacement text.
|
||||||
- Validation: oldText/newText and edits are mutually exclusive
|
* OR use **edits** (array) for multiple replacements: [{oldText:"a", newText:"b"}, ...]
|
||||||
|
*replaceAll* (boolean): Replace all occurrences (default: false).
|
||||||
|
*dryRun* (boolean): Preview diff without modifying (default: false).
|
||||||
|
|
||||||
**Line Mode**:
|
Example:
|
||||||
- Use for precise line-based operations
|
edit_file(path="file.ts", oldText="old", newText="new")
|
||||||
- Parameters: operation (insert_before/insert_after/replace/delete), line, end_line, text, dryRun
|
edit_file(path="file.ts", edits=[{oldText:"a", newText:"b"}])
|
||||||
- Cannot use update mode parameters (oldText, newText, edits, replaceAll)
|
edit_file(path="file.ts", oldText="x", newText="y", replaceAll=true)
|
||||||
|
|
||||||
Usage (update mode - single replacement):
|
**Mode 2: line** - Line-based operations
|
||||||
edit_file(path="f.js", oldText="old", newText="new")
|
**path** (string, **REQUIRED**): File path to edit.
|
||||||
|
**operation** (string, **REQUIRED**): "insert_before" | "insert_after" | "replace" | "delete".
|
||||||
|
**line** (number, **REQUIRED**): 1-based line number.
|
||||||
|
*text* (string): Content for insert/replace operations.
|
||||||
|
*end_line* (number): End line for range operations (replace/delete).
|
||||||
|
*dryRun* (boolean): Preview diff without modifying (default: false).
|
||||||
|
|
||||||
Usage (update mode - multiple replacements):
|
Example:
|
||||||
edit_file(path="f.js", edits=[{oldText:"a",newText:"b"},{oldText:"c",newText:"d"}])
|
edit_file(path="file.ts", mode="line", operation="insert_after", line=10, text="new line")
|
||||||
|
edit_file(path="file.ts", mode="line", operation="delete", line=5, end_line=8)
|
||||||
|
|
||||||
Usage (line mode):
|
**⚠️ MUTUAL EXCLUSIVITY:**
|
||||||
edit_file(path="f.js", mode="line", operation="insert_after", line=10, text="new line")
|
- update mode: Use ONLY oldText/newText OR edits, plus replaceAll, dryRun
|
||||||
edit_file(path="f.js", mode="line", operation="delete", line=5, end_line=8)
|
- line mode: Use ONLY operation, line, end_line, text, dryRun
|
||||||
|
- DO NOT mix parameters from both modes`,
|
||||||
Options: dryRun=true (preview diff), replaceAll=true (update mode only)
|
|
||||||
|
|
||||||
**Important**: Each mode only accepts its own parameters. Providing parameters from both modes will cause a validation error.`,
|
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
@@ -1022,15 +1022,51 @@ async function execute(params: Params): Promise<any> {
|
|||||||
|
|
||||||
export const schema: ToolSchema = {
|
export const schema: ToolSchema = {
|
||||||
name: 'session_manager',
|
name: 'session_manager',
|
||||||
description: `Workflow session management.
|
description: `Workflow session management. Choose an operation and provide its required parameters.
|
||||||
|
|
||||||
Usage:
|
**Operations & Required Parameters:**
|
||||||
session_manager(operation="init", type="workflow", description="...")
|
|
||||||
session_manager(operation="list", location="active|archived|both")
|
* **init**: Initialize a new workflow session.
|
||||||
session_manager(operation="read", sessionId="WFS-xxx", contentType="plan|task|summary")
|
* **metadata** (object, **REQUIRED**): Session metadata with project, type, description.
|
||||||
session_manager(operation="write", sessionId="WFS-xxx", contentType="plan", content={...})
|
* Returns: New session ID.
|
||||||
session_manager(operation="archive", sessionId="WFS-xxx")
|
|
||||||
session_manager(operation="stats", sessionId="WFS-xxx")`,
|
* **list**: List workflow sessions.
|
||||||
|
* *location* (string): Filter by "active" | "archived" | "both" (default: "both").
|
||||||
|
* *include_metadata* (boolean): Include session metadata (default: false).
|
||||||
|
|
||||||
|
* **read**: Read content from a session file.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID (e.g., WFS-my-session).
|
||||||
|
* **content_type** (string, **REQUIRED**): Type to read - "plan" | "task" | "summary" | "session" | "process" | "chat" | "brainstorm" | "review-dim" | "review-iter" | "review-fix" | "todo" | "context".
|
||||||
|
* *path_params* (object): Dynamic path parameters (task_id, filename, dimension, iteration).
|
||||||
|
|
||||||
|
* **write**: Write content to a session file.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
* **content_type** (string, **REQUIRED**): Type to write (see read operation).
|
||||||
|
* **content** (object, **REQUIRED**): Content to write (object for JSON, string for text).
|
||||||
|
* *path_params* (object): Dynamic path parameters.
|
||||||
|
|
||||||
|
* **update**: Update existing content.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
* **content_type** (string, **REQUIRED**): Type to update.
|
||||||
|
* **content** (object, **REQUIRED**): Updated content.
|
||||||
|
* *path_params* (object): Dynamic path parameters.
|
||||||
|
|
||||||
|
* **archive**: Archive a completed session.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
* *update_status* (boolean): Mark status as completed (default: true).
|
||||||
|
|
||||||
|
* **mkdir**: Create session directories.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
* **dirs** (array, **REQUIRED**): Directory paths to create.
|
||||||
|
|
||||||
|
* **delete**: Delete a file within a session.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
* **file_path** (string, **REQUIRED**): Relative file path to delete.
|
||||||
|
|
||||||
|
* **stats**: Get session statistics.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
|
||||||
|
**Session ID Format:** WFS-{name}-{date} (e.g., WFS-my-project-2026-03-05)`,
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
@@ -2032,38 +2032,46 @@ async function executePriorityFallbackMode(params: Params): Promise<SearchResult
|
|||||||
// Tool schema for MCP
|
// Tool schema for MCP
|
||||||
export const schema: ToolSchema = {
|
export const schema: ToolSchema = {
|
||||||
name: 'smart_search',
|
name: 'smart_search',
|
||||||
description: `Unified code search tool with content search, file discovery, and semantic search capabilities.
|
description: `Unified code search tool. Choose an action and provide its required parameters.
|
||||||
|
|
||||||
**Actions:**
|
**Actions & Required Parameters:**
|
||||||
- search: Search file content (default)
|
|
||||||
- find_files: Find files by path/name pattern (glob matching)
|
|
||||||
- init: Create FTS index (incremental - skips existing)
|
|
||||||
- init_force: Force full rebuild (delete and recreate index)
|
|
||||||
- status: Check index status
|
|
||||||
- update: Incremental index update (for changed files)
|
|
||||||
- watch: Start file watcher for automatic updates
|
|
||||||
|
|
||||||
**Content Search (action="search"):**
|
* **search** (default): Search file content.
|
||||||
smart_search(query="authentication logic") # fuzzy mode (default) - FTS + ripgrep fusion
|
* **query** (string, **REQUIRED**): Content to search for.
|
||||||
smart_search(query="MyClass", mode="fuzzy") # fuzzy mode - fast hybrid search
|
* *mode* (string): 'fuzzy' (default, FTS+ripgrep) or 'semantic' (dense+reranker).
|
||||||
smart_search(query="how to auth", mode="semantic") # semantic mode - dense + reranker
|
* *limit* (number): Max results (default: 20).
|
||||||
|
* *path* (string): Directory to search (default: current).
|
||||||
|
* *contextLines* (number): Context lines around matches (default: 0).
|
||||||
|
* *regex* (boolean): Use regex matching (default: true).
|
||||||
|
* *caseSensitive* (boolean): Case-sensitive search (default: true).
|
||||||
|
|
||||||
**File Discovery (action="find_files"):**
|
* **find_files**: Find files by path/name pattern.
|
||||||
smart_search(action="find_files", pattern="*.ts") # find all TypeScript files
|
* **pattern** (string, **REQUIRED**): Glob pattern (e.g., "*.ts", "src/**/*.js").
|
||||||
smart_search(action="find_files", pattern="src/**/*.js") # recursive glob pattern
|
* *limit* (number): Max results (default: 20).
|
||||||
smart_search(action="find_files", pattern="test_*.py") # find test files
|
* *offset* (number): Pagination offset (default: 0).
|
||||||
smart_search(action="find_files", pattern="*.tsx", offset=20, limit=10) # pagination
|
* *includeHidden* (boolean): Include hidden files (default: false).
|
||||||
|
|
||||||
**Index Maintenance:**
|
* **init**: Create FTS index (incremental, skips existing).
|
||||||
smart_search(action="update", path="/project") # incremental index update
|
* *path* (string): Directory to index (default: current).
|
||||||
smart_search(action="watch", path="/project") # start file watcher
|
* *languages* (array): Languages to index (e.g., ["javascript", "typescript"]).
|
||||||
smart_search(action="watch", debounce=2000) # custom debounce interval
|
|
||||||
|
|
||||||
**Pagination:** All actions support offset/limit for paginated results:
|
* **init_force**: Force full rebuild (delete and recreate index).
|
||||||
smart_search(query="auth", limit=10, offset=0) # first page
|
* *path* (string): Directory to index (default: current).
|
||||||
smart_search(query="auth", limit=10, offset=10) # second page
|
|
||||||
|
|
||||||
**Modes:** fuzzy (FTS + ripgrep fusion, default), semantic (dense + reranker)`,
|
* **status**: Check index status. (No required params)
|
||||||
|
|
||||||
|
* **update**: Incremental index update.
|
||||||
|
* *path* (string): Directory to update (default: current).
|
||||||
|
|
||||||
|
* **watch**: Start file watcher for auto-updates.
|
||||||
|
* *path* (string): Directory to watch (default: current).
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
smart_search(query="authentication logic") # Content search (default action)
|
||||||
|
smart_search(query="MyClass", mode="semantic") # Semantic search
|
||||||
|
smart_search(action="find_files", pattern="*.ts") # Find TypeScript files
|
||||||
|
smart_search(action="init", path="/project") # Initialize index
|
||||||
|
smart_search(query="auth", limit=10, offset=0) # Paginated search`,
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
@@ -234,27 +234,55 @@ function resolveTeamId(params: Params): string | null {
|
|||||||
|
|
||||||
export const schema: ToolSchema = {
|
export const schema: ToolSchema = {
|
||||||
name: 'team_msg',
|
name: 'team_msg',
|
||||||
description: `Team message bus - persistent JSONL log for Agent Team communication.
|
description: `Team message bus - persistent JSONL log for Agent Team communication. Choose an operation and provide its required parameters.
|
||||||
|
|
||||||
Directory Structure (NEW):
|
**Storage Location:** .workflow/.team/{session-id}/.msg/messages.jsonl
|
||||||
.workflow/.team/{session-id}/.msg/messages.jsonl
|
|
||||||
|
|
||||||
Directory Structure (LEGACY):
|
**Operations & Required Parameters:**
|
||||||
.workflow/.team-msg/{team-name}/messages.jsonl
|
|
||||||
|
|
||||||
Operations:
|
* **log**: Append a message to the log.
|
||||||
team_msg(operation="log", session_id="TLS-xxx", from="planner", type="plan_ready", data={ref: "plan.json"})
|
* **session_id** (string, **REQUIRED**): Session ID (e.g., TLS-my-project-2026-02-27).
|
||||||
team_msg(operation="log", session_id="TLS-xxx", from="coordinator", type="state_update", data={pipeline_mode: "full"})
|
* **from** (string, **REQUIRED**): Sender role name (e.g., "planner", "coordinator").
|
||||||
team_msg(operation="broadcast", session_id="TLS-xxx", from="coordinator", type="shutdown")
|
* *to* (string): Recipient role (default: "coordinator").
|
||||||
team_msg(operation="get_state", session_id="TLS-xxx", role="researcher")
|
* *type* (string): Message type (default: "message").
|
||||||
team_msg(operation="read", session_id="TLS-xxx", id="MSG-003")
|
* *summary* (string): One-line summary (auto-generated if omitted).
|
||||||
team_msg(operation="list", session_id="TLS-xxx", from="tester", last=5)
|
* *data* (object): Structured data payload. Use data.ref for file paths.
|
||||||
team_msg(operation="status", session_id="TLS-xxx")
|
|
||||||
team_msg(operation="delete", session_id="TLS-xxx", id="MSG-003")
|
|
||||||
team_msg(operation="clear", session_id="TLS-xxx")
|
|
||||||
|
|
||||||
Defaults: to="coordinator", summary=auto-generated if omitted, type="message"
|
* **broadcast**: Send message to all team members.
|
||||||
Message types: plan_ready, plan_approved, plan_revision, task_unblocked, impl_complete, impl_progress, test_result, review_result, fix_required, error, shutdown, state_update`,
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
* **from** (string, **REQUIRED**): Sender role name.
|
||||||
|
* *type* (string): Message type (e.g., "shutdown").
|
||||||
|
* *summary* (string): One-line summary.
|
||||||
|
* *data* (object): Structured data payload.
|
||||||
|
|
||||||
|
* **read**: Read a specific message by ID.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
* **id** (string, **REQUIRED**): Message ID (e.g., "MSG-003").
|
||||||
|
|
||||||
|
* **list**: List recent messages.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
* *last* (number): Number of messages to show (default: 20, max: 100).
|
||||||
|
* *from* (string): Filter by sender role.
|
||||||
|
* *to* (string): Filter by recipient role.
|
||||||
|
* *type* (string): Filter by message type.
|
||||||
|
|
||||||
|
* **status**: Summarize team member activity.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
|
||||||
|
* **get_state**: Get state for a specific role.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
* *role* (string): Role name to query (omit for all roles).
|
||||||
|
|
||||||
|
* **delete**: Delete a message by ID.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
* **id** (string, **REQUIRED**): Message ID to delete.
|
||||||
|
|
||||||
|
* **clear**: Clear all messages for a session.
|
||||||
|
* **session_id** (string, **REQUIRED**): Session ID.
|
||||||
|
|
||||||
|
**Common Message Types:** plan_ready, plan_approved, plan_revision, task_unblocked, impl_complete, impl_progress, test_result, review_result, fix_required, error, shutdown, state_update
|
||||||
|
|
||||||
|
**Session ID Format:** TLS-{name}-{date} (e.g., TLS-my-project-2026-02-27)`,
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
Reference in New Issue
Block a user