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-RESEARCH.md
T

24 KiB

Phase 4: GSD Integration - Research

Researched: 2026-03-11 Domain: GSD command bridging, user context tracking, special command handling Confidence: HIGH

Summary

Phase 4 completes the GSD command coverage by implementing special handling for key commands (/gsd:new-project and /gsd:use) while ensuring all 34 GSD slash commands work through pass-through mode. The primary technical challenges are:

  1. Special Command Handling: /gsd:new-project requires pre-creating the tmux session and workspace before passing the command to GSD. /gsd:use requires tracking user context across sessions.

  2. User Context Tracking: A new UserContextManager class is needed to track which project each user is currently working on, stored in independent user state files.

  3. Long Command Support: Certain commands (execute-phase, plan-phase, discuss-phase, new-project) have no timeout and rely on GSD's completion signal with progress updates.

Primary recommendation: Extend the existing Orchestrator class with special command detection logic, add a new UserContextManager class following Phase 1's atomic write patterns, and leverage existing Phase 3 components (ProgressMonitor, ApprovalHandler) for long-running operations.

<user_constraints>

User Constraints (from CONTEXT.md)

Locked Decisions

命令清单处理策略

  • 处理模式: 关键命令特殊处理,其余泛型透传
  • 关键命令定义: /gsd:new-project 和 /gsd:use 需要 orchestrator 特殊逻辑
  • 泛型命令: 其他 32 个命令统一通过 tmux 透传 + 卡片格式化

关键命令特殊处理

/gsd:new-project
  • 预创建会话: orchestrator 检测命令后,先调用 TmuxSessionManager 创建会话和工作空间
  • 命令透传: 会话创建后,透传命令到 tmux 让 GSD 初始化项目结构
  • 工作空间路径: ~/gsd-workspaces/{project}/
/gsd:use
  • 上下文追踪: OpenClaw 在用户级别追踪当前项目(存入独立用户状态文件)
  • 后续命令路由: 后续命令根据追踪的上下文选择目标 tmux 会话
  • 项目不存在处理: 检查项目是否存在,不存在则返回错误卡片 + 「创建新项目」按钮

项目上下文追踪

存储设计
  • 位置: ~/gsd-workspaces/.users/{user_id}/context.json
  • 格式: JSON,原子写入(与 Phase 1 state.json 一致)
追踪数据
  • 当前项目: 用户当前正在操作的项目名
  • 最近项目列表: 最近使用的项目(保留最近 5 个)
  • 最后活跃时间: 用户上次活动时间戳
  • 用户偏好: 可选的个性化设置(默认超时、输出格式等)

多用户场景

  • 隔离策略: 完全隔离 — 每个用户独立的 tmux 会话和工作空间
  • 用户识别: 通过 OpenClaw 的 user_id 区分

频道支持

  • Phase 4 范围: 仅飞书
  • 其他频道: 微信、Telegram、Discord 延后到 v2

工作流连续性

上下文保持
  • 机制: tmux 持久会话
  • Claude CLI 上下文: 自然保持在 tmux 会话中
  • 用户重连: 直接重连到现有 tmux 会话
中途掉线恢复
  • 责任归属: GSD 处理恢复(通过 STATE.md 追踪)
  • OpenClaw 角色: 只负责重新连接到 tmux 会话
长命令超时
  • 普通命令: 60 秒超时(Phase 3 已定义)
  • 长命令: 无超时,依赖 GSD 自己的完成信号
  • 长命令列表: execute-phase, plan-phase, discuss-phase, new-project
  • 进度更新: 使用 Phase 3 的 ProgressMonitor 机制

Claude's Discretion

  • 用户偏好的具体字段名和默认值
  • 长命令检测的具体逻辑(命令名匹配 vs 运行时检测)
  • 最近项目列表的保留数量(建议 5 个)

Deferred Ideas (OUT OF SCOPE)

  • 微信频道支持 — v2 特性
  • Telegram/Discord 频道支持 — v2 特性
  • 多语言支持(中文/英文切换)
  • 项目共享(多用户协作同一项目)
  • 命令历史记录和搜索

</user_constraints>

<phase_requirements>

Phase Requirements

