How wsp runs each agent
wsp does not include an agent of its own. A thread runs one of four coding agents through that agent's own command line: Claude Code, Codex, OpenCode or Cursor. An adapter in wsp starts the command, reads what it prints and answers its questions. This page shows the command each adapter starts and how the parts of a thread map to it.
The catalog knows other agents too: Amp, Crush, Gemini CLI, Goose, Hermes Agent, Pi and Qwen Code. wsp can install them and give them the wsp skill, but it has no adapter for them, so they cannot run threads.
What every turn gets
Each command starts in the thread's folder: the project's folder, or a worktree of it.
Each turn's environment carries these wsp variables:
WSP_TURNis a random token for this one turn.WSP_HOST_TOKENis a token for this thread, which the host takes back when the turn's process ends.WSP_HOST_URLandWSP_HOST_KEYsay where the host is and which key it proves, for a turn on the computer that the app runs on. The URL is the host's own loopback address. A turn on a box gets neither, because itswspreaches the host through the daemon's link.
So a wsp command that the agent runs, such as wsp run --notify me, acts as this thread.
Claude Code and Codex also get the wsp tools in the launch, as an MCP server. On the computer that the app runs on, the server is wsp mcp --state <state> --scoped. On a box, the server is wsp mcp there, a client in the daemon that carries each call up the daemon's link. The host's own server answers it. A turn on a box gets the tools only when the box's daemon reports that this client is ready, which an older daemon does not. A thread that another thread started also gets --no-slate, because it has no slate. OpenCode and Cursor get no wsp tools.
The agent reads and writes its own session files where it always does. On the computer that the app runs on, these are your own files, for example ~/.claude/projects and ~/.codex/sessions. On a box, wsp points each agent's own variable, CLAUDE_CONFIG_DIR for Claude Code and CODEX_HOME for Codex, at the folder that it keeps for that agent there. wsp copies nothing for a turn.
You can set your own program or arguments for an agent on a computer. Your program then takes the place of the command's name. Your arguments come after the subcommand or the print flag, for example after claude -p or codex app-server.
Where the process runs
- On the computer that the app runs on, the turn runs as you. The Claude Code and Codex processes stay up between turns.
- On a box, the turn runs as the login that the box was added with, in the thread's own cgroup. wsp's own folder is first on the
PATH. That login must be root for now. A box has no worktrees yet. The process ends with each turn.
Access
wsp has four access words, the same for every agent. Each agent maps them to its own modes. An agent with no mode for a word refuses it and names the words that it takes.
| wsp word | Claude Code | Codex | OpenCode | Cursor |
|---|---|---|---|---|
ask | default | workspace-write | none | none |
auto-edit | acceptEdits | none | none | none |
full | bypassPermissions | danger-full-access | auto | force |
plan | none | read-only | none | default |
Claude Code
claude -p --input-format stream-json --output-format stream-json --verbose \
--permission-mode default --permission-prompt-tool stdio \
--model <model> --effort <effort> --name <title> \
--mcp-config '<json>' --settings '<json>' \
--session-id <uuid>
- The message goes in on stdin as a stream-json line. Images go in the same line.
- With
fullaccess, the command has--dangerously-skip-permissionsin place of--permission-mode. It keeps--permission-prompt-tool stdio, so a question from the agent still reaches you. - A thread with a slate also gets
--append-system-promptwith the slate's brief. - A permission question comes out on stdout as a control request. Your answer in the app goes back on stdin.
- A message that you send while the turn runs goes in on stdin as one more line. The turn takes it at its next tool round.
- A later turn resumes with
--resume <uuid>. After a rewind, it resumes with--resume-session-at <message>too, which cuts the conversation at that message. - On the computer that the app runs on, the process stays up between turns, so a stop sends it an interrupt request. If the turn does not stop, wsp ends the process. On a box, a stop ends the process at once.
- The access of a running turn can change without a restart.
- wsp removes inherited
CLAUDE_CODE_*variables and sets its own. It signs the turn in withCLAUDE_CODE_OAUTH_TOKEN, the token thatclaude setup-tokenprints, or withANTHROPIC_API_KEY, from the keys file of the host. On the computer that the app runs on, it does not setCLAUDE_CONFIG_DIR, and a value in the host's environment comes through. A host that you start from your shell has your shell's value. The app's service host has only the variables that its unit lists. On a box, it setsCLAUDE_CONFIG_DIRto the folder that it keeps for Claude Code there. - The session file is
<config folder>/projects/<folder>/<uuid>.jsonl. On the computer that the app runs on, Claude Code keys the session file off the turn's folder, as in your own terminal. wsp sets only the memory folder there, with theautoMemoryDirectorysetting. In the project folder and in a worktree that you made, memory takes the key of the repo's main checkout. A worktree that wsp made keys memory off its own folder, so a builder there does not load the notes of the person and of its lead. On a box,CLAUDE_CONFIG_DIRis set, so the session file and memory both take the key that wsp gives.
Codex
codex app-server -c tools.update_plan.enabled=true \
-c mcp_servers.wsp.command=... -c mcp_servers.wsp.args=[...]
- wsp talks to Codex's app server in JSON-RPC over stdin and stdout. It opens the thread with
thread/startorthread/resume, then starts each turn withturn/start. The model, the sandbox and the approval policy go inthread/start. The message, its images and the effort go inturn/start. - A sandboxed mode asks for approval on request. Full access never asks.
- A permission question comes as
item/commandExecution/requestApprovaloritem/fileChange/requestApproval. wsp answers accept or decline for that one action. A reason that you give with a deny goes into the turn as your next message. - A message that you send while the turn runs goes in with
turn/steer. - A stop sends
turn/interrupt. If the turn does not stop, wsp ends the process. - A rewind runs
thread/reverton a separate, read-only app server, which cuts the conversation at that turn. - The wsp tools get
tool_timeout_sec=3600. The slate tools sit in a second server,wsp_slate, whose calls need no approval. - An API key from the keys file goes in as both
CODEX_API_KEYandOPENAI_API_KEY. - The session file is under
$CODEX_HOME/sessions. A rename goes throughthread/name/set.
OpenCode
opencode run --format json --print-logs --log-level ERROR --dir <folder> \
-s <session> -m <provider/model> --variant <effort> --title=<title> --auto
- The message goes in on stdin.
- OpenCode takes only
fullaccess. Its run mode asks nobody, and it refuses every permission question that its own settings raise. So no question reaches you. - A message that you send while the turn runs waits and runs as the next turn.
- A later turn resumes with
-s <session>. The sessions are in~/.local/share/opencode/opencode.db. - A stop ends the process. A rewind puts back the files only.
Cursor
cursor-agent -p --output-format stream-json --stream-partial-output --trust \
--workspace <folder> --model <model> --resume <chat> --force
- The message goes in on stdin. Cursor takes no images.
- Cursor takes the effort as part of the model's name, so wsp does not pass a separate effort.
--forceis there only forfullaccess.- No permission question reaches you.
- A message that you send while the turn runs waits and runs as the next turn.
- The key goes in as
CURSOR_API_KEY, never on the command line. - A stop ends the process. A rewind puts back the files only.
Stop and rewind for every agent
When an interrupt does not end a turn, wsp sends SIGTERM to the turn's process group, then SIGKILL 5 seconds later.
A rewind puts the files back from the checkpoint that the daemon keeps for each turn. If another thread worked in the same folder after that checkpoint, wsp leaves the files alone. Only Claude Code and Codex also cut the conversation.
Next
- The host, the daemon and the relay shows where the host and the daemon run.
- Agents and sign-ins shows how to install and sign in each agent.