companion-offload

SKILL.md

Companion Offload

Offload the current Claude Code session to a remote Companion sandbox so it can continue running autonomously in the cloud.

When to use

  • The user says "offload this task" or "run this in the cloud"
  • A long-running task needs to continue without tying up the local machine
  • The user wants to hand off work to their Companion sandbox

Prerequisites

  • The companion CLI must be installed and the user must be logged in (companion login)
  • An active sandbox must exist and be running (companion ls to check)
  • rsync must be available locally

Instructions

Step 1: Verify companion CLI is available and user is logged in

companion whoami

If this fails, tell the user to run companion login first.

Step 2: Check that a sandbox is running

companion ls

If no sandbox exists or it's not running, tell the user to create one with companion create <handle>.

Step 3: Inject SSH key into the sandbox

Use --inject-only to set up SSH access without connecting:

companion ssh --inject-only

This outputs the SSH key path and the manual SSH command. Parse the output to extract:

  • The key path (e.g. ~/.companion/ssh/id_ed25519_<handle>)
  • The sandbox handle

Step 4: Build the SSH/rsync connection parameters

The Companion SSH gateway uses a ProxyCommand. Construct the connection parameters:

HANDLE="<sandbox-handle-from-step-2>"
KEY_PATH="$HOME/.companion/ssh/id_ed25519_$HANDLE"
SSH_GATEWAY="${COMPANION_SSH_GATEWAY:-ssh.os.companion.ai}"
SSH_PORT="2222"
PROXY_CMD="sh -c '( printf \"COMPANION:${HANDLE}\n\"; cat ) | nc ${SSH_GATEWAY} ${SSH_PORT}'"
SSH_OPTS="-i $KEY_PATH -o StrictHostKeyChecking=accept-new -o LogLevel=ERROR -o ProxyCommand=$PROXY_CMD"

Step 5: Determine the remote workspace path

ssh $SSH_OPTS node@$HANDLE '[ -d /home/node/.openclaw/workspace ] && echo "/home/node/.openclaw/workspace" || ([ -d /home/node/.pi/workspace ] && echo "/home/node/.pi/workspace" || echo "NONE")'

If NONE, use /home/node/.openclaw/workspace and create it:

ssh $SSH_OPTS node@$HANDLE 'mkdir -p /home/node/.openclaw/workspace'

Store the result as REMOTE_WORKSPACE.

Step 6: Install Claude Code on the sandbox if missing

ssh $SSH_OPTS node@$HANDLE 'command -v claude >/dev/null 2>&1 && echo "installed" || echo "missing"'

If missing:

ssh $SSH_OPTS node@$HANDLE 'curl -fsSL https://claude.ai/install.sh | sh 2>/dev/null || npm install -g @anthropic-ai/claude-code'

Step 7: Sync the repository to the sandbox

Use rsync over the SSH ProxyCommand to transfer the current project:

rsync -avz --progress \
  --exclude='node_modules' \
  --exclude='.git/objects' \
  --exclude='__pycache__' \
  --exclude='.venv' \
  --exclude='venv' \
  --exclude='.next' \
  --exclude='dist' \
  --exclude='build' \
  -e "ssh $SSH_OPTS" \
  "$(pwd)/" "node@$HANDLE:$REMOTE_WORKSPACE/"

Step 8: Sync the Claude session and config

Transfer the project-level .claude/ directory (session history, project memory) if it exists:

rsync -avz --progress \
  -e "ssh $SSH_OPTS" \
  "$(pwd)/.claude/" "node@$HANDLE:$REMOTE_WORKSPACE/.claude/"

Also sync the global ~/.claude/ directory (global settings, global memory, credentials, CLAUDE.md):

rsync -avz --progress \
  -e "ssh $SSH_OPTS" \
  "$HOME/.claude/" "node@$HANDLE:/home/node/.claude/"

Both are needed: the project-level .claude/ has session history for --continue, and the global ~/.claude/ has settings, global memory, and the user's global CLAUDE.md instructions.

Step 9: Transfer environment variables

Capture relevant env vars (especially ANTHROPIC_API_KEY) and send them to the sandbox:

env | grep -v '^_=' | grep -v '^SHELL=' | grep -v '^TERM_' | grep -v '^SSH_' | \
  grep -v '^DISPLAY=' | grep -v '^HOME=' | grep -v '^USER=' | grep -v '^LOGNAME=' | \
  grep -v '^PATH=' | grep -v '^PWD=' | grep -v '^OLDPWD=' | grep -v '^SHLVL=' \
  > /tmp/companion_env_export.txt
rsync -avz -e "ssh $SSH_OPTS" /tmp/companion_env_export.txt "node@$HANDLE:$REMOTE_WORKSPACE/.companion_env"
rm -f /tmp/companion_env_export.txt

Step 10: Launch Claude Code on the sandbox

If the user provided a specific task/prompt to offload:

ssh -t $SSH_OPTS node@$HANDLE "cd $REMOTE_WORKSPACE && set -a && source .companion_env 2>/dev/null; set +a && claude --dangerously-skip-permissions --prompt '${TASK_PROMPT}'"

Otherwise, continue the session:

ssh -t $SSH_OPTS node@$HANDLE "cd $REMOTE_WORKSPACE && set -a && source .companion_env 2>/dev/null; set +a && claude --dangerously-skip-permissions --continue"

Step 11: Confirm to the user

After launching, tell the user:

  • The session is now running on their Companion sandbox
  • They can reconnect with: companion ssh then cd $REMOTE_WORKSPACE && claude --continue
  • To sync results back locally: rsync -avz -e "ssh $SSH_OPTS" node@$HANDLE:$REMOTE_WORKSPACE/ ./

Important notes

  • Always exclude node_modules, .git/objects, and other large directories from rsync
  • The --dangerously-skip-permissions flag is required so the remote session runs autonomously
  • If the sandbox already has ANTHROPIC_API_KEY set, the offloaded session will use it. Otherwise ensure Step 9 transfers it.
  • Session history in .claude/ gives the remote Claude full context of the local conversation
  • The SSH gateway at ssh.os.companion.ai:2222 routes connections via the COMPANION:<handle> prefix

Error handling

  • If companion whoami fails: user needs to companion login
  • If companion ls shows no sandbox: user needs to companion create <handle>
  • If SSH key injection fails: sandbox may not be running
  • If rsync fails: check disk space on sandbox
  • If Claude is not installable: ensure Node.js >= 18 is on the sandbox
Weekly Installs
4
First Seen
6 days ago
Installed on
augment4
claude-code4
github-copilot4
codex4
droid4
kimi-cli4