ID Description Research Support
BRDG-06 All GSD slash commands are supported (no command left behind) GSD has 34 commands across 5 categories (Core Workflow, Navigation, Brownfield, Phase Management, Session, Utilities). Current Orchestrator supports generic pass-through via regex parsing. Special handling needed for new-project and use.
</phase_requirements>

Standard Stack

Core

Library Version Purpose Why Standard
libtmux 0.37.0+ tmux session management Already used in Phase 1 TmuxSessionManager
Python dataclasses 3.12+ Data structures Established pattern in existing codebase
json (stdlib) 3.12+ State persistence Already used in Phase 1 StateManager
tempfile (stdlib) 3.12+ Atomic writes Established pattern from Phase 1
re (stdlib) 3.12+ Command parsing Already used in Orchestrator

Supporting

Library Version Purpose When to Use
pytest 8.0+ Testing All new components
unittest.mock 3.12+ Mocking tmux Unit tests for UserContextManager

Alternatives Considered

Instead of Could Use Tradeoff
Custom UserContextManager SQLite for user state SQLite adds complexity; JSON is simpler and matches Phase 1 pattern
Command name prefix matching Runtime detection of long commands Prefix matching is simpler and more predictable; runtime detection would require analyzing output patterns

Installation:

# No new dependencies required - all existing stack

Architecture Patterns

src/gsd_openclaw/
├── user_context.py        # NEW: UserContextManager class
├── orchestrator.py        # EXTEND: Add special command handling
├── tmux_session.py        # REUSE: Session creation for new-project
├── command_executor.py    # EXTEND: Add long command detection
├── progress_monitor.py    # REUSE: Progress updates for long commands
├── approval_handler.py    # REUSE: Button callbacks for "create project"
├── response_formatter.py  # REUSE: Card formatting
└── state_manager.py       # REUSE: Atomic write pattern reference

tests/
├── test_user_context.py   # NEW: UserContextManager tests
├── test_orchestrator.py   # EXTEND: Add special command tests
└── conftest.py            # EXTEND: Add user context fixtures

Pattern 1: UserContextManager Class

What: Manages per-user project context with atomic persistence When to use: Tracking which project a user is working on Example:

# Source: Based on Phase 1 StateManager pattern
from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional, List
import json
import tempfile
import os

@dataclass
class UserContext:
    """User's project context state."""
    schema_version: str = "1.0"
    user_id: str = ""
    current_project: str = ""
    recent_projects: List[str] = field(default_factory=list)
    last_active_at: str = ""
    preferences: dict = field(default_factory=dict)

class UserContextManager:
    """Manages user context with atomic persistence."""

    USERS_ROOT = Path.home() / "gsd-workspaces" / ".users"

    def __init__(self, user_id: str, users_root: Optional[Path] = None):
        self.user_id = user_id
        self.users_root = Path(users_root) if users_root else self.USERS_ROOT
        self.context_path = self.users_root / user_id / "context.json"

    def load(self) -> Optional[UserContext]:
        """Load user context with backup fallback."""
        # Same pattern as StateManager.load()
        ...

    def save(self, context: UserContext) -> None:
        """Save user context atomically with backup rotation."""
        # Same pattern as StateManager.save_state()
        # 1. Create parent dirs
        # 2. Rotate backup
        # 3. Write to temp file
        # 4. Atomic replace
        ...

Pattern 2: Special Command Detection in Orchestrator

What: Route specific commands to special handlers, pass others through When to use: Processing incoming /gsd:* commands Example:

