CLI reference / Agents
On this page

CLI reference / Agents

Agent commands

Set up a project for Claude Code or Codex, report how a session ended, and print the text agents need.

Most of these commands are for the programs around an agent, not for the agent itself. The runtime runs hook for you. A runner runs session end. A runner is a program that starts agent sessions and sees how each one ended. Read Tell your agents for the setup, step by step.

Each command also takes the global options, such as --session and --json. The CLI reference explains them. adapter install and hook do not offer --runtime, because their own <RUNTIME> argument names the runtime.

handsoff adapter

Groups the adapter commands. It has one, install.

Usage: handsoff adapter [OPTIONS] <COMMAND>

Commands:
  install  
  help     Print this message or the help of the given subcommand(s)

Options:
      --server <SERVER>        
      --workspace <WORKSPACE>  
      --as <HANDLE>            
      --session <SESSION>      
      --runtime <RUNTIME>      
      --model <MODEL>          
      --leg <LEG>              
      --account <ACCOUNT>      
      --json                   
  -h, --help                   Print help

handsoff adapter install

Sets up one project folder so that Claude Code or Codex sessions there work with Handsoff. It adds the standing instruction and the hooks. It keeps your other settings, and it never touches the runtime's global settings. Run it again and nothing changes.

Usage: handsoff adapter install [OPTIONS] --project <PROJECT> <RUNTIME>

Arguments:
  <RUNTIME>  

Options:
      --project <PROJECT>      
      --server <SERVER>        
      --print                  
      --workspace <WORKSPACE>  
      --as <HANDLE>            
      --session <SESSION>      
      --model <MODEL>          
      --leg <LEG>              
      --account <ACCOUNT>      
      --json                   
  -h, --help                   Print help
OptionWhat it does
<RUNTIME>claude-code or codex.
--project <PROJECT>The project folder to set up.
--printWrites no files. Prints the settings as JSON instead. A runner can pass the Claude Code settings to one session.

For Claude Code, it writes hooks and permissions to .claude/settings.local.json and the instruction to CLAUDE.md. For Codex, it writes hooks to .codex/hooks.json and the instruction to AGENTS.md.

handsoff adapter install claude-code --project .
Installed hooks and permissions in …/.claude/settings.local.json; standing instruction in …/CLAUDE.md.
Interactive sessions run no project hook until you answer yes to the folder-trust question.

The tool prints the full path of each file, shortened here with …. For Codex, it prints more lines on how to trust the folder and the hooks. Read them before the first session. Codex and Claude Code explain each runtime's steps.

handsoff hook

Handles one runtime event. The hooks that adapter install writes run this command, with the event's details as JSON on standard input. You do not run it yourself.

Usage: handsoff hook [OPTIONS] <RUNTIME> <EVENT>

Arguments:
  <RUNTIME>  
  <EVENT>    

Options:
      --server <SERVER>        
      --workspace <WORKSPACE>  
      --as <HANDLE>            
      --session <SESSION>      
      --model <MODEL>          
      --leg <LEG>              
      --account <ACCOUNT>      
      --json                   
  -h, --help                   Print help
OptionWhat it does
<RUNTIME>claude-code or codex.
<EVENT>The event: session-start, tool-use, renew, stop, stop-failure, pre-compact or session-end. Codex sends no stop-failure.

At session start, the hook prints the standing instruction and the first lines of your status. Other events count the agent's tool use and renew its leases. At a stop, the hook asks the agent to save first if it did work since its last save. At the end of a session, it ends the session's legs, unless a runner will report the end.

This is what a runtime sends at the start of a new session, and what the hook printed:

echo '{"session_id":"demo-1","source":"startup"}' | handsoff hook claude-code session-start
This machine uses Handsoff, a relay for agent work. When you are asked to continue a piece
of work named in the record, run `handsoff continue <name>` first and work from what it
prints: the baton and what it refers to. Save the baton as you work with `handsoff save`.
Before you stop, offer it to the next carrier with `handsoff offer` or end your leg with
`handsoff end`. Never ask for or read an earlier session's transcript.
The status could not be read; handsoff status shows it.

All the hook's network calls share half a second, so the runtime never waits long. Here the service did not answer in that time. So the hook printed no status lines, and told the agent to run handsoff status.

A hook always exits 0, even when it fails. It writes the reason for a failure to adapter.log in the tool's state folder.

handsoff session

Groups the session commands. It has one, end.

Usage: handsoff session [OPTIONS] <COMMAND>

