Skip to main content
Three commands, three different problems. base handoff is for stopping and picking up again later. base fork is for side-work you want to keep visible without derailing what you are doing now. base relay is for two or more sessions running at the same time and needing to reach each other. Handoffs and forks both surface at the start of a session: the ten newest open handoffs, one per project and lettered A to J, and the newest three forks. They keep appearing until you act on them.
base relay dispose deletes a project’s relay store. It prints what it would remove and changes nothing until you pass --force. Everything else on this page either writes or reads; nothing else here removes data. An archive is never a deletion: unarchive undoes it.

Handoffs

A handoff is a document that says where you stopped and what happens next. Register one when you finish a session, and it is offered back to you when you start the next one. base handoff carries -g / --global on the command itself, before the verb.

base handoff create

Register a document as this project’s handoff.
Creating a handoff archives the earlier open (or deferred) handoff for the same project and the same lane, in every tier. That is the difference from a fork: one lane has one current place to pick up. Other lanes’ handoffs stay open, so several sessions working one project no longer archive each other’s. With no codenames anywhere, everything is one lane and a project keeps one open handoff, as before. The output says what happened after its first line: lane: <name> (from <where>), then archived: <slug> (<tier>) for each one it archived, or archived: nothing, then any handoffs it left open in other lanes. base handoff unarchive undoes an archive.

base handoff show

Find one open or deferred handoff and print its document path.
It takes a letter from the last session start (A to J), a key from base handoff deferred (D1, D2, …), a slug, a project name, or a few words. Inside a session the letter is read from that session’s own session start, so another session starting does not move it. Several matches are listed and none is picked (exit 2); no match exits 1. A deferred match comes back to open, which is the only write it makes.

base handoff deferred

List deferred handoffs: open but paused, so session start does not list them.
Each line carries a key (D1, D2, …) that base handoff show takes, and the command that brings it back. Deferral is off until [defer] enabled = true; see Projects and tasks.

base handoff list

Show open handoffs from the global tier and this workspace together, with the tier each one lives in.

base handoff snooze

Hide a handoff for a number of days.
Both arguments are positional: the slug, then the number of days. Use this when something is real but not now.

base handoff archive

Stop a handoff resurfacing. It is kept, not deleted.

base handoff unarchive

Undo an archive: set an archived handoff back to open, in the tier that holds it.
It prints what changed, for example unarchived docs-pickup (workspace): status archived -> open. When two tiers hold the slug, only the newest copy is reopened. Nothing to reopen exits 1 and writes nothing.

base fork create

Register a build specification as a fork: side-work that stays visible without replacing anything.
Forks are additive. Creating one does not archive its siblings, so several can be open at once and each is picked up by name.

base fork list

Show open forks across both tiers.

base fork snooze

Hide a fork for a number of days.

base fork archive

Stop a fork resurfacing. It is kept, not deleted.

base fork unarchive

Undo an archive: set an archived fork back to open, in the tier that holds it.

base fork show

Find one fork and print its document path.
It takes a key from base fork deferred, a title, a project name or a few words. Several matches are listed and none is picked (exit 2); no match exits 1. A deferred fork it finds comes back to open.

base fork deferred

List deferred forks: open but paused, not listed at session start.
Each line carries a key that base fork show takes.

Relay

Relay is for sessions running at the same time. Each session registers under a stable title, and everything else addresses that title rather than a session id you would have to look up. A message is delivered to the session that held the title when it was sent, and to no other. When a title passes to a new session, the earlier holder’s undelivered messages move to relay-inbox/.archive/<title>-<session>/, and each sender gets a relay: not delivered notice naming who holds the title now. A ping that waits more than a day undelivered is archived the same way. In the hooks, relay is information, never an order: a new message is shown once, on the next prompt, with who sent it, when, and the command to answer it. It never appears on a tool call, and an unanswered one is listed in one line at session start. The store is per project and deliberately disposable. It is a working surface for a milestone, not a permanent record.

base relay init

Create the relay store for a project.

base relay register

Give this session a stable title, so other sessions can address it.
Register early. Until a session has a title, nothing can be sent to it by name. --project names a project’s relay store. When no store of that name exists, the command says it registered the title globally only, so it is not on base relay board, and tells you to run it with no --project to join this workspace’s store. When the title has no inbox watcher running the current script, it also prints what base relay arm prints.

base relay arm

Print what to start this session’s inbox watcher with.
It prints the fields for Claude Code’s Monitor tool (description, command, timeout_ms, which is the host’s maximum of 30 minutes), the step to run when the Monitor reports it expired (run base relay arm again), and the status-line and register steps. A session whose title is in use and has no watcher gets one line in its hooks, once, pointing here: relay: <title> has no inbox watcher · run base relay arm and start the Monitor it prints. “In use” means the session sent or received a ping, or registered its title by hand. base config set relay.wake_nudge false turns that line off.

base relay send

Send a typed message to a session, a title, a phase, or everyone.

base relay poll

Read pending messages without blocking. Reading them consumes them.

base relay wait

Block until a matching message arrives. This costs no tokens while it waits, which is what makes it better than polling in a loop.

base relay claim

Take an advisory claim on a path or a phase, so other sessions can see you are working there.
Claims are advisory. Nothing enforces them, and a claim that expires simply stops appearing. The point is that base relay board shows who is where before two sessions edit the same file.

base relay release

Give a claim back.

base relay board

The operator view: every session, whether it is alive, what it has claimed, and how many messages are waiting for it.

base relay export

Write the current spool out as inbox.nq, a read-only snapshot.
Do this before base relay dispose if you want to keep any of it.

base relay dispose

Destructive. Preview by default. Tear down a project’s relay store at the end of a milestone.

base relay task

Hand a briefed task to another live session. It keeps firing in that session until it is picked up, and it crosses workspaces through the global tier.
A task is the right shape when there is a document behind it. If everything you need to say fits in three sentences, send a ping instead.

base relay ping

Send an instant message to a live titled session. No document, no completion ceremony. It is shown in the receiver’s next prompt, or at once by its inbox watcher, and their reply ping clears it.
Keep a ping to a sentence or three. More than that is a task, and sending it as a ping means the context has nowhere to live afterwards.

base relay done

Mark a relayed task finished, which clears the alert in the receiving session and closes its record in the graph.

base relay tasks

List inbound relay tasks and pings across every live session, each with its message.

base relay sessions

List every titled session in the global registry, with liveness.
Check this before sending a task. A title that is not listed here has nothing behind it, and the task will sit unread.