From eb231be1d02ca3354a08f7de18d8a0d5a7bc4b6d Mon Sep 17 00:00:00 2001 From: egg Date: Fri, 13 Mar 2026 23:48:49 +0000 Subject: [PATCH 1/2] Convert /run-workflow from command to skill Move run-workflow from sandbox/.claude/commands/ (a command) to skills/run-workflow/SKILL.md (a proper Claude Code skill). This lets users install it globally by copying to ~/.claude/skills/. Add YAML frontmatter: name, description, disable-model-invocation, argument-hint. The skill content is unchanged. Update Dockerfile, docker.py, and entrypoint.py to copy and install skills from the top-level skills/ directory into sandbox containers. --- sandbox/.claude/commands/README.md | 14 -------------- sandbox/Dockerfile | 4 ++++ sandbox/egg_lib/docker.py | 16 ++++++++++++++++ sandbox/entrypoint.py | 16 ++++++++++++++++ .../run-workflow/SKILL.md | 7 +++++++ 5 files changed, 43 insertions(+), 14 deletions(-) rename sandbox/.claude/commands/run-workflow.md => skills/run-workflow/SKILL.md (92%) diff --git a/sandbox/.claude/commands/README.md b/sandbox/.claude/commands/README.md index 157ce93a26..82ddb73712 100644 --- a/sandbox/.claude/commands/README.md +++ b/sandbox/.claude/commands/README.md @@ -60,20 +60,6 @@ Switch to Reviewer agent mode for code quality or contract adherence review. **File**: `reviewer-mode.md` -### /run-workflow -Guide a full pipeline lifecycle: seed prompt creation, submit, monitor, HITL handling, and completion. Uses MCP tools (`submit_task`, `get_status`, `provide_input`) to interact with the coordinator. - -**Usage**: `/run-workflow` - -**What it does**: -- Gathers task parameters (description, repo, issue) -- Submits the task via the `submit_task` MCP tool -- Sets up recurring polling to monitor pipeline progress -- Handles HITL decisions inline (choice and feedback types) -- Summarizes results on completion or failure - -**File**: `run-workflow.md` - ## How Commands Work These commands are **slash commands** for Claude Code. They are markdown files that provide instructions to Claude on how to respond when you use the command syntax. diff --git a/sandbox/Dockerfile b/sandbox/Dockerfile index 3cdaf95c53..61e63e1ace 100644 --- a/sandbox/Dockerfile +++ b/sandbox/Dockerfile @@ -145,6 +145,10 @@ RUN mkdir -p /usr/local/share/claude-commands COPY sandbox/claude-commands/*.md /usr/local/share/claude-commands/ RUN chmod 644 /usr/local/share/claude-commands/*.md +# Copy Claude skills +COPY skills/ /usr/local/share/claude-skills/ +RUN find /usr/local/share/claude-skills -type f -exec chmod 644 {} \; + # Copy Claude agent rules directory RUN mkdir -p /opt/claude-rules COPY sandbox/claude-rules/*.md /opt/claude-rules/ diff --git a/sandbox/egg_lib/docker.py b/sandbox/egg_lib/docker.py index 249d2abdd1..c34e6742c3 100644 --- a/sandbox/egg_lib/docker.py +++ b/sandbox/egg_lib/docker.py @@ -460,6 +460,15 @@ def create_dockerfile() -> None: else: warn("claude-commands directory not found") + # Copy skills directory from repo root to build context + # (Dockerfile references skills/) + skills_src = script_dir.parent / "skills" + skills_dest = Config.CONFIG_DIR / "skills" + if skills_src.exists(): + _copy_directory_atomic(skills_src, skills_dest, "Claude skills", quiet) + else: + warn("skills directory not found") + # Copy claude-rules directory to sandbox subdirectory of build context # (Dockerfile references sandbox/claude-rules/) # Use atomic copy with retry to handle race conditions @@ -697,6 +706,7 @@ def compute_build_hash() -> str: - entrypoint.py - docker-setup.py - claude-commands/ + - skills/ (from repo root) - claude-rules/ - .claude/hooks/ - bin/, egg_lib/, llm/, tools/, scripts/ @@ -750,6 +760,12 @@ def compute_build_hash() -> str: hasher.update(b".claude/hooks") hash_directory(hooks_path, hasher) + # skills/ directory from repo root + skills_path = repo_root / "skills" + if skills_path.exists(): + hasher.update(b"skills") + hash_directory(skills_path, hasher) + # shared/ directory from repo root shared_path = repo_root / "shared" if shared_path.exists(): diff --git a/sandbox/entrypoint.py b/sandbox/entrypoint.py index c320579fa8..939e540ed9 100644 --- a/sandbox/entrypoint.py +++ b/sandbox/entrypoint.py @@ -897,6 +897,22 @@ def setup_claude(config: Config, logger: Logger) -> None: for cmd in (config.claude_dir / "commands").glob("*.md"): print(f" @{cmd.stem}") + # Copy skills (directory-based, each skill is a subdirectory with SKILL.md) + skills_src = Path("/usr/local/share/claude-skills") + if skills_src.exists(): + skills_dest = config.claude_dir / "skills" + skills_dest.mkdir(parents=True, exist_ok=True) + installed = [] + for skill_dir in skills_src.iterdir(): + if skill_dir.is_dir() and (skill_dir / "SKILL.md").exists(): + target = skills_dest / skill_dir.name + if target.exists(): + shutil.rmtree(target) + shutil.copytree(skill_dir, target) + installed.append(skill_dir.name) + if installed: + logger.success(f"Skills installed: {', '.join(installed)}") + # Create settings.json settings = { "defaultPermissionMode": "bypassPermissions", diff --git a/sandbox/.claude/commands/run-workflow.md b/skills/run-workflow/SKILL.md similarity index 92% rename from sandbox/.claude/commands/run-workflow.md rename to skills/run-workflow/SKILL.md index 0170972cfc..1f2294b3fd 100644 --- a/sandbox/.claude/commands/run-workflow.md +++ b/skills/run-workflow/SKILL.md @@ -1,3 +1,10 @@ +--- +name: run-workflow +description: Guide a full egg pipeline lifecycle — seed prompt, submit, monitor, HITL handling, and completion — using MCP tools (submit_task, get_status, provide_input). +disable-model-invocation: true +argument-hint: "[description] [--repo owner/name] [--issue N]" +--- + # Run Workflow You are guiding the user through a complete egg pipeline lifecycle using MCP tools. Walk through 5 phases: Seed, Submit, Monitor, HITL, and Complete. From 1abce9510192a8db80a96b32a5bb4c22bc531f64 Mon Sep 17 00:00:00 2001 From: "egg-reviewer[bot]" <261018737+egg-reviewer[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2026 00:03:10 +0000 Subject: [PATCH 2/2] Address review feedback: fix stale doc path and build resilience --- docs/guides/coordinator.md | 2 +- sandbox/egg_lib/docker.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/guides/coordinator.md b/docs/guides/coordinator.md index c3a4871538..c64d6486ac 100644 --- a/docs/guides/coordinator.md +++ b/docs/guides/coordinator.md @@ -79,7 +79,7 @@ The `/run-workflow` slash command provides a guided end-to-end workflow for subm /run-workflow --repo owner/name "Fix the auth bug" ``` -It walks through five phases automatically: seed (gather parameters), submit (`submit_task`), monitor (`get_status` polling every 60 seconds), HITL (present decisions inline via `AskUserQuestion`), and complete (summarize results and show PR link). See `sandbox/.claude/commands/run-workflow.md` for the full workflow definition. +It walks through five phases automatically: seed (gather parameters), submit (`submit_task`), monitor (`get_status` polling every 60 seconds), HITL (present decisions inline via `AskUserQuestion`), and complete (summarize results and show PR link). See `skills/run-workflow/SKILL.md` for the full workflow definition. ### Available Tools diff --git a/sandbox/egg_lib/docker.py b/sandbox/egg_lib/docker.py index c34e6742c3..35b6175464 100644 --- a/sandbox/egg_lib/docker.py +++ b/sandbox/egg_lib/docker.py @@ -467,6 +467,7 @@ def create_dockerfile() -> None: if skills_src.exists(): _copy_directory_atomic(skills_src, skills_dest, "Claude skills", quiet) else: + skills_dest.mkdir(parents=True, exist_ok=True) warn("skills directory not found") # Copy claude-rules directory to sandbox subdirectory of build context