# Remote Agents

> Runs a long or expensive coding-agent task headlessly on a remote SSH host (e.g. claude -p or codex exec) instead of the local machine, so the job survives disconnects and doesn't block the local machine while it runs. Tracks job state as files on the remote host, polls status, and pulls results back once done. Use when a task will run long, needs to keep going after closing the laptop, or should run somewhere other than the current machine.

- Skill: `jsvillalbat/remote-agents` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add jsvillalbat/remote-agents`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jsvillalbat/remote-agents/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: jsvillalbat (https://skillmd.com/u/jsvillalbat)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/jsvillalbat/remote-agents

---


# Remote Agents

A long-running coding-agent task tied to the local session dies the moment the laptop
sleeps, the network drops, or the session ends. This skill submits the job to a remote
host as a detached process instead — it keeps running independent of the connection,
and file-based state means checking on it later is just reading files, not
maintaining a live session.

## When to use this

- The task will run long enough that keeping a local session open for it is wasteful
  or risky (network drop, laptop sleep).
- The work should survive you closing the laptop and checking back later.
- The task should run on a different machine than the current one (more resources,
  a specific environment, isolation from local state).
- **Not for short interactive work** — the setup overhead (self-contained prompt,
  submit/poll/collect cycle) isn't worth it for anything that finishes in a couple of
  minutes with you watching.

## Instructions

### 1. Write a fully self-contained prompt

The remote job gets **zero context from this session** — only what's in the prompt
you hand it. It must include:

- The task itself, stated completely (no "as discussed above" — there is no above).
- Verification commands the job should run to confirm its own work (see
  [`verify-before-done`](../verify-before-done) for what counts as real evidence).
- Any constraints (files it must not touch, style/conventions to follow).
- A **REPORT contract**: ask the job to print a clearly delimited block at the end so
  results are machine-parseable later, e.g.:

  ```text
  REPORT_START
  status: <done|blocked|partial>
  summary: <what was done>
  verification: <what was run and what it showed>
  REPORT_END
  ```

A job that runs unsupervised and produces unparseable prose output is much harder to
collect results from later — the contract is what makes `collect.sh` useful.

### 2. Submit the job

```bash
scripts/submit.sh <host> <job-id> <remote-work-dir> <claude|codex> [-- extra CLI args...] <<'PROMPT'
<the fully self-contained prompt from step 1>
PROMPT
```

This copies the runner script to the host, writes the prompt there, and launches the
job as a detached, `nohup`'d process so it survives the SSH session ending. Pick a
`job-id` you'll remember (a short slug, not a random UUID) — you'll use it for every
subsequent command.

### 3. Poll status

```bash
scripts/status.sh <host> <job-id>
```

Reports `RUNNING`, `DONE`, `FAILED` (nonzero exit — check logs), or `UNKNOWN` (no
state found — check the host/job-id). Safe to run repeatedly; each call is a cheap
SSH round-trip reading one file.

### 4. Debug a failed or stuck job

```bash
scripts/logs.sh <host> <job-id> [lines]
```

Tails the remote job's output log. Check this before resubmitting — a `FAILED` status
with no investigation just repeats whatever went wrong the first time.

### 5. Collect results once DONE

```bash
scripts/collect.sh <host> <job-id> [local-out-dir]
```

Pulls the full output log locally and, if the job printed a `REPORT_START`/
`REPORT_END` block per the contract in step 1, extracts it to `report.txt`
separately from the raw log.

### 6. Cross-provider review (optional, for higher-stakes jobs)

If both `claude` and `codex` are set up on the remote host, review with whichever
engine did **not** implement — mirrors the reasoning in
[`codex-judge`](../codex-judge): same-model review inherits the same blind spots.
Submit a second job whose self-contained prompt includes the diff and a review
request, using the other engine.

### 7. Report back

State: job id, host, final status, what the collected REPORT block said (not just
"check the remote host" — actually read and relay it), and whether verification
evidence was included or the job reported it couldn't verify.

## Scripts

- `scripts/remote-runner.sh` — runs **on the remote host**; launches the detached job
  and writes status/output files. Copied there automatically by `submit.sh`.
- `scripts/submit.sh` — local: pushes the prompt + runner to the host and starts the job.
- `scripts/status.sh` — local: reads the job's current status.
- `scripts/logs.sh` — local: tails the job's remote output log.
- `scripts/collect.sh` — local: pulls results back and extracts the REPORT block.

These are a reference implementation — reviewed for correct shell syntax and tested
locally for argument validation, but not exercised end-to-end against a real remote
host (that requires infrastructure this skill can't assume). Read them before trusting
them against a host you care about, and adapt the `claude`/`codex` invocation lines if
your CLI's actual flags differ from what's assumed here.