# Source: Extension of existing Orchestrator.handle_message()
class Orchestrator:
    # Long commands that need no timeout
    LONG_COMMANDS = {'execute-phase', 'plan-phase', 'discuss-phase', 'new-project'}

    def handle_message(self, user_id: str, message: str, channel: str, context: Dict) -> Dict:
        parsed = self.parse_command(message)
        if parsed is None:
            return self.formatter.format_info(title="无效命令", content="...")

        command, args = parsed

        # Special handling for new-project
        if command == 'new-project':
            return self._handle_new_project(user_id, args)

        # Special handling for use
        if command == 'use':
            return self._handle_use_project(user_id, args)

        # Generic pass-through for all other commands
        return self._handle_generic_command(user_id, command, args)

    def _handle_new_project(self, user_id: str, project_name: str) -> Dict:
        """Pre-create session then pass command to GSD."""
        # 1. Create tmux session via TmuxSessionManager
        session = self.tmux_manager.create_session(project_name)
        # 2. Execute /gsd:new-project in the session
        result = self.executor.execute(session, f"/gsd:new-project {project_name}", timeout=None)
        # 3. Update user context
        self.user_context_manager.set_current_project(user_id, project_name)
        # 4. Return formatted result
        ...

    def _handle_use_project(self, user_id: str, project_name: str) -> Dict:
        """Switch user's current project context."""
        # 1. Check if project exists
        session = self.tmux_manager.get_session(project_name)
        if session is None:
            # Return error card with "Create New Project" button
            return self.formatter.format_error(
                title="项目不存在",
                content=f"项目 '{project_name}' 不存在",
                buttons=[CardButton(text="创建新项目", value={"action": "new-project", "name": project_name})]
            )
        # 2. Update user context
        self.user_context_manager.set_current_project(user_id, project_name)
        # 3. Return success
        ...

    def _is_long_command(self, command: str) -> bool:
        """Check if command requires no timeout."""
        return command in self.LONG_COMMANDS

Pattern 3: Long Command Execution

What: Execute commands without timeout, use progress monitoring When to use: Commands that take minutes to complete Example:

# Source: Extension of CommandExecutor.execute()
def execute_with_progress(
    self,
    session,
    command: str,
    progress_callback: Callable[[ProgressInfo], None],
    poll_interval: float = 5.0  # Check every 5 seconds for long commands
) -> CommandResult:
    """Execute long command with progress updates."""
    # 1. Send command
    self.send_command(session.tmux_session.active_pane, command)

    # 2. Poll for output and progress
    while True:
        time.sleep(poll_interval)
        output = self._capture_current_output(session.tmux_session.active_pane)

        # Check for progress indicators
        progress = self.progress_monitor.extract_progress(output)
        if progress and self.progress_monitor.should_send_update():
            progress_callback(progress)

        # Check for completion (prompt or stabilization)
        if self._is_complete(output):
            return CommandResult(output=output, completed=True, ...)

Anti-Patterns to Avoid

  • Don't block on long commands: Use async polling, not synchronous waits
  • Don't mix user contexts: Each user has isolated context, never share between users
  • Don't timeout long commands: execute-phase, plan-phase, discuss-phase, new-project have no timeout
  • Don't duplicate state logic: Reuse Phase 1's atomic write pattern for UserContextManager

Don't Hand-Roll

Problem Don't Build Use Instead Why
User state persistence Custom file locking StateManager atomic write pattern Crash-safe, tested pattern from Phase 1
Progress detection Custom regex ProgressMonitor.extract_progress() Already handles percentage, fraction, phase patterns
Approval cards New button format ApprovalHandler.create_approval_card() Existing pattern for interactive buttons
Session creation Manual tmux commands TmuxSessionManager.create_session() Handles collision resolution, state persistence

Key insight: Phase 4 is primarily about extending existing patterns, not creating new ones. The UserContextManager follows StateManager patterns exactly, special commands extend Orchestrator's routing, and long commands extend CommandExecutor.

Common Pitfalls

Pitfall 1: Race Condition in Session Creation

What goes wrong: Two users try to create project with same name simultaneously Why it happens: No locking on session creation How to avoid: TmuxSessionManager._resolve_collision() already handles this with timestamp suffix Warning signs: Session names with unexpected suffixes, duplicate state files

Pitfall 2: User Context File Corruption

What goes wrong: Server crash during write leaves corrupted context.json Why it happens: Not using atomic writes How to avoid: Follow StateManager pattern exactly: tempfile + os.replace Warning signs: JSONDecodeError when loading context, missing user preferences

Pitfall 3: Long Command Timeout

What goes wrong: execute-phase times out after 60 seconds Why it happens: Using default timeout for all commands How to avoid: Check command name against LONG_COMMANDS set, pass timeout=None Warning signs: Commands return "timeout" status, incomplete phases

Pitfall 4: Missing User Context on First Use

What goes wrong: New user sends command without context Why it happens: UserContextManager.load() returns None for new users How to avoid: Create default context on first access, use "default" project Warning signs: KeyError on user_id, missing project routing

Code Examples

Verified patterns from existing codebase:

Atomic Write Pattern (from state_manager.py)

