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

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

View File

@@ -0,0 +1,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 |

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 |

View File

@@ -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 |

View 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 |

View 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"]
}
}

View File

@@ -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,32 +254,30 @@ 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>
<Input <div className="flex gap-2">
id="sourcePath" <Input
value={sourcePath} id="sourcePath"
onChange={(e) => { value={sourcePath}
setSourcePath(e.target.value); onChange={(e) => {
setValidationResult(null); setSourcePath(e.target.value);
}} setValidationResult(null);
placeholder={formatMessage({ id: 'skills.create.sourcePathPlaceholder' })} }}
className="font-mono text-sm" placeholder={formatMessage({ id: 'skills.create.sourcePathPlaceholder' })}
/> className="font-mono text-sm flex-1"
/>
<Button
type="button"
variant="outline"
size="icon"
onClick={() => setIsFileBrowserOpen(true)}
title={formatMessage({ id: 'skills.create.browseFolder' })}
>
<FolderOpen className="w-4 h-4" />
</Button>
</div>
<p className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.sourcePathHint' })}</p> <p className="text-xs text-muted-foreground">{formatMessage({ id: 'skills.create.sourcePathHint' })}</p>
</div> </div>
<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>
{/* Validation Result */} {/* Validation Result */}
{isValidating && ( {isValidating && (
<div className="flex items-center gap-2 p-3 bg-muted/50 rounded-lg"> <div className="flex items-center gap-2 p-3 bg-muted/50 rounded-lg">
@@ -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>
); );
} }

View File

@@ -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: {

View File

@@ -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: {

View File

@@ -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: {

View File

@@ -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: {

View File

@@ -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: {

View File

@@ -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: {