# Prompt an agent remotely

> Send Claude Code or Codex on your box a prompt from your machine or from any script, follow what it does as it happens, and interrupt it. The run lives on the box, not in a terminal, so nothing depends on your laptop staying open.

URL: https://prized.dev/docs/remote-agents

## Prompt the agent [#prompt-the-agent]

```bash
prized prompt --provider claude "fix the failing tests in app/ and run them again"
```

This starts a headless run of Claude Code on the box (`claude -p`, in your home directory), streams its events to your terminal, and exits when the agent is done. Nothing runs in a tmux session; the first prompt installs three small helper scripts on the box and nothing else.

| Command                                                          | What it does                                                                                               |
| ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `prized prompt --provider claude "…"`                            | Run Claude Code on the default box and follow it. `--provider codex` runs Codex.                           |
| `prized prompt box-a7f3 --provider codex --cwd app "…"`          | Run on a named box, in `~/app` (`--cwd` is relative to your home, or absolute).                            |
| `prized prompt --provider claude --model opus --effort high "…"` | Pick the model and the reasoning effort (`low`, `medium`, `high`).                                         |
| `prized prompt --provider claude --continue "…"`                 | Continue the provider's newest session on the box instead of starting fresh.                               |
| `prized prompt --provider claude --auto "…"`                     | Let the agent edit and run commands without approvals. See [Approvals](#approvals).                        |
| `prized prompt --provider claude --detach "…"`                   | Start the run and print its id; follow it later with `prized events`.                                      |
| `prized prompt --provider claude --queue "…"`                    | When a run is in progress, queue this prompt behind it instead of refusing.                                |
| `cat brief.md \| prized prompt --provider claude -`              | Read the prompt from stdin.                                                                                |
| `prized prompt ls`                                               | Every run on the box, newest first (at most 50), with its state.                                           |
| `prized events --follow`                                         | Follow the run in progress (or show the newest); `--run pr_…` picks one, `--after N` starts after event N. |
| `prized interrupt`                                               | Stop the run in progress (TERM to its process group, KILL after 5 s); `--run pr_…` stops a specific one.   |

* Output: the agent's text plainly, each tool call and result as one dim line, and a last line with the run's verdict and event count; `-v` adds the provider's system events.
* Exit code: 0 when the run ends cleanly, 1 when the provider reports an error, exits non-zero, or the run was interrupted, 130 on Ctrl-C, which also interrupts the run on the box (`prized events --follow` leaves the run alone on Ctrl-C).
* The prompt travels to the box as a file, never on a command line, so it is not in the box's process list or shell history. A suspended box wakes for `prized prompt`; `prized events`, `prized prompt ls` and `prized interrupt` do not wake one.

## Sign in first [#sign-in-first]

The agent runs as you, on the box, with the sign-in already there: hand your credentials over once with `prized agents handoff claude codex`. `prized prompt` refuses with `provider_not_signed_in` when the box has no sign-in for the provider (Claude Code: `~/.claude/.credentials.json` or `CLAUDE_CODE_OAUTH_TOKEN` in a login shell; Codex: `~/.codex/auth.json`). What travels is in [Credentials](https://prized.dev/docs/credentials); the interactive alternative is [Agents](https://prized.dev/docs/agents).

## Approvals [#approvals]

By default the agent can edit files but not act freely: Claude Code runs with `--permission-mode acceptEdits` (commands it wants to run are denied, since a headless run cannot ask you), and Codex runs in its `workspace-write` sandbox. `--auto` lifts both (`claude --dangerously-skip-permissions`, `codex --dangerously-bypass-approvals-and-sandbox`), which is what "run the tests and fix them" needs.

> `--auto` means no approvals at all: the agent runs any command and edits any file your account on the box can, with your credentials and synced projects in reach. Use it for work you would let the agent do unattended, and interrupt it when it strays.

## Continuity [#continuity]

Every run records the provider's session id, and `--continue` starts the next run with `--resume <that id>` (Claude Code) or `codex exec resume <id>` (Codex), so "now also update the docs" works; the newest session of the same provider on the box is the one continued, and `prized prompt ls --json` shows each run's `sessionId` and `resumedFrom`. With no earlier session on the box, `--continue` refuses (exit 5, `no_session_to_continue` on the API) rather than quietly starting fresh.

## One run at a time, and a queue [#one-run-at-a-time-and-a-queue]

A box runs one prompt at a time. A second `prized prompt` while one is in progress answers `prompt_in_progress`; with `--queue` the text is queued and runs as soon as the current run ends, continuing its session. Two commands on the box itself do the same, so a setup script or any shell there can drive the agent:

```bash
queuePrompt "then run the linter and fix what it finds"
stopAgent
```

`queuePrompt` appends to the queue (from its arguments, or stdin); `stopAgent` interrupts the run in progress. Both live in `~/.prized/bin`, on the PATH of login shells after the first prompt. A queued prompt with no run in progress waits for the next `prized prompt` to finish; an interrupted run does not drain the queue.

A prompt queued with `--queue` keeps its own provider, model, effort, working directory and `--auto`; one queued with `queuePrompt` inherits them from the run it follows. A queued prompt of the same provider continues the session of the run it follows (with `--continue`, the provider's newest session when it runs); a different provider starts fresh.

## Where a run lives on the box [#where-a-run-lives-on-the-box]

Everything about a run is a directory on the box, so it survives a pause, rides a snapshot, and can be read with `ls` and `tail -f`:

| File in `~/.prized/prompts/<run id>/` | Contents                                                                                                                 |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `prompt.txt`, `meta.json`             | The prompt as given; provider, model, reasoning effort, and whether `--auto` was on.                                     |
| `cmd`, `next`                         | The provider command line for this run, and the one a continuation uses.                                                 |
| `cwd`, `pid`, `started_at`, `exit`    | The working directory, the process group id, the start time, the exit code when done.                                    |
| `events.jsonl`, `stderr.log`          | The provider's raw event stream (`claude --output-format stream-json`, `codex exec --json`) and its stderr.              |
| `session`, `resume`, `parent`         | The provider's session id once seen; for a continued run, the session it resumed; for a queued one, the run it followed. |
| `interrupted`                         | Present when the run was stopped through `prized interrupt` or `stopAgent`.                                              |

`~/.prized/prompts/active` names the run in progress; `~/.prized/prompts/queue/` holds queued prompts, one directory each.

> Run directories are never deleted for you. `rm -r ~/.prized/prompts/pr_…` on the box when you are done with one.

## JSON and JSON Lines [#json-and-json-lines]

`--json` on `prized prompt` prints the started run as one object and does not follow. `--jsonl` follows and prints one normalized event per line: this is the one command, with `prized events --jsonl`, that prints more than one JSON document, because a live stream has no end to wait for.

```json
{"seq": 7, "type": "tool_use", "text": "Let me run the suite.", "tool": {"name": "Bash", "input": {"command": "npm test"}}, "raw": {…}}
```

| Field  | Meaning                                                                                                                          |
| ------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `seq`  | The event's line number in `events.jsonl`, from 1; paging and `--after` use it (a page holds up to 200 events or 1 MiB).         |
| `at`   | The provider's timestamp when the line carries one.                                                                              |
| `type` | `system`, `assistant`, `tool_use`, `tool_result`, `result`, `error`, or `raw` for a line the mapping does not know.              |
| `text` | The readable content: the agent's text, a command, a tool's output, the final answer, an error (capped at 8 KiB).                |
| `tool` | For tool events, `{name, input}`; Codex's are `command_execution`, `file_change`, `mcp_tool_call` (`server/tool`), `web_search`. |
| `raw`  | The provider's line as written.                                                                                                  |

A run object (`prized prompt --json`, `prized prompt ls --json`, `prized events --json`) has `id, provider, model, reasoningEffort, auto, status (running, done, failed, interrupted), exitCode, pid, cwd, startedAt, finishedAt, sessionId, resumedFrom, parent, eventCount, prompt`.

## The edge API [#the-edge-api]

The same surface is HTTP for scripts that hold a CLI token: `POST /prompts` starts or queues a run, `GET /prompts` lists them, `GET /prompts/{runId}/events` pages the events or streams them as Server-Sent Events (`follow=1`, or `Accept: text/event-stream`; a stream holds one of the token's concurrent request slots until the run ends), and `POST /prompts/{runId}/interrupt` stops one. Every route is under `$EDGE/v1/box/{box}/` with the token as the bearer, found as for [running commands](https://prized.dev/docs/exec#the-edge-api); only `POST /prompts` wakes a suspended box. Routes, bodies and answers are on [API reference: Prompts and events](https://prized.dev/docs/api#prompts-and-events).

## Errors [#errors]

A failed request answers `{"ok": false, "error": {"code", "message"}}`. On top of the shared edge codes, these routes add `invalid_provider`, `prompt_required`, `invalid_request`, `prompt_in_progress`, `provider_not_signed_in`, `provider_not_installed` and `no_session_to_continue`, described on [API reference: Errors](https://prized.dev/docs/api#errors). From the CLI a run in progress is exit 6 (`CONFLICT`) and the rest exit 5 (`CHECK_FAILED`) with the hint.

## Limits [#limits]

Every cap for prompts, runs, and events is on [Limits](https://prized.dev/docs/limits#prompting-an-agent-remotely).

## Compared with `prized agents run` [#compared-with-prized-agents-run]

[`prized agents run`](https://prized.dev/docs/agents) starts the agent interactively in a tmux session you attach to and approve things in. `prized prompt` is the headless form: one prompt in, a stream of events out, a verdict at the end, and an API for scripts. Both use the same sign-in on the box and keep working when your laptop is closed.
