--- phase: 04-gsd-integration plan: 02 type: execute wave: 1 depends_on: [] files_modified: - src/gsd_openclaw/orchestrator.py - tests/test_orchestrator.py autonomous: true requirements: - BRDG-06 user_setup: [] must_haves: truths: - "User can send /gsd:new-project through chat and get a pre-created session" - "User can send /gsd:use to switch their current project context" - "User receives clear error when /gsd:use references non-existent project" - "Generic GSD commands pass through correctly" artifacts: - path: "src/gsd_openclaw/orchestrator.py" provides: "Extended Orchestrator with special command handling" exports: ["Orchestrator._handle_new_project", "Orchestrator._handle_use_project"] - path: "tests/test_orchestrator.py" provides: "Tests for special command handling" exports: ["TestSpecialCommands"] key_links: - from: "src/gsd_openclaw/orchestrator.py" to: "src/gsd_openclaw/user_context.py" via: "UserContextManager for context tracking" pattern: "UserContextManager" - from: "src/gsd_openclaw/orchestrator.py" to: "src/gsd_openclaw/tmux_session.py" via: "TmuxSessionManager.create_session for new-project" pattern: "create_session" --- Extend Orchestrator with special command handling for /gsd:new-project and /gsd:use. Purpose: Enable key GSD commands that require orchestrator-level logic: pre-creating sessions for new-project and tracking user context for use. Output: Orchestrator with _handle_new_project and _handle_use_project methods integrated into handle_message routing. @/home/starmen1265/.claude/get-shit-done/workflows/execute-plan.md @/home/starmen1265/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/04-gsd-integration/04-CONTEXT.md @.planning/phases/04-gsd-integration/04-RESEARCH.md From src/gsd_openclaw/orchestrator.py (current implementation): ```python class Orchestrator: COMMAND_PATTERN = re.compile(r'^/gsd:(\S+)\s*(.*)$') MAX_OUTPUT_LENGTH = 2000 def parse_command(self, message: str) -> Optional[Tuple[str, str]]: """Parse a message for /gsd:* command pattern.""" # Returns (command, args) or None def handle_message(self, user_id: str, message: str, channel: str, context: Dict) -> Dict: """Main entry point - currently auto-creates session for all commands.""" ``` From src/gsd_openclaw/response_formatter.py: ```python @dataclass class CardButton: """Interactive button for Feishu Card actions.""" text: str value: Dict[str, Any] button_type: str = "primary" # primary, default, danger ``` From src/gsd_openclaw/tmux_session.py: ```python class TmuxSessionManager: def create_session(self, project_name: str, ...) -> TmuxSession: """Create a new tmux session for a project.""" def get_session(self, project_name: str) -> Optional[TmuxSession]: """Get existing session without creating new one.""" ``` Special command handling requirements (from CONTEXT.md): - /gsd:new-project: Pre-create session, then pass command to tmux - /gsd:use: Track user context, show error + "Create New Project" button if not exists Task 1: Add UserContextManager to Orchestrator and implement /gsd:new-project handling src/gsd_openclaw/orchestrator.py, tests/test_orchestrator.py - Test 1: Orchestrator initializes with UserContextManager instance - Test 2: _handle_new_project creates tmux session before executing command - Test 3: _handle_new_project updates user context with new project - Test 4: _handle_new_project executes the command in the new session - Test 5: _handle_new_project returns success card with output - Test 6: handle_message routes 'new-project' command to _handle_new_project Extend Orchestrator with UserContextManager and new-project handling: 1. Add import: from gsd_openclaw.user_context import UserContextManager 2. Update Orchestrator.__init__: - Add: self.user_context_managers: Dict[str, UserContextManager] = {} - Add helper: _get_user_context_manager(user_id) -> UserContextManager 3. Add LONG_COMMANDS class attribute: ```python LONG_COMMANDS = {'execute-phase', 'plan-phase', 'discuss-phase', 'new-project'} ``` 4. Implement _handle_new_project(user_id: str, project_name: str) -> Dict: - If project_name is empty, return format_error with "Project name required" - Create session via tmux_manager.create_session(project_name) - Execute "/gsd:new-project {project_name}" in the session with timeout=None - Update user context: user_context.set_current_project(project_name) - Return formatted result (success or error based on command result) 5. Update handle_message to route 'new-project' to _handle_new_project 6. Add TestSpecialCommands class to tests/test_orchestrator.py with tests for new-project pytest tests/test_orchestrator.py::TestSpecialCommands::test_new_project -x -v Orchestrator has _handle_new_project method that pre-creates session and updates user context Task 2: Implement /gsd:use command handling with context tracking src/gsd_openclaw/orchestrator.py, tests/test_orchestrator.py - Test 1: _handle_use_project updates user context to new project - Test 2: _handle_use_project returns success card when project exists - Test 3: _handle_use_project returns error card with "Create New Project" button when project doesn't exist - Test 4: handle_message routes 'use' command to _handle_use_project - Test 5: _handle_use_project with no args returns error card - Test 6: Subsequent commands use the project from user context Implement _handle_use_project method: 1. Implement _handle_use_project(user_id: str, project_name: str) -> Dict: - If project_name is empty, return format_error with "Project name required" - Check if project session exists: tmux_manager.get_session(project_name) - If session exists: * Update user context: user_context.set_current_project(project_name) * Return format_success with "Switched to project '{project_name}'" - If session doesn't exist: * Return format_error with: - title: "Project not found" - content: "Project '{project_name}' does not exist" - buttons: [CardButton(text="Create New Project", value={"action": "new-project", "name": project_name})] 2. Update handle_message to route 'use' command to _handle_use_project 3. Add tests for _handle_use_project in TestSpecialCommands class 4. Ensure CardButton import is available from response_formatter pytest tests/test_orchestrator.py::TestSpecialCommands::test_use_project tests/test_orchestrator.py::TestSpecialCommands::test_use_nonexistent -x -v Orchestrator has _handle_use_project method with context tracking and error handling Task 3: Update handle_message routing to use user context for project selection src/gsd_openclaw/orchestrator.py, tests/test_orchestrator.py - Test 1: Generic commands use project from user context when not in context param - Test 2: Generic commands fall back to "default" project if no context - Test 3: Special commands (new-project, use) are routed correctly - Test 4: Generic pass-through works for all other commands Update handle_message routing logic: 1. Modify handle_message to get project from user context: ```python def handle_message(self, user_id, message, channel, context): # Parse command parsed = self.parse_command(message) if not parsed: return format_error(...) command, args = parsed # Special commands if command == 'new-project': return self._handle_new_project(user_id, args) if command == 'use': return self._handle_use_project(user_id, args) # Generic commands - get project from user context user_ctx = self._get_user_context_manager(user_id) project_name = user_ctx.get_current_project() if not project_name: project_name = context.get("project", "default") # Rest of existing logic... ``` 2. Ensure existing tests still pass (backward compatibility) 3. Add integration tests in TestIntegrationFlows for: - Command after /gsd:use goes to correct project - Context persists across multiple commands pytest tests/test_orchestrator.py -x -v handle_message routes special commands and uses user context for project selection - All tests in tests/test_orchestrator.py pass - /gsd:new-project pre-creates session and updates context - /gsd:use tracks context and shows error for non-existent projects - Generic commands use user context for project selection - Orchestrator has _handle_new_project and _handle_use_project methods - Special commands are routed correctly in handle_message - User context is used for project selection in generic commands - Error cards include "Create New Project" button for missing projects After completion, create `.planning/phases/04-gsd-integration/04-02-SUMMARY.md`