Commands:
  end   
  help  Print this message or the help of the given subcommand(s)

Options:
      --server <SERVER>        
      --workspace <WORKSPACE>  
      --as <HANDLE>            
      --session <SESSION>      
      --runtime <RUNTIME>      
      --model <MODEL>          
      --leg <LEG>              
      --account <ACCOUNT>      
      --json                   
  -h, --help                   Print help

handsoff session end

Reports how a session ended, after its process exits. The service then ends every live leg of that session among your handles. A runner uses it, because a runner sees the session's final result. Name the session with --session.

Usage: handsoff session end [OPTIONS] --reason <REASON>

Options:
      --reason <REASON>        [possible values: clean, limit, crash, killed, other]
      --server <SERVER>        
      --cause <CAUSE>          
      --workspace <WORKSPACE>  
      --as <HANDLE>            
      --note <NOTE>            
      --session <SESSION>      
      --runtime <RUNTIME>      
      --model <MODEL>          
      --leg <LEG>              
      --account <ACCOUNT>      
      --json                   
  -h, --help                   Print help
OptionWhat it does
--reason <REASON>How the session ended. The list below says what each reason means.
--cause <CAUSE>The cause the runtime reported, such as its error. The history shows it.
--note <NOTE>A short note to keep with the end.

The reasons:

  • clean: the runner checked that the session succeeded.
  • limit: the runtime reported a usage limit.
  • crash: the runtime reported a failure.
  • killed: the runner stopped the process.
  • other: the result cannot tell.

The tool turns clean into other when the session did work after its last save, or when it cannot tell.

handsoff open BILL-45 --title "Archive the 2024 invoices" --as build-agent --session run-7 --baton baton.md
Opened BILL-45 at r1 (work 66)
Leg 127; lease expires 2026-10-05T05:00:30.854079+00:00
handsoff session end --session run-7 --reason limit --cause "usage limit reached"
Ended billing / BILL-45 (leg 127): limit

The tool prints one line for each leg it ended, or says that no live leg matched.

handsoff instructions

Prints the standing instruction for agents. Add it where each agent reads its standing instructions. It needs no sign-in.

Usage: handsoff instructions [OPTIONS]

Options:
      --server <SERVER>        
      --workspace <WORKSPACE>  
      --as <HANDLE>            
      --session <SESSION>      
      --runtime <RUNTIME>      
      --model <MODEL>          
      --leg <LEG>              
      --account <ACCOUNT>      
      --json                   
  -h, --help                   Print help

This command has no options of its own.

handsoff instructions
This machine uses Handsoff, a relay for agent work. When you are asked to continue a piece
of work named in the record, run `handsoff continue <name>` first and work from what it
prints: the baton and what it refers to. Save the baton as you work with `handsoff save`.
Before you stop, offer it to the next carrier with `handsoff offer` or end your leg with
`handsoff end`. Never ask for or read an earlier session's transcript.

handsoff checks

Lists the checks that Handsoff runs on every piece of text you send. It refuses text that looks like a secret or a transcript, or that holds control characters. It needs no sign-in.

Usage: handsoff checks [OPTIONS]

Options:
      --server <SERVER>        
      --workspace <WORKSPACE>  
      --as <HANDLE>            
      --session <SESSION>      
      --runtime <RUNTIME>      
      --model <MODEL>          
      --leg <LEG>              
      --account <ACCOUNT>      
      --json                   
  -h, --help                   Print help

This command has no options of its own.

handsoff checks
sk-ant: API token beginning sk-ant-
sk: API token beginning sk-
ghp: Source token beginning ghp_
gho: Source token beginning gho_
github-pat: Source token beginning github_pat_
glpat: Source token beginning glpat-
xox: Chat token beginning xox plus a letter and dash
cloud-access: AKIA followed by sixteen uppercase letters or digits
cloud-api: AIza followed by thirty-five token characters
private-key: Private key block header
signed-token: Three-part signed token with two eyJ segments
bearer: Bearer followed by a long token
url-credentials: User and password inside a URL
secret-assignment: Secret-named assignment with at least twelve characters and 3.5 bits character entropy, excluding references
json-transcript: JSON array of objects containing role and content
speaker-transcript: Different labelled speakers within twelve lines
controls: C0 except tab/newline, DEL, C1, bidi overrides and isolates
These checks catch common shapes, not every secret.

When a check refuses your text, the refusal names the field, the line and the check. It never repeats the text it matched. Name where a secret lives instead of the secret itself.