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-03-PLAN.md
T

268 lines
9.1 KiB
Markdown

---
phase: 04-gsd-integration
plan: 03
type: execute
wave: 2
depends_on:
- 04-01
- 04-02
files_modified:
- src/gsd_openclaw/command_executor.py
- src/gsd_openclaw/orchestrator.py
- tests/test_command_executor.py
- tests/test_orchestrator.py
autonomous: true
requirements:
- BRDG-06
user_setup: []
must_haves:
truths:
- "Long commands (execute-phase, plan-phase, discuss-phase, new-project) don't timeout"
- "Regular commands still use 60 second default timeout"
- "Long command detection is based on command name matching"
- "Create New Project button callback works from error card"
artifacts:
- path: "src/gsd_openclaw/command_executor.py"
provides: "Extended CommandExecutor with long command support"
exports: ["CommandExecutor.LONG_COMMANDS", "CommandExecutor._is_long_command"]
- path: "src/gsd_openclaw/orchestrator.py"
provides: "Orchestrator with adaptive timeout and button callback"
exports: ["Orchestrator._is_long_command"]
- path: "tests/test_command_executor.py"
provides: "Tests for long command detection"
exports: ["TestLongCommands"]
key_links:
- from: "src/gsd_openclaw/orchestrator.py"
to: "src/gsd_openclaw/command_executor.py"
via: "execute() with timeout=None for long commands"
pattern: "_is_long_command|LONG_COMMANDS"
---
<objective>
Extend CommandExecutor with long command support and update Orchestrator for adaptive timeout and button callback.
Purpose: Ensure long-running GSD commands don't timeout prematurely, and the "Create New Project" button from error cards works correctly.
Output: CommandExecutor with LONG_COMMANDS detection, Orchestrator with adaptive timeout handling, and button callback support.
</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/command_executor.py:
```python
class CommandExecutor:
ERROR_KEYWORDS: List[str] = [...]
DEFAULT_TIMEOUT: float = 60.0
def execute(self, session, command: str, timeout: Optional[float] = None) -> CommandResult:
"""Execute command with optional timeout override."""
timeout = timeout if timeout is not None else self.DEFAULT_TIMEOUT
# ...
```
From src/gsd_openclaw/orchestrator.py:
```python
class Orchestrator:
COMMAND_PATTERN = re.compile(r'^/gsd:(\S+)\s*(.*)$')
MAX_OUTPUT_LENGTH = 2000
def handle_callback(self, callback_data: Dict[str, Any]) -> Dict[str, Any]:
"""Handle button callback - currently only supports approve/reject."""
```
Long commands from CONTEXT.md:
- execute-phase, plan-phase, discuss-phase, new-project have no timeout
- Detection via command name matching
</interfaces>
</context>
<tasks>
<task type="auto" tdd="true">
<name>Task 1: Add LONG_COMMANDS detection to CommandExecutor</name>
<files>src/gsd_openclaw/command_executor.py, tests/test_command_executor.py</files>
<behavior>
- Test 1: LONG_COMMANDS contains 'execute-phase', 'plan-phase', 'discuss-phase', 'new-project'
- Test 2: _is_long_command returns True for commands in LONG_COMMANDS
- Test 3: _is_long_command returns False for commands not in LONG_COMMANDS
- Test 4: _is_long_command handles commands with arguments correctly
</behavior>
<action>
Add long command detection to CommandExecutor:
1. Add LONG_COMMANDS class attribute:
```python
class CommandExecutor:
ERROR_KEYWORDS: List[str] = [...]
DEFAULT_TIMEOUT: float = 60.0
LONG_COMMANDS: Set[str] = {'execute-phase', 'plan-phase', 'discuss-phase', 'new-project'}
```
2. Add _is_long_command method:
```python
def _is_long_command(self, command: str) -> bool:
"""Check if command requires no timeout.
Args:
command: The full command string (e.g., '/gsd:execute-phase').
Returns:
True if command is in LONG_COMMANDS, False otherwise.
"""
# Extract command name from /gsd:command format
match = re.match(r'^/gsd:(\S+)', command)
if match:
command_name = match.group(1)
return command_name in self.LONG_COMMANDS
return False
```
3. Add TestLongCommands class to tests/test_command_executor.py:
- Test LONG_COMMANDS set contents
- Test _is_long_command for each long command
- Test _is_long_command returns False for regular commands
- Test _is_long_command handles commands with args
</action>
<verify>
<automated>pytest tests/test_command_executor.py::TestLongCommands -x -v</automated>
</verify>
<done>CommandExecutor has LONG_COMMANDS set and _is_long_command method with tests</done>
</task>
<task type="auto" tdd="true">
<name>Task 2: Update Orchestrator to use adaptive timeout</name>
<files>src/gsd_openclaw/orchestrator.py, tests/test_orchestrator.py</files>
<behavior>
- Test 1: _is_long_command in Orchestrator returns True for long commands
- Test 2: execute() is called with timeout=None for long commands
- Test 3: execute() is called with default timeout for regular commands
- Test 4: handle_message passes correct timeout based on command type
</behavior>
<action>
Add adaptive timeout to Orchestrator:
1. Add LONG_COMMANDS and _is_long_command to Orchestrator (mirror CommandExecutor):
```python
class Orchestrator:
LONG_COMMANDS = {'execute-phase', 'plan-phase', 'discuss-phase', 'new-project'}
def _is_long_command(self, command: str) -> bool:
"""Check if command requires no timeout."""
# Extract command name from parsed command
if command in self.LONG_COMMANDS:
return True
return False
```
2. Update handle_message to use adaptive timeout:
```python
# In handle_message, before execute call:
timeout = None if self._is_long_command(command) else self.executor.DEFAULT_TIMEOUT
result = self.executor.execute(session, full_command, timeout=timeout)
```
3. Update _handle_new_project to use timeout=None (already a long command):
```python
result = self.executor.execute(session, f"/gsd:new-project {project_name}", timeout=None)
```
4. Add tests in TestSpecialCommands for adaptive timeout:
- Test that long commands get timeout=None
- Test that regular commands get DEFAULT_TIMEOUT
</action>
<verify>
<automated>pytest tests/test_orchestrator.py::TestSpecialCommands -x -v</automated>
</verify>
<done>Orchestrator uses adaptive timeout based on command type</done>
</task>
<task type="auto" tdd="true">
<name>Task 3: Update handle_callback to support Create New Project button</name>
<files>src/gsd_openclaw/orchestrator.py, tests/test_orchestrator.py</files>
<behavior>
- Test 1: Callback with action="new-project" creates new session
- Test 2: Callback with action="new-project" executes /gsd:new-project command
- Test 3: Callback with action="new-project" returns success card
- Test 4: Callback with action="new-project" and missing name returns error
</behavior>
<action>
Update handle_callback to support new-project action:
1. Add new-project action handling to handle_callback:
```python
def handle_callback(self, callback_data: Dict[str, Any]) -> Dict[str, Any]:
action = callback_data.get("action", "")
if action == "new-project":
project_name = callback_data.get("name", "")
user_id = callback_data.get("user_id", "")
if not project_name:
return self.formatter.format_error(
title="Invalid Request",
content="Project name is required"
)
return self._handle_new_project(user_id, project_name)
# Existing approval handling...
if action == "approve":
...
```
2. Update _handle_use_project to include user_id in button value:
```python
CardButton(
text="Create New Project",
value={
"action": "new-project",
"name": project_name,
"user_id": user_id
}
)
```
3. Add tests in TestHandleCallback for new-project action
4. Ensure backward compatibility with existing approval callbacks
</action>
<verify>
<automated>pytest tests/test_orchestrator.py::TestHandleCallback -x -v</automated>
</verify>
<done>handle_callback supports "new-project" action from error card button</done>
</task>
</tasks>
<verification>
- All tests in tests/test_command_executor.py pass
- All tests in tests/test_orchestrator.py pass
- Long commands execute with no timeout
- Regular commands still use 60 second timeout
- "Create New Project" button callback works correctly
</verification>
<success_criteria>
- CommandExecutor has LONG_COMMANDS detection
- Orchestrator uses adaptive timeout based on command type
- handle_callback supports "new-project" action
- All existing tests still pass
</success_criteria>
<output>
After completion, create `.planning/phases/04-gsd-integration/04-03-SUMMARY.md`
</output>