Prized docs

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.

Prompt the agent

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 as they happen, and exits when the agent is done. Nothing runs in a tmux session and nothing is installed on the box beyond three small helper scripts on the first prompt.

CommandWhat 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 a fresh one.
prized prompt --provider claude --auto "…"Let the agent edit and run commands without approvals. See 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 lsEvery run on the box, newest first (at most 50), with its state.
prized events --followFollow the run in progress (or show the newest); --run pr_… picks one, --after N starts after event N.
prized interruptStop 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 (prompt.txt), never on a command line, so it does not show up 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

The agent runs as you, on the box, with the sign-in already there. Before the first prompt, hand your credentials over:

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; the interactive alternative is Agents.

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 a prompt like "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 your synced projects in reach, for as long as the run lasts. Use it for work you would let the agent do unattended, and interrupt it when it strays.

Continuity

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

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 instead and runs as soon as the current run ends, continuing its session. Two commands exist on the box itself for this, so a setup script or any shell there can drive the agent:

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

queuePrompt appends to the queue (from its arguments, or from stdin with none); stopAgent interrupts the run in progress. Both are installed to ~/.prized/bin on the first prompt, with a line in ~/.profile that puts them on the PATH of login shells. 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 (or queue: true) keeps its own provider, model, effort, working directory and --auto; one queued with queuePrompt inherits them from the run it follows. A queued prompt with --continue continues its provider's newest session as of the moment it runs (nothing to continue is recorded as a failed run, the reason in its stderr). Without --continue, a queued prompt of the same provider as the run it follows continues that run's session (or, when that run never named one, the session it was itself continuing); a different provider starts fresh.

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.txtThe prompt as given.
meta.jsonProvider, model, reasoning effort, and whether --auto was on.
cmd, nextThe provider command line for this run, and the one a continuation uses.
cwd, pid, started_at, exitThe working directory, the process group id, the start time, the exit code when done.
events.jsonlThe provider's raw event stream (claude --output-format stream-json, codex exec --json), appended as it happens.
stderr.logThe provider's stderr.
sessionThe provider's session or thread id, once seen.
resume, parentFor a continued run, the session it resumed; for a queued one, the run it followed.
interruptedPresent 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 (prompt.txt, plus the request's own meta.json, cmd, next and cwd when it was queued from the CLI or the API).

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 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.

{"seq": 7, "type": "tool_use", "text": "Let me run the suite.", "tool": {"name": "Bash", "input": {"command": "npm test"}}, "raw": {}}
FieldMeaning
seqThe event's line number in events.jsonl, from 1. Paging and --after use it; a page holds up to 200 events or 1 MiB, whichever comes first, and always at least one.
atThe provider's timestamp when the line carries one.
typesystem, assistant, tool_use, tool_result, result, error, or raw for a line the mapping does not know.
textThe readable content: the agent's text, a command, a tool's output, the final answer, an error (capped at 8 KiB).
toolFor tool events, {name, input}; Codex's are command_execution, file_change, mcp_tool_call (server/tool), web_search.
rawThe 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 same surface is HTTP, for scripts and agents that hold a CLI token and have no prized installed. The token and base URL are found as for running commands:

export PRIZED_TOKEN=dcp_…
EDGE=$(curl -s -H "Authorization: Bearer $PRIZED_TOKEN" https://api.prized.dev/api/v1/me | jq -r .edge.url)
RouteBody or queryAnswer
POST /prompts{provider, prompt, model?, reasoningEffort?, cwd?, continue?, queue?, auto?}202 prompt.started: run (as above, status: running), or 202 prompt.queued: queued, active
GET /promptsprompt.list: runs[] newest first (at most 50), active (the id in progress, or null)
GET /prompts/{runId}prompt.status: run with the full prompt, stderr (last 4 KiB), stderrTruncated
GET /prompts/{runId}/events?after=&limit=after (a seq, default 0), limit (1 to 1000, default 200; a page also stops at 1 MiB)prompt.events: run, events[], next, finished; pass next as the following after
GET /prompts/{runId}/events?follow=1or Accept: text/event-streamServer-Sent Events: event: prompt per event, then event: done with {run, next} when the run has ended
POST /prompts/{runId}/interruptprompt.interrupted: id, wasRunning, signal (TERM, or KILL when TERM was not enough)
POST /prompts/interruptThe same, for the run in progress

Every route is under $EDGE/v1/box/{box}/ with the token as the bearer. POST /prompts wakes a suspended box; the others answer box_not_running.

# start a run and follow it as SSE
curl -s -X POST "$EDGE/v1/box/box-a7f3/prompts" -H "Authorization: Bearer $PRIZED_TOKEN" -H "Content-Type: application/json" -d '{"provider":"claude","prompt":"fix the failing tests","cwd":"app"}'
curl -sN "$EDGE/v1/box/box-a7f3/prompts/pr_3f9c0a1b2d4e/events" -H "Authorization: Bearer $PRIZED_TOKEN" -H "Accept: text/event-stream"

# or page through the events, then continue the conversation
curl -s "$EDGE/v1/box/box-a7f3/prompts/pr_3f9c0a1b2d4e/events?after=0&limit=200" -H "Authorization: Bearer $PRIZED_TOKEN" | jq '.events[] | select(.type=="assistant") | .text'
curl -s -X POST "$EDGE/v1/box/box-a7f3/prompts" -H "Authorization: Bearer $PRIZED_TOKEN" -H "Content-Type: application/json" -d '{"provider":"claude","prompt":"now update the docs","continue":true}'

# stop whatever is running
curl -s -X POST "$EDGE/v1/box/box-a7f3/prompts/interrupt" -H "Authorization: Bearer $PRIZED_TOKEN"

Errors

A failed request answers {"ok": false, "error": {"code", "message"}}. On top of the shared codes (unauthorized, not_found, box_not_running, invalid_path, payload_too_large, rate_limited, box_unreachable, exec_failed), these routes add:

HTTPerror.codeMeaning
400invalid_providerprovider is not claude or codex.
400prompt_requiredprompt is missing or blank.
400invalid_requestA bad model shape, reasoningEffort outside low/medium/high, a newline in cwd, bad JSON.
409prompt_in_progressA run is in progress; the message names it. Queue behind it, or interrupt it.
409provider_not_signed_inThe provider has no sign-in on the box; run prized agents handoff <provider>.
409provider_not_installedThe provider's CLI is not on the box's login PATH.
409no_session_to_continuecontinue: true with no earlier run of the provider that recorded a session.

From the CLI these are exit 6 (CONFLICT) for a run in progress and exit 5 (CHECK_FAILED) with the hint for the rest.

Limits

WhatLimit
Runs in progress per box1 (others queue or are refused)
Prompt size512 KiB
Events per page200 by default, 1000 at most, or 1 MiB, whichever first (one event of any size is always delivered; a single event over 32 MiB cannot be)
Runs listed50, newest first (older directories stay on the box)
Event text8 KiB (the raw line is whole)
Requests per token, per boxAs for the edge API

Compared with prized agents run

prized agents run starts the agent interactively in a tmux session you attach to: it asks you for approvals, you type into it, and it stays open. 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 both keep working when your laptop is closed.

Something unclear or out of date?

On this page