# Source: /home/starmen1265/work/kb-skills/gsd-openclaw/src/gsd_openclaw/state_manager.py
def save_state(state: SessionState, state_path: Path) -> None:
    """Save session state to file atomically with backup rotation."""
    state_path = Path(state_path)
    backup_path = state_path.with_suffix('.json.bak')

    # 1. Create parent directories if missing
    state_path.parent.mkdir(parents=True, exist_ok=True)

    # 2. Rotate backup
    if state_path.exists():
        if backup_path.exists():
            backup_path.unlink()
        state_path.rename(backup_path)

    # 3. Write to temp file in same directory
    fd, temp_path = tempfile.mkstemp(dir=state_path.parent, suffix='.tmp')
    try:
        with os.fdopen(fd, 'w', encoding='utf-8') as f:
            json.dump(state.to_dict(), f, indent=2, ensure_ascii=False)
        # 4. Atomic replace
        os.replace(temp_path, state_path)
    except Exception:
        if os.path.exists(temp_path):
            os.unlink(temp_path)
        raise

Command Parsing Pattern (from orchestrator.py)

# Source: /home/starmen1265/work/kb-skills/gsd-openclaw/src/gsd_openclaw/orchestrator.py
class Orchestrator:
    COMMAND_PATTERN = re.compile(r'^/gsd:(\S+)\s*(.*)$')

    def parse_command(self, message: str) -> Optional[Tuple[str, str]]:
        """Parse a message for /gsd:* command pattern."""
        match = self.COMMAND_PATTERN.match(message.strip())
        if match:
            command = match.group(1)
            args = match.group(2).strip()
            return (command, args)
        return None

Progress Detection Pattern (from progress_monitor.py)

# Source: /home/starmen1265/work/kb-skills/gsd-openclaw/src/gsd_openclaw/progress_monitor.py
class ProgressMonitor:
    PROGRESS_PATTERNS = [
        (re.compile(r'(\d+)%'), 'percentage'),
        (re.compile(r'\[(\d+)/(\d+)(?:[^\]]*)\]'), 'fraction'),
        (re.compile(r'Phase\s+(\d+)', re.IGNORECASE), 'phase'),
        (re.compile(r'完成|completed|done', re.IGNORECASE), 'completion'),
    ]

    def extract_progress(self, output: str) -> Optional[ProgressInfo]:
        """Extract progress information from output text."""
        for pattern, progress_type in self.PROGRESS_PATTERNS:
            match = pattern.search(output)
            if match:
                # Return ProgressInfo based on type
                ...

State of the Art

Old Approach Current Approach When Changed Impact
Per-session context Per-user context (Phase 4) This phase Users can switch projects without losing context
Fixed 60s timeout Adaptive timeout based on command This phase Long commands no longer timeout prematurely
Generic command handling Special handling for key commands This phase new-project pre-creates session, use tracks context

Deprecated/outdated:

  • None in this phase (building on existing patterns)

GSD Command Categories (34 Total)

