diff --git a/skills/claude-codex-delegation/SKILL.md b/skills/claude-codex-delegation/SKILL.md index f64f77f6b53..322b9a7dcd2 100644 --- a/skills/claude-codex-delegation/SKILL.md +++ b/skills/claude-codex-delegation/SKILL.md @@ -2,7 +2,7 @@ name: claude-codex-delegation description: Delegate code-writing, document generation, and analysis tasks to Claude Code or OpenAI Codex sub-processes. Use when you need to spawn a coding agent for file generation, code modification, script writing, or any multi-step coding task. Triggers on "delegate to claude", "delegate to codex", "use claude code", "use codex", "spawn coding agent", "run delegation", or when a task requires writing/modifying code that should be handed off to a sub-process. metadata: - { "openclaw": { "os": ["linux", "darwin"], "requires": { "anyBins": ["claude", "codex"], "bins": ["bash", "timeout"] } } } + { "openclaw": { "os": ["linux"], "requires": { "anyBins": ["claude", "codex"], "bins": ["bash", "timeout"] } } } --- # Claude Code + Codex Delegation diff --git a/skills/claude-codex-delegation/install.sh b/skills/claude-codex-delegation/install.sh index 915dbbe0950..cf9976f0d8e 100755 --- a/skills/claude-codex-delegation/install.sh +++ b/skills/claude-codex-delegation/install.sh @@ -1,33 +1,38 @@ #!/usr/bin/env bash -# install.sh — Install Claude Code + Codex delegation bundle for OpenClaw. +# install.sh - Install Claude Code + Codex delegation bundle for OpenClaw. # -# Installs the Claude Code and Codex CLIs, copies delegation scripts -# into your OpenClaw workspace, and verifies the setup. +# Copies the entire skill directory (SKILL.md, scripts, references) into +# OpenClaw's shared skill location so the agent can discover and use it. +# Optionally installs the Claude Code and Codex CLIs via npm. # # Usage: # install.sh [options] # # Options: # --skip-npm Skip npm package installation (if already installed) -# --scripts-dir DIR Where to install scripts (default: ~/.openclaw/scripts) +# --skill-dir DIR Override skill install location +# (default: ~/.openclaw/skills/claude-codex-delegation) +# --force Reinstall npm packages even if already present # --dry-run Show what would be done without doing it # -h, --help Show this help message # # Requirements: # - Node.js 22+ with npm # - Existing OpenClaw installation +# - GNU coreutils (timeout, script) on Linux; macOS needs coreutils via brew # - Claude Max or OpenAI subscription (for subscription-based auth) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SCRIPTS_DIR="${HOME}/.openclaw/scripts" +SKILL_DIR="${HOME}/.openclaw/skills/claude-codex-delegation" SKIP_NPM=false +FORCE=false DRY_RUN=false -# --- Versions (pin to known-good releases) --- -CLAUDE_CODE_PKG="@anthropic-ai/claude-code" -CODEX_PKG="@openai/codex" +# --- Pinned versions --- +CLAUDE_CODE_PKG="@anthropic-ai/claude-code@latest" +CODEX_PKG="@openai/codex@latest" # --- Colors --- RED='\033[0;31m' @@ -42,16 +47,14 @@ error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } # --- Parse arguments --- while [[ $# -gt 0 ]]; do case "$1" in - --skip-npm|--scripts-dir|--dry-run) - if [[ "$1" == "--scripts-dir" ]]; then - if [[ $# -lt 2 ]]; then - echo "Error: $1 requires a value" >&2 - exit 1 - fi + --skill-dir) + if [[ $# -lt 2 ]]; then + echo "Error: $1 requires a value" >&2 + exit 1 fi - ;;& + SKILL_DIR="$2"; shift 2 ;; --skip-npm) SKIP_NPM=true; shift ;; - --scripts-dir) SCRIPTS_DIR="$2"; shift 2 ;; + --force) FORCE=true; shift ;; --dry-run) DRY_RUN=true; shift ;; -h|--help) sed -n '2,/^$/p' "$0" | sed 's/^# \?//' @@ -70,7 +73,7 @@ run() { } echo "" -echo "Claude Code + Codex Delegation — Installer" +echo "Claude Code + Codex Delegation - Installer" echo "============================================" echo "" @@ -83,8 +86,11 @@ fi NODE_MAJOR="$(node -v | sed 's/^v//' | cut -d. -f1)" if [[ "$NODE_MAJOR" -lt 22 ]]; then - warn "Node.js $(node -v) detected. Version 22+ is recommended." + error "Node.js $(node -v) detected. Version 22+ is required." + echo " Install Node.js 22+: curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -" + exit 1 fi +info "Node.js $(node -v)" if ! command -v npm &> /dev/null; then error "npm is not installed." @@ -98,12 +104,38 @@ if ! command -v openclaw &> /dev/null; then fi info "OpenClaw detected ($(openclaw --version 2>/dev/null || echo 'unknown version'))" -# --- Install Claude Code --- +# --- Check required system utilities --- +echo "" +echo "Checking system dependencies..." +MISSING=0 + +if ! command -v timeout &> /dev/null; then + error "'timeout' is required but not found." + if [[ "$(uname)" == "Darwin" ]]; then + echo " Install with: brew install coreutils" + fi + ((MISSING++)) +else + info "timeout: available" +fi + +if command -v tmux &> /dev/null; then + info "tmux: available" +else + warn "tmux: not installed (optional, needed for tmux-session.sh)" +fi + +if [[ $MISSING -gt 0 ]]; then + error "Missing $MISSING required system dependency. Install it and rerun." + exit 1 +fi + +# --- Install Claude Code and Codex --- if ! $SKIP_NPM; then echo "" echo "Installing Claude Code..." - if command -v claude &> /dev/null; then - info "Claude Code already installed ($(claude --version 2>/dev/null || echo 'unknown version'))" + if command -v claude &> /dev/null && ! $FORCE; then + info "Claude Code already installed ($(claude --version 2>/dev/null || echo 'unknown version')). Use --force to reinstall." else run npm install -g "$CLAUDE_CODE_PKG" if ! $DRY_RUN; then @@ -113,8 +145,8 @@ if ! $SKIP_NPM; then echo "" echo "Installing OpenAI Codex CLI..." - if command -v codex &> /dev/null; then - info "Codex CLI already installed ($(codex --version 2>/dev/null || echo 'unknown version'))" + if command -v codex &> /dev/null && ! $FORCE; then + info "Codex CLI already installed ($(codex --version 2>/dev/null || echo 'unknown version')). Use --force to reinstall." else run npm install -g "$CODEX_PKG" if ! $DRY_RUN; then @@ -123,35 +155,38 @@ if ! $SKIP_NPM; then fi fi -# --- Install delegation scripts --- +# --- Install skill bundle --- +# Copies the entire skill directory (SKILL.md, scripts/, references/) into +# OpenClaw's shared skill location (~/.openclaw/skills/) so the agent +# discovers it automatically. All resources stay inside the skill folder. echo "" -echo "Installing delegation scripts to $SCRIPTS_DIR..." -run mkdir -p "$SCRIPTS_DIR" - -for script in delegate.sh tmux-session.sh; do - SRC="$SCRIPT_DIR/scripts/$script" - DST="$SCRIPTS_DIR/$script" - if [[ -f "$SRC" ]]; then - run cp "$SRC" "$DST" - run chmod +x "$DST" - info "Installed $script" - else - warn "Script not found: $SRC" - fi -done - -# --- Install skill file --- -echo "" -echo "Installing skill definition..." -SKILL_DIR="${HOME}/.openclaw/workspace/skills/claude-codex-delegation" +echo "Installing skill bundle to $SKILL_DIR..." +run mkdir -p "$SKILL_DIR/scripts" run mkdir -p "$SKILL_DIR/references" + +# SKILL.md if [[ -f "$SCRIPT_DIR/SKILL.md" ]]; then run cp "$SCRIPT_DIR/SKILL.md" "$SKILL_DIR/SKILL.md" info "Installed SKILL.md" fi + +# Scripts (inside the skill directory, not a global scripts dir) +for script in delegate.sh tmux-session.sh; do + SRC="$SCRIPT_DIR/scripts/$script" + DST="$SKILL_DIR/scripts/$script" + if [[ -f "$SRC" ]]; then + run cp "$SRC" "$DST" + run chmod +x "$DST" + info "Installed scripts/$script" + else + error "Script not found: $SRC" + fi +done + +# References if [[ -f "$SCRIPT_DIR/references/delegation-policy.md" ]]; then run cp "$SCRIPT_DIR/references/delegation-policy.md" "$SKILL_DIR/references/delegation-policy.md" - info "Installed delegation-policy.md" + info "Installed references/delegation-policy.md" fi # --- Verify --- @@ -173,43 +208,36 @@ else ((ERRORS++)) fi -if [[ -x "$SCRIPTS_DIR/delegate.sh" ]] || $DRY_RUN; then - info "delegate.sh: OK" +if [[ -f "$SKILL_DIR/SKILL.md" ]] || $DRY_RUN; then + info "SKILL.md: OK" else - error "delegate.sh: not found or not executable" + error "SKILL.md: not found at $SKILL_DIR" ((ERRORS++)) fi -if [[ -x "$SCRIPTS_DIR/tmux-session.sh" ]] || $DRY_RUN; then - info "tmux-session.sh: OK" +if [[ -x "$SKILL_DIR/scripts/delegate.sh" ]] || $DRY_RUN; then + info "scripts/delegate.sh: OK" else - error "tmux-session.sh: not found or not executable" + error "scripts/delegate.sh: not found or not executable" ((ERRORS++)) fi -# --- Optional dependencies --- -echo "" -if command -v tmux &> /dev/null; then - info "tmux: available (for long-running sessions)" +if [[ -x "$SKILL_DIR/scripts/tmux-session.sh" ]] || $DRY_RUN; then + info "scripts/tmux-session.sh: OK" else - warn "tmux: not installed (optional — needed for tmux-session.sh)" -fi - -if command -v timeout &> /dev/null; then - info "timeout: available" -else - warn "timeout: not found (needed for delegate.sh)" + error "scripts/tmux-session.sh: not found or not executable" + ((ERRORS++)) fi # --- Auth check --- echo "" echo "Checking auth..." -echo " Claude Code auth: run 'claude auth' to verify subscription/OAuth is configured" -echo " Codex auth: run 'codex auth' to verify OpenAI subscription is configured" +echo " Claude Code: run 'claude auth' to verify subscription/OAuth is configured" +echo " Codex: run 'codex auth' to verify OpenAI subscription is configured" echo "" echo " NOTE: The delegation scripts strip API keys from the sub-process" -echo " environment. Both Claude Code and Codex must be configured with" -echo " subscription/OAuth auth — API key auth will NOT work." +echo " environment. Both CLIs must be configured with subscription/OAuth" +echo " auth. API key auth will NOT work." # --- Summary --- echo "" @@ -217,13 +245,15 @@ if [[ $ERRORS -eq 0 ]]; then echo "============================================" info "Installation complete." echo "" + echo " Skill installed to: $SKILL_DIR" + echo "" echo " Delegate a task:" - echo " $SCRIPTS_DIR/delegate.sh --prompt 'Your task' --workdir ~/project" + echo " $SKILL_DIR/scripts/delegate.sh --prompt 'Your task' --workdir ~/project" echo "" echo " Long-running task in tmux:" - echo " $SCRIPTS_DIR/tmux-session.sh --name my-task --prompt 'Your task' --workdir ~/project" + echo " $SKILL_DIR/scripts/tmux-session.sh --name my-task --prompt 'Your task' --workdir ~/project" echo "" - echo " See SKILL.md for full usage and security documentation." + echo " OpenClaw will discover the skill automatically on next session." echo "============================================" else error "$ERRORS verification error(s). Check the output above." diff --git a/skills/claude-codex-delegation/scripts/delegate.sh b/skills/claude-codex-delegation/scripts/delegate.sh index 6403de9ae4e..4fddf524ee6 100755 --- a/skills/claude-codex-delegation/scripts/delegate.sh +++ b/skills/claude-codex-delegation/scripts/delegate.sh @@ -185,11 +185,11 @@ ESCAPED_LOG="$(printf '%q' "$LOG_FILE")" if $BACKGROUND; then ( + EXIT_CODE=0 timeout "$TIMEOUT" bash -c "$(declare -f run_delegation build_claude_cmd build_codex_cmd); \ AGENT='$AGENT' PROMPT='$(printf '%s' "$PROMPT" | sed "s/'/'\\\\''/g")' \ WORKDIR=$ESCAPED_WORKDIR LOG_FILE=$ESCAPED_LOG FULL_AUTO=$FULL_AUTO \ - run_delegation" - EXIT_CODE=$? + run_delegation" || EXIT_CODE=$? echo "" echo "--- Delegation complete (exit code: $EXIT_CODE) ---" ) >> "$LOG_FILE" 2>&1 & @@ -197,11 +197,11 @@ if $BACKGROUND; then echo "Background PID: $BG_PID" echo "Monitor: tail -f $LOG_FILE" else + EXIT_CODE=0 timeout "$TIMEOUT" bash -c "$(declare -f run_delegation build_claude_cmd build_codex_cmd); \ AGENT='$AGENT' PROMPT='$(printf '%s' "$PROMPT" | sed "s/'/'\\\\''/g")' \ WORKDIR=$ESCAPED_WORKDIR LOG_FILE=$ESCAPED_LOG FULL_AUTO=$FULL_AUTO \ - run_delegation" - EXIT_CODE=$? + run_delegation" || EXIT_CODE=$? if [[ $EXIT_CODE -eq 0 ]]; then echo "Delegation complete." elif [[ $EXIT_CODE -eq 124 ]]; then