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/04-gsd-integration/04-02-PLAN.md
T

251 lines
9.6 KiB
Markdown

---
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 <project> 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"
---
<objective>
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.
</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/04-gsd-integration/04-CONTEXT.md
@.planning/phases/04-gsd-integration/04-RESEARCH.md
<interfaces>
<!-- Key types and contracts from existing codebase -->
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
</interfaces>
</context>
<tasks>
<task type="auto" tdd="true">
<name>Task 1: Add UserContextManager to Orchestrator and implement /gsd:new-project handling</name>
<files>src/gsd_openclaw/orchestrator.py, tests/test_orchestrator.py</files>
<behavior>
- 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
</behavior>
<action>
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
</action>
<verify>
<automated>pytest tests/test_orchestrator.py::TestSpecialCommands::test_new_project -x -v</automated>
</verify>
<done>Orchestrator has _handle_new_project method that pre-creates session and updates user context</done>
</task>
<task type="auto" tdd="true">
<name>Task 2: Implement /gsd:use command handling with context tracking</name>
<files>src/gsd_openclaw/orchestrator.py, tests/test_orchestrator.py</files>
<behavior>
- 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
</behavior>
<action>
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
</action>
<verify>
<automated>pytest tests/test_orchestrator.py::TestSpecialCommands::test_use_project tests/test_orchestrator.py::TestSpecialCommands::test_use_nonexistent -x -v</automated>
</verify>
<done>Orchestrator has _handle_use_project method with context tracking and error handling</done>
</task>
<task type="auto" tdd="true">
<name>Task 3: Update handle_message routing to use user context for project selection</name>
<files>src/gsd_openclaw/orchestrator.py, tests/test_orchestrator.py</files>
<behavior>
- 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
</behavior>
<action>
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
</action>
<verify>
<automated>pytest tests/test_orchestrator.py -x -v</automated>
</verify>
<done>handle_message routes special commands and uses user context for project selection</done>
</task>
</tasks>
<verification>
- 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
</verification>
<success_criteria>
- 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
</success_criteria>
<output>
After completion, create `.planning/phases/04-gsd-integration/04-02-SUMMARY.md`
</output>