Your agents / Codex
On this page

Your agents / Codex

Codex

The Codex adapter connects Codex sessions to Handsoff. It works like the Claude Code adapter, with a few limits that come from Codex itself. This page shows how to install it and what it cannot do.

Before you start

Put the tool on your PATH (Install) and sign in on the machine (Sign in).

The examples use the workspace billing from Your first relay, with its agent handle build-agent. They run in a project folder called my-project. BILL-61, in the take-over example, is work that build-agent opened in an earlier Codex conversation, with the baton.md file from Your first relay. Work names are used once in a workspace, so if BILL-61 already exists in yours, use a new name.

Install the adapter

Run this from the project folder that Codex works in:

handsoff adapter install codex --project .
Installed hooks in …/my-project/.codex/hooks.json; standing instruction in …/my-project/AGENTS.md.
Trust the folder first: answer "Trust this folder?" in the interactive runtime, or set [projects."<dir>"] trust_level = "trusted" in the CODEX_HOME a runner uses.
Then trust the hooks ("Hooks need review" / "Trust all and continue") or pass --dangerously-bypass-hook-trust, which replaces hook trust only. An untrusted codex exec runs no hook and says nothing.
For the session's own handsoff commands use: -c sandbox_workspace_write.network_access=true -c 'sandbox_workspace_write.writable_roots=["…/.config/handsoff","…/.local/state/handsoff"]'
Hooks run outside the sandbox; only the session's own handsoff commands need these settings.
…

The tool prints three more lines after these. The sections below say what they mean. Run it again and nothing changes. Both files stay the same, byte for byte.

What it writes

The adapter writes two files in the project and nothing else:

  • AGENTS.md gets the standing instruction, the paragraph that handsoff instructions prints. If the file is new, it holds only the instruction. If it already holds the instruction, the adapter leaves it alone. Otherwise the adapter adds the instruction at the end, after a blank line.
  • .codex/hooks.json gets six hooks. The adapter keeps any hooks that are already there.

It never reads or changes your Codex config.toml, its notify command, or anything in your Codex home folder. It adds no permission lines.

The hooks

Each hook runs handsoff hook codex <event> and has a three-second time limit:

Codex eventCommandWhat it does
SessionStarthandsoff hook codex session-startPrints the standing instruction and the first lines of handsoff status. After a resume or a compaction, it also prints the baton of work the session holds.
PreToolUsehandsoff hook codex tool-useCounts each tool the agent uses since its last saved baton.
PostToolUsehandsoff hook codex renewRuns in the background and renews the lease, at most once a minute.
Stophandsoff hook codex stopStops the agent from stopping once if it has unsaved work, and asks it to save.
PreCompacthandsoff hook codex pre-compactRecords that the session compacted its context.
SessionEndhandsoff hook codex session-endEnds the session's hold on its work, with the reason other.

At session start the agent sees the same text as in Claude Code. Claude Code shows it.

Trust the folder and the hooks

Codex runs a project's hooks only after you trust them, in two steps:

  1. Trust the folder. In an interactive window, answer "Trust this folder?" with yes.
  2. Trust the hooks. Codex shows "Hooks need review". Choose "Trust all and continue".

If you skip a step, the hooks do not run. An untrusted codex exec runs no hook and says nothing about it. A program that starts Codex for you trusts the folder in its own Codex settings, with trust_level = "trusted". It can then pass --dangerously-bypass-hook-trust in place of the second step. That flag does not trust the folder.

The sandbox

Codex runs the agent's own commands in a sandbox. The hooks run outside it, so they need nothing. But the agent's own handsoff commands need two things the sandbox blocks: the network, and write access to the tool's config and state folders.

The install prints the two -c flags that allow exactly that, with your folders filled in. It shows them as … above. Start Codex with them. The adapter writes no sandbox settings for you.

What Codex cannot do

Codex gives its hooks less than Claude Code does. So some things work differently:

  • No clean end. Codex tells its hooks nothing about why a session ended. So the adapter ends every leg other, even after a normal exit. A leg is one carrier's stretch on the work. Only a program that started the session can end it clean, with handsoff session end. Other runtimes shows how.
  • No usage limits. Codex does not tell hooks about a usage limit or a failed request. A limit shows in the record as a lease that ran out, or as an other end.
  • No session variables. Codex has no way for a hook to set variables for the session. The agent's handsoff commands find the session from Codex's own thread id instead.

One background process for every window

In its default interactive mode, Codex runs every window's conversations in one shared background process. This changes two things.

First, /clear and /new do not end the earlier conversation's hold at once. It ends when Codex sends its own late session end, or when the lease runs out. To get the work back at once, catch it from the new conversation with --take-over. The tool reads the new conversation's id from Codex by itself:

handsoff continue BILL-61 --as build-agent
Your handle holds this work in another session; use --take-over.
invalid: the requested operation needs correction; fix: use handsoff continue --take-over, or wait for the lease to lapse
handsoff continue BILL-61 --as build-agent --take-over
Caught BILL-61 at r3 from build-agent via take-over
…

The first command shows what you get without --take-over. The take-over ends the old conversation's leg and starts a new one here. The tool then prints the baton and the warning it gives after any interruption. After an interruption explains that warning.

Second, a variable you set when a window starts does not reach that window's session. This includes HANDSOFF_HANDLE. The session uses the background process's variables, from whichever window started that process. So either:

  • set the handle in the tool's config.json file, under the key handle, or
  • start Codex with --no-daemon, so it runs on its own and uses your window's variables.

Any -c flag also makes Codex run on its own, including the two sandbox flags above.

When Codex runs on its own, such as codex exec, a new conversation in the same process ends the earlier conversation's legs other at once. The note on each says "runtime started another conversation in the same process".

For one session only

--print writes no files. It prints the same hooks as JSON instead.

Remove it

There is no command to remove the adapter. Remove it by hand:

  1. In .codex/hooks.json, delete each hook whose command starts with handsoff hook codex. If the adapter made the file and you added nothing to it, delete the file.
  2. In AGENTS.md, delete the paragraph that starts "This machine uses Handsoff".

Your sign-in and the work in the record stay as they are.