Based on official GSD documentation (https://github.com/gsd-build/get-shit-done):

Core Workflow (8 commands)

Command Description Special Handling
/gsd:new-project Initialize project with questions, research, requirements, roadmap YES - Pre-create session
/gsd:discuss-phase Capture implementation decisions Long command
/gsd:plan-phase Research + plan + verify Long command
/gsd:execute-phase Execute plans in parallel waves Long command
/gsd:verify-work Manual user acceptance testing Pass-through
/gsd:audit-milestone Verify milestone completion Pass-through
/gsd:complete-milestone Archive milestone, tag release Pass-through
/gsd:new-milestone Start next version Pass-through

Navigation (4 commands)

Command Description Special Handling
/gsd:progress Show current position Pass-through
/gsd:help Show all commands Pass-through
/gsd:update Update GSD Pass-through
/gsd:join-discord Join community Pass-through

Brownfield (1 command)

Command Description Special Handling
/gsd:map-codebase Analyze existing codebase Pass-through

Phase Management (5 commands)

Command Description Special Handling
/gsd:add-phase Append phase to roadmap Pass-through
/gsd:insert-phase Insert urgent work Pass-through
/gsd:remove-phase Remove future phase Pass-through
/gsd:list-phase-assumptions See Claude's approach Pass-through
/gsd:plan-milestone-gaps Create phases for gaps Pass-through

Session (2 commands)

Command Description Special Handling
/gsd:pause-work Create handoff Pass-through
/gsd:resume-work Restore from session Pass-through

Utilities (9 commands)

Command Description Special Handling
/gsd:use Switch project context YES - Track user context
/gsd:settings Configure GSD Pass-through
/gsd:set-profile Switch model profile Pass-through
/gsd:add-todo Capture idea Pass-through
/gsd:check-todos List pending todos Pass-through
/gsd:debug Systematic debugging Pass-through
/gsd:quick Execute ad-hoc task Pass-through
/gsd:health Validate .planning/ Pass-through

Note: 2 commands need special handling (new-project, use), 4 are long commands (new-project, execute-phase, plan-phase, discuss-phase), all others pass through generically.

Open Questions

  1. User Preferences Schema

    • What we know: CONTEXT.md mentions preferences field (default timeout, output format)
    • What's unclear: Exact field names and default values
    • Recommendation: Start minimal with empty dict, add fields as needed
  2. Long Command Detection Implementation

    • What we know: Command name matching is the approach (from CONTEXT.md)
    • What's unclear: Whether to also detect long-running at runtime
    • Recommendation: Start with command name matching, add runtime detection if needed
  3. Recent Projects List Size

    • What we know: CONTEXT.md suggests 5 items
    • What's unclear: Whether this should be configurable
    • Recommendation: Hardcode 5, make configurable later if requested

Validation Architecture

Test Framework

Property Value
Framework pytest 8.0+
Config file pyproject.toml (existing)
Quick run command pytest tests/test_user_context.py tests/test_orchestrator.py -x -v
Full suite command pytest -x

Phase Requirements → Test Map

Req ID Behavior Test Type Automated Command File Exists?
BRDG-06 All 34 GSD commands supported unit pytest tests/test_orchestrator.py::TestGsdCommands -x -v Wave 0 (new)
BRDG-06 new-project pre-creates session unit pytest tests/test_orchestrator.py::TestSpecialCommands::test_new_project_creates_session -v Wave 0 (new)
BRDG-06 use tracks user context unit pytest tests/test_user_context.py::TestUserContextManager::test_set_current_project -v Wave 0 (new)
BRDG-06 use shows error for non-existent project unit pytest tests/test_orchestrator.py::TestSpecialCommands::test_use_nonexistent_project -v Wave 0 (new)
BRDG-06 long commands have no timeout unit pytest tests/test_command_executor.py::TestLongCommands -v Wave 0 (extend)
BRDG-06 user context persists atomically unit pytest tests/test_user_context.py::TestAtomicWrites -v Wave 0 (new)
BRDG-06 user context isolated between users unit pytest tests/test_user_context.py::TestMultiUser -v Wave 0 (new)

Sampling Rate

  • Per task commit: pytest tests/test_user_context.py tests/test_orchestrator.py -x -v
  • Per wave merge: pytest -x
  • Phase gate: Full suite green before /gsd:verify-work

Wave 0 Gaps

  • tests/test_user_context.py — new file for UserContextManager tests
  • tests/test_orchestrator.py — extend with TestSpecialCommands class
  • tests/conftest.py — add user_context fixture
  • Extend tests/test_command_executor.py — add long command tests

Sources

Primary (HIGH confidence)

  • GSD Official Repository: https://github.com/gsd-build/get-shit-done - Complete command list and documentation
  • Existing codebase: /home/starmen1265/work/kb-skills/gsd-openclaw/src/gsd_openclaw/ - Established patterns for state management, command execution, response formatting

Secondary (MEDIUM confidence)

  • Phase 1 research: .planning/phases/01-core-infrastructure/01-RESEARCH.md - StateManager atomic write pattern
  • Phase 3 research: .planning/phases/03-orchestration/03-RESEARCH.md - Orchestrator command routing

Tertiary (LOW confidence)

  • None - all findings verified against codebase or official docs

Metadata

Confidence breakdown:

  • Standard stack: HIGH - All libraries already in use
  • Architecture: HIGH - Patterns established in Phases 1-3
  • Pitfalls: HIGH - Based on analysis of existing code patterns

Research date: 2026-03-11 Valid until: 30 days - stable patterns, unlikely to change significantly