256 lines
10 KiB
Markdown
256 lines
10 KiB
Markdown
---
|
|
phase: 03-orchestration
|
|
plan: 03
|
|
type: execute
|
|
wave: 3
|
|
depends_on: [03-01, 03-02]
|
|
files_modified:
|
|
- src/gsd_openclaw/orchestrator.py
|
|
- src/gsd_openclaw/__init__.py
|
|
- skill/SKILL.md
|
|
- tests/test_orchestrator.py
|
|
autonomous: true
|
|
requirements: [BRDG-01, OCLW-03, OCLW-05, OCLW-06]
|
|
|
|
must_haves:
|
|
truths:
|
|
- "User can send /gsd:* command through chat and receive output"
|
|
- "Session is auto-created if it doesn't exist"
|
|
- "Error messages are formatted as red cards when commands fail"
|
|
- "Approval requests trigger interactive card with buttons"
|
|
- "Orchestrator routes commands through appropriate handlers"
|
|
artifacts:
|
|
- path: "src/gsd_openclaw/orchestrator.py"
|
|
provides: "Main command router and OpenClaw skill handler"
|
|
exports: ["Orchestrator", "handle_message", "handle_callback"]
|
|
- path: "skill/SKILL.md"
|
|
provides: "OpenClaw skill definition with orchestrator reference"
|
|
contains: "orchestrator.py"
|
|
- path: "tests/test_orchestrator.py"
|
|
provides: "Test coverage for orchestration"
|
|
min_lines: 200
|
|
key_links:
|
|
- from: "Orchestrator.handle_message"
|
|
to: "TmuxSessionManager"
|
|
via: "get_session()/create_session()"
|
|
pattern: "tmux_manager\\.(get|create)_session"
|
|
- from: "Orchestrator.handle_message"
|
|
to: "CommandExecutor"
|
|
via: "execute(session, command)"
|
|
pattern: "executor\\.execute"
|
|
- from: "Orchestrator.handle_message"
|
|
to: "ApprovalHandler"
|
|
via: "detect_approval_request()"
|
|
pattern: "approval_handler\\.detect"
|
|
- from: "Orchestrator.handle_message"
|
|
to: "FeishuResponseFormatter"
|
|
via: "format_success()/format_error()"
|
|
pattern: "formatter\\.format_(success|error)"
|
|
---
|
|
|
|
<objective>
|
|
Implement the main orchestrator that integrates all components into a cohesive command routing system for OpenClaw skill invocation.
|
|
|
|
Purpose: Create the central command router that receives chat messages, routes them through session management and command execution, handles approvals and progress, and returns formatted responses.
|
|
Output: Orchestrator class with handle_message() entry point, SKILL.md update with orchestrator reference.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@/home/starmen1265/.claude/get-shit-done/workflows/execute-plan.md
|
|
@/home/starmen1265/.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/ROADMAP.md
|
|
@.planning/STATE.md
|
|
@.planning/phases/03-orchestration/03-CONTEXT.md
|
|
@.planning/phases/03-orchestration/03-RESEARCH.md
|
|
@.planning/phases/03-orchestration/03-01-PLAN.md
|
|
@.planning/phases/03-orchestration/03-02-PLAN.md
|
|
|
|
<interfaces>
|
|
<!-- Key types and contracts from Waves 1 and 2 -->
|
|
|
|
From src/gsd_openclaw/command_executor.py (Wave 1):
|
|
```python
|
|
@dataclass
|
|
class CommandResult:
|
|
output: str
|
|
completed: bool
|
|
has_error: bool
|
|
error_type: Optional[str]
|
|
|
|
class CommandExecutor:
|
|
DEFAULT_TIMEOUT: float = 60.0
|
|
def execute(self, session: TmuxSession, command: str, timeout: float = None) -> CommandResult: ...
|
|
```
|
|
|
|
From src/gsd_openclaw/approval_handler.py (Wave 2):
|
|
```python
|
|
@dataclass
|
|
class ApprovalState:
|
|
approval_id: str
|
|
session_id: str
|
|
project_name: str
|
|
context: dict
|
|
created_at: float
|
|
|
|
class ApprovalHandler:
|
|
def detect_approval_request(self, output: str) -> Optional[dict]: ...
|
|
def create_approval_card(self, context: dict, session_id: str, project_name: str) -> dict: ...
|
|
def handle_callback(self, callback_data: dict) -> str: ...
|
|
```
|
|
|
|
From src/gsd_openclaw/progress_monitor.py (Wave 2):
|
|
```python
|
|
@dataclass
|
|
class ProgressInfo:
|
|
type: str # percentage, fraction, phase, completion
|
|
value: Optional[int] = None
|
|
current: Optional[int] = None
|
|
total: Optional[int] = None
|
|
|
|
class ProgressMonitor:
|
|
def extract_progress(self, output: str) -> Optional[ProgressInfo]: ...
|
|
def should_send_update(self) -> bool: ...
|
|
def create_progress_card(self, progress: ProgressInfo, message: str) -> dict: ...
|
|
```
|
|
|
|
From src/gsd_openclaw/tmux_session.py:
|
|
```python
|
|
class TmuxSessionManager:
|
|
def get_session(self, project_name: str) -> Optional[TmuxSession]: ...
|
|
def create_session(self, project_name: str, ...) -> TmuxSession: ...
|
|
```
|
|
|
|
From src/gsd_openclaw/response_formatter.py:
|
|
```python
|
|
class FeishuResponseFormatter:
|
|
def format_success(self, title: str, content: str, buttons=None) -> dict: ...
|
|
def format_error(self, title: str, content: str, buttons=None) -> dict: ...
|
|
def format_info(self, title: str, content: str, buttons=None) -> dict: ...
|
|
```
|
|
</interfaces>
|
|
</context>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto" tdd="true">
|
|
<name>Task 1: Create test scaffold for orchestrator</name>
|
|
<files>tests/test_orchestrator.py</files>
|
|
<behavior>
|
|
- Test 1: handle_message routes to session creation when no session exists
|
|
- Test 2: handle_message executes command and returns success card
|
|
- Test 3: handle_message returns error card when command fails
|
|
- Test 4: handle_message returns approval card when approval detected
|
|
- Test 5: handle_callback routes approval response correctly
|
|
- Test 6: Command parsing extracts /gsd:* pattern
|
|
</behavior>
|
|
<action>Create test file with pytest test functions. Mock all dependencies (TmuxSessionManager, CommandExecutor, ApprovalHandler, ProgressMonitor). Follow mock patterns from tests/test_tmux_session.py.</action>
|
|
<verify>
|
|
<automated>pytest tests/test_orchestrator.py -v --collect-only 2>&1 | grep -c "test_" | xargs -I{} bash -c 'test {} -ge 6'</automated>
|
|
</verify>
|
|
<done>Test file exists with at least 6 test functions, all discoverable by pytest</done>
|
|
</task>
|
|
|
|
<task type="auto" tdd="true">
|
|
<name>Task 2: Implement Orchestrator class</name>
|
|
<files>src/gsd_openclaw/orchestrator.py, tests/test_orchestrator.py</files>
|
|
<behavior>
|
|
- Test 1: Orchestrator initializes with all required components
|
|
- Test 2: handle_message creates session if not exists (auto-create per CONTEXT.md)
|
|
- Test 3: handle_message executes command via CommandExecutor
|
|
- Test 4: handle_message returns format_success() for successful commands
|
|
- Test 5: handle_message returns format_error() for failed commands
|
|
- Test 6: handle_message returns approval card when approval detected
|
|
- Test 7: handle_message truncates output to 2000 chars for card limits
|
|
- Test 8: handle_callback processes approval/reject actions
|
|
</behavior>
|
|
<action>
|
|
Implement Orchestrator class with:
|
|
1. __init__(self, tmux_manager=None, formatter=None) - inject dependencies for testing
|
|
2. Command routing via regex: r'^/gsd:(\S+)\s*(.*)$' extracts command and args
|
|
3. handle_message(user_id, message, channel, context) -> dict
|
|
- Extract project_name from context.get('project', 'default')
|
|
- Get or create session via TmuxSessionManager
|
|
- Execute command via CommandExecutor.execute()
|
|
- Check for approval request via ApprovalHandler.detect_approval_request()
|
|
- Return appropriate card (success/error/approval)
|
|
4. handle_callback(callback_data) -> dict
|
|
- Route to ApprovalHandler.handle_callback()
|
|
- Send approval/rejection to tmux session
|
|
- Return confirmation card
|
|
5. Error handling with try/except, return format_error() on exceptions
|
|
6. Use format_error(title="命令执行失败", content=output[-2000:]) for errors
|
|
</action>
|
|
<verify>
|
|
<automated>pytest tests/test_orchestrator.py -v</automated>
|
|
</verify>
|
|
<done>Orchestrator class implemented with handle_message() and handle_callback(), 8+ tests pass</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 3: Update SKILL.md and __init__.py exports</name>
|
|
<files>skill/SKILL.md, src/gsd_openclaw/__init__.py</files>
|
|
<action>
|
|
1. Update skill/SKILL.md to add orchestrator integration notes:
|
|
- Add section "## How It Works" explaining orchestrator.py entry point
|
|
- Document that the skill calls orchestrator.handle_message() for each message
|
|
- Keep existing command documentation
|
|
2. Update src/gsd_openclaw/__init__.py to export:
|
|
- from gsd_openclaw.orchestrator import Orchestrator
|
|
- from gsd_openclaw.command_executor import CommandExecutor, CommandResult
|
|
- from gsd_openclaw.approval_handler import ApprovalHandler, ApprovalState
|
|
- from gsd_openclaw.progress_monitor import ProgressMonitor, ProgressInfo
|
|
- Add to __all__ list
|
|
</action>
|
|
<verify>
|
|
<automated>python -c "from gsd_openclaw import Orchestrator, CommandExecutor, ApprovalHandler, ProgressMonitor; print('OK')"</automated>
|
|
</verify>
|
|
<done>SKILL.md updated with orchestrator documentation, __init__.py exports all new classes</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 4: Integration test with all components</name>
|
|
<files>tests/test_orchestrator.py</files>
|
|
<action>
|
|
Add integration-style tests to test_orchestrator.py:
|
|
1. Test full flow: handle_message -> session creation -> command execution -> success card
|
|
2. Test error flow: handle_message -> command fails -> error card
|
|
3. Test approval flow: handle_message -> approval detected -> approval card
|
|
4. Test callback flow: handle_callback -> approval processed -> confirmation
|
|
|
|
Use real component instances where possible, mock only tmux server.
|
|
Ensure all tests pass with full coverage of integration paths.
|
|
</action>
|
|
<verify>
|
|
<automated>pytest tests/test_orchestrator.py -v --cov=src/gsd_openclaw/orchestrator</automated>
|
|
</verify>
|
|
<done>Integration tests added and passing, orchestrator coverage >90%</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<verification>
|
|
Run full test suite for Phase 3:
|
|
```bash
|
|
pytest tests/test_command_executor.py tests/test_approval_handler.py tests/test_progress_monitor.py tests/test_orchestrator.py -v --cov=src/gsd_openclaw
|
|
```
|
|
All tests must pass. Phase 3 coverage should be >85%.
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- Orchestrator integrates all Phase 3 components
|
|
- handle_message() provides complete command routing flow
|
|
- Auto-session-creation works per CONTEXT.md decision
|
|
- Error handling returns formatted error cards
|
|
- Approval workflow integrates with callback handling
|
|
- All exports added to __init__.py
|
|
- SKILL.md documents orchestrator integration
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/03-orchestration/03-03-SUMMARY.md`
|
|
</output>
|