This repository has been archived on 2026-08-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
openclaw/skills/gsd-openclaw/.planning/phases/03-orchestration/03-03-PLAN.md
T

10 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
03-orchestration 03 execute 3
03-01
03-02
src/gsd_openclaw/orchestrator.py
src/gsd_openclaw/__init__.py
skill/SKILL.md
tests/test_orchestrator.py
true
BRDG-01
OCLW-03
OCLW-05
OCLW-06
truths artifacts key_links
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
path provides exports
src/gsd_openclaw/orchestrator.py Main command router and OpenClaw skill handler
Orchestrator
handle_message
handle_callback
path provides contains
skill/SKILL.md OpenClaw skill definition with orchestrator reference orchestrator.py
path provides min_lines
tests/test_orchestrator.py Test coverage for orchestration 200
from to via pattern
Orchestrator.handle_message TmuxSessionManager get_session()/create_session() tmux_manager.(get|create)_session
from to via pattern
Orchestrator.handle_message CommandExecutor execute(session, command) executor.execute
from to via pattern
Orchestrator.handle_message ApprovalHandler detect_approval_request() approval_handler.detect
from to via pattern
Orchestrator.handle_message FeishuResponseFormatter format_success()/format_error() formatter.format_(success|error)
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.

<execution_context> @/home/starmen1265/.claude/get-shit-done/workflows/execute-plan.md @/home/starmen1265/.claude/get-shit-done/templates/summary.md </execution_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

From src/gsd_openclaw/command_executor.py (Wave 1):

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

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

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

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:

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: ...
Task 1: Create test scaffold for orchestrator tests/test_orchestrator.py - 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 Create test file with pytest test functions. Mock all dependencies (TmuxSessionManager, CommandExecutor, ApprovalHandler, ProgressMonitor). Follow mock patterns from tests/test_tmux_session.py. pytest tests/test_orchestrator.py -v --collect-only 2>&1 | grep -c "test_" | xargs -I{} bash -c 'test {} -ge 6' Test file exists with at least 6 test functions, all discoverable by pytest Task 2: Implement Orchestrator class src/gsd_openclaw/orchestrator.py, tests/test_orchestrator.py - 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 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 pytest tests/test_orchestrator.py -v Orchestrator class implemented with handle_message() and handle_callback(), 8+ tests pass Task 3: Update SKILL.md and __init__.py exports skill/SKILL.md, src/gsd_openclaw/__init__.py 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 python -c "from gsd_openclaw import Orchestrator, CommandExecutor, ApprovalHandler, ProgressMonitor; print('OK')" SKILL.md updated with orchestrator documentation, __init__.py exports all new classes Task 4: Integration test with all components tests/test_orchestrator.py 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.
pytest tests/test_orchestrator.py -v --cov=src/gsd_openclaw/orchestrator Integration tests added and passing, orchestrator coverage >90% 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%.

<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>
After completion, create `.planning/phases/03-orchestration/03-03-SUMMARY.md`