Sessions
A session owns its conversation, model, permission posture, workspace and running work. Every session starts with its own crew. The background daemon hosts the sessions, while the chat and the Session Concourse display them. The daemon outlives whichever window started it: close that window and it passes to another that is still open, so the sessions your other windows hold keep their runners. It shuts down only when the last window closes, and parks every session on its way out so the next boot brings them back. mercury daemon stop parks the sessions it ends the same way, and the next start reads them as parked and leaves their crewmates where they were.
The daemon waits for a runner to finish starting, however slow or busy the machine is, and a session whose first runner died before it wrote anything restarts on its own id. The runner restarted line after a restart is a system notice. A chat whose daemon has gone says so within seconds, and the next prompt starts a new daemon.
Session views
- Focused chat: The session displayed by the current terminal. Changing focus moves that terminal's focus record to the selected session.
- Live row: A session with a runner on the Session Concourse. Its NOW cell shows the reply's last line or the tool the session is running.
- Parked row: A chat with no runner, touched within the last week. The board lists at most ten, newest first, and counts everything older into one last line,
N older chats · ↵ to browse, which expands the list in place.Enteron a parked row shows its transcript and admits the same durable session through the daemon. - NEEDS YOU: A runner that crashed stays on the board with its reason. The user's next act on the session clears the mark, and only a release removes the row.
In the compact layout, the line under the composer counts the session's samples.
The board shows the current project's sessions. Each other project with activity gets one line under OTHER PROJECTS, such as N running in foo, and Enter on it switches the view to that project. At most three such lines show, a line for the rest opens the project picker, as Ctrl+G does, and the NEEDS YOU rail lists every open question whichever project asked it.
Oculus and headless sessions
Every session is hosted by the daemon as a runner and is one of two kinds, decided once when the daemon admits the session from who asked for it and stamped on the session's record and runner:
- Oculus: An interactive session a screen belongs to (
New Session,--chat, a resume, or a session launched from the board's composer). Switching away to another session and coming back does not change its kind. The model is told in one line that you are on the screen and may be away for a while, so a slow answer does not mean nobody is there. Permission asks and questions from an oculus session wait for the screen without timing out in every permission mode until you answer or end the session (MERCURY_PERMISSION_ASK_EXPIRY_MINUTESnever applies to it), and a turn that ends on a question waits on the screen for your answer. - Headless: An unattended session with no screen (
mercury runfrom a script,mercury runnerunder a script or the SDK, a session started by a schedule in Saturn scheduling, or a session launched by a coordinator). With a host that holds asks, tool approvals and questions travel to the host; with no host, an ask is denied and no question can reach anyone. An unanswered ask expires on its clock (ten minutes in Flow, three in Sovereign; a crewmate's ask ten minutes in every other mode), and a turn that ends on an unansweredAskUserQuestionends with statusblockedand the question quoted on its outcome row (read from the run's recorded asks). On the Session Concourse, a headless session's NOW cell begins withheadless;mercury://seatnames the kind in its posture line,/healthreportsSession kindunder RUNTIME, and a session record without a kind runs as headless until resumed from the screen.
Expired sign-ins
A claude.ai or ChatGPT sign-in is checked once when Mercury opens and
whenever /health runs: a sign-in past its expiry is renewed through its
refresh grant, and one the provider refuses shows as <Family> sign-in expired on the boot screen's Logins row and in /health before a first
prompt is sent. A prompt that still meets an expired sign-in is not lost: the
error line paints, its words come back to the composer, and they are sent
again on their own once /logins lands a credential (or /model moves the
session to a signed-in family) while the composer holds them unchanged.
Create a session
Select New Session on the home screen and press Enter. A blank session opens in the current folder on your default model, with its board row created at the same time.
Creating a session starts an empty conversation. A further New Session action creates another session while the previous one keeps running. On the Session Concourse, Enter on the new-session line at the top of the board starts a session the same way, and m on that line picks the model and effort new sessions start on. The first session in a folder initializes an empty .mercury/ directory and a project card in Mercury's config home; browsing the home screen alone initializes nothing.
A chat you just opened is kept until your first message. An empty background session retires after MERCURY_SESSION_IDLE_RETIRE_MINUTES, ten by default, and its row stays on the board as stopped until you release it; a session created through New Session that has not received your first message is excluded from that timeout without limit, or for the MERCURY_SESSION_NEWBORN_GRACE_MINUTES you set. --title <name> on the command line titles the first session you open.
A session can work in a worktree of its repository: --worktree [name] at launch cuts one, with --multiplex inside a tmux session of its own, and the EnterWorktree tool cuts one mid-session. The worktree lives under the repository’s .mercury/worktrees/ on a branch of its own, cut from the commit the checkout is on; a name of the form #<n> or a pull-request link cuts it from that pull request’s head. It comes ready to build, with node_modules and each vendored pack linked to the checkout’s copies, and workspace.worktree.prepare in settings names a shell command Mercury runs inside every new worktree after git makes it and before any session uses it, for the dependency links and copies a project needs; a failure is named on the row that made the worktree, and the worktree is used anyway. When you choose to remove a session worktree on exit and git worktree remove fails, Mercury reports the path and error (Could not remove <path>: <reason>. Fix the error and try again.) and keeps the worktree record instead of reporting it removed.
Continue the latest conversation
Run mercury -c or mercury --continue to return to the most recent conversation through the same restoration path used by Continue Last Session, which selects only <uuid>.jsonl conversation transcripts (ignoring sidecar files such as .receipts.jsonl and auth-failure husks) and refuses non-UUID session identifiers at the resume door.
Resume a named conversation
Run mercury -r <id|title> with the session’s identifier or title to open its transcript and reconnect the session through the daemon.
The session comes back on its own model and effort unless the command line names --model or --effort; then the launch's choice wins and the resume card says so (when the recorded model cannot start, an interactive resume falls back to the default model with a one-line notice). A resumed session uses the prompt saved in its own record, including when a parked chat returns on a warm runner. With no saved record, it uses the current prompt. A resumed session keeps its title, its agent's name and colour, its permission mode, its worktree record and its pull request link. A runner that died mid-work comes back carrying what it held: each line you typed that the dead runner never read is queued again and runs as the next turn, an agent that had finished is delivered from the notice it left, and an agent still working is relaunched from its own transcript.
The restoration controls are:
/sessions: Shows this project's history except the open conversation, as the recent-session list does after a direct resume, and brings the chosen chat back.awidens the view to all projects.mercury sessions list(also baremercury sessions): Lists this project’s saved sessions from the command line, newest first (breaking ties on the transcript’s recorded time): the session id, when it was last written, its size,livewhen the daemon currently hosts it, and its title or first prompt;--allreads every project and--limit <n>bounds the list. The id is whatmercury --resume <id>reopens andmercury sessions delete <id>removes.mercury sessions delete <id>: Deletes one saved session on purpose (its transcript and sidecar records such as receipts and the resume snapshot) from the command line after a confirmation prompt (--yesfor scripts), while refusing a session the daemon currently hosts or an id that does not exist; nothing in the board deletes a transcript.- Sessions · Projects: Lists sessions above repositories.
Tabjumps between the two, highlighting a repository filters the sessions to it, andEnteron a repository opens its most recent chat or, with no history there, a new session. -w: Runs the session inside a managed worktree.records.retentionDays: The retention sweep, 30 days by default, ages recordings and tool results; a session transcript stays until your own act removes it. Set to0, it stops new transcript and lineage writing. Mercury does not ask for a note for the next session, and the entry page says that no record is kept. Existing records stay on disk.
Copy a reply
/copy puts the last reply on the system
clipboard as the model wrote it, with its line breaks, emoji and right-to-left
text and none of the screen's wrapping or row marks; /copy 2 takes the reply
before it, /copy code the last fenced code block, and ctrl+x y runs /copy
from the composer (with a message focused through shift+up, the same chord
copies that message). The text goes through pbcopy on macOS, clip on
Windows and wl-copy, xclip or xsel on Linux; over SSH, or where none of
those answers, the terminal itself is asked to take it (OSC 52) and the row
says so.
Notes between sessions
A new session receives an entry page with the project’s session history and the last note left for it. When a session ends, Mercury asks the model for one orienting handoff note for the next session. A mercury run ends on the model's final answer and leaves no note; its ledger entry closes without one. When a headless run’s input closes, every monitor and every background shell ends when the session exits, whether persistent is set or not; a process that must stay up after such a run (such as a server another command checks once the run has ended) is a Service started with lifecycle project, which is keyed by the session’s project and outlives the session that started it. A session killed mid-tool has its lineage ledger row reconciled as interrupted at the next session start in the project (while any still-running session is left untouched), and the entry page reports that the last session was cut off mid-tool with the time and that no note was left. When leaving Mercury (/exit or Ctrl+C/Ctrl+D), a clean session ends on the farewell line alone; the tester report link (https://mercury-cli.ai/report) is shown once per session only after a session in which a tool call failed or a turn ended on an error. You can read the lineage and its notes in /memory; Memory explains the entry page, journal and settings.
Long conversations and compaction
By default, automatic compaction starts 20,000 tokens before the usable context edge, with proportional room preserved for small local windows. The context gauge, warning and ContextLeft tool count down to the same point from the request’s own view.
Mercury sends every tool result whole: nothing is pruned before a summary. When the estimated context reaches the automatic compaction threshold:
- Summary first: Compaction runs with the complete history in front of the summariser and writes the summary before any pruning happens, including a record of the compacted user turns, the tool calls by name and count, how many failed, the compacted part of a turn that continues below, and the files those tools touched as paths to re-read. A cancelled or failed compaction keeps the original context whole and says so.
- Preserved messages and rounds: The ten most recent complete rounds stay when they fit under the window, along with your own messages from the compacted stretch word for word and a bounded index of its tool receipts (while every receipt stays whole in the boundary record).
- Memory retirement and boundary receipt: When memory is on, the run’s state moves to project memory with a read-back pointer, the tools the session loaded in full (
ToolSearch) carry across the compaction as loaded in full on every provider, and the compaction boundary row shows an exact receipt naming the rounds kept, the user messages kept whole, what moved to memory, what was pruned (nothing, for a compaction), and the context before and after. A run’s check status reads stale the moment a file changes after its last green test, across the compaction capsule,/run, the left rail and the editor projection.
Each automatic compaction frees enough room under the threshold for the next turn (reserving the largest token underestimate seen in the session so a file-heavy task does not immediately re-trigger compaction on the next round), answers your latest message before resuming an older task, and draws its own boundary row with its own figures; after a compaction, the transcript writer on daemon-hosted chats scans all recorded IDs on disk without duplicating earlier history, and the chat view re-anchors at the newest boundary record and keeps every post-compaction row in order across reattach, /restart and daemon restart. A normal compaction at the threshold sends the conversation unshaped so the prompt cache stays warm; when a conversation would cross the summariser’s blocking limit, a three-rung ladder pre-fits the input, retries on half the input with thinking and effort unchanged if the provider returns an empty or terminated summary, and lands on Mercury’s own turn and tool records with the cause named when no prose summary returns. Past 80% of the context window, parallel tool calls in a round share the remaining room to the blocking limit. If the compaction loop breaker pauses automatic compaction for the run, its notice appears beside the answer instead of repeating compactions without answering. On a small-window local model, fixed material is measured from the request’s own tools instead of the full catalogue, and a compaction that cannot land states why.
Only when compaction cannot bring the context under its threshold, or any non-cancelled compaction attempt fails, or the provider refuses the request despite the estimate, does the emergency prune clear older file results that a later successful Read, Edit or Write of the same path superseded; the latest result for a path, unique results, failed or unfinished operations, skill and brief material, the ten most recent eligible results and the newest 40,000 tokens of tool output stay, and a result under 50 tokens is never replaced. The chat reports the number of result bodies pruned and Mercury’s estimate of the tokens saved, net of placeholders, and states that no summary was written and nothing moved to memory by that prune. An idle gap on its own does not clear results.
Turning Auto-compact off in /config, or setting MERCURY_AUTO_COMPACT=0, disables early compaction; emergency recovery stays available. If a request outgrows the window, Mercury can still compact and retry. MERCURY_COMPACT=0 disables compaction and pruning altogether. The health check names the setting that disabled it and whether emergency recovery remains available.
A conversation too big to summarise in one request is compacted in parts, and one plain warning says when a conversation’s size is what makes its requests fail. The summary call gets the provider’s own patience, and a model’s refusal of the first summary request is retried once with the conversation handed over as text. After three failed automatic compactions the session pauses, and the pause message says what works: /compact by hand, and the next message makes a fresh automatic attempt. If the request still will not fit, the message names what was tried and suggests shortening or splitting an oversized prompt, using /compact, starting fresh with /clear, or choosing a larger model window. A headless run reports the same reason with remedies for that mode.
A line sent while the session compacts waits in the runner’s own queue and is drawn as a queued row marked held; while compaction runs, the chat shows one row (compacting context, ↓ ~<tokens>, the progress bar and elapsed time). When compaction finishes, the runner takes the held lines as its next turn, in the order they were sent, each exactly once. ↑ on an empty composer while a line is queued or held takes it back into the composer. A notice an agent has not read within MERCURY_NOTICE_DEADLINE_MS, three minutes unless set, nudges the agent once with the notice’s own text; a busy agent is left to its turn, and a nudge that finds the agent gone retires the notice and says why.
Send a waiting line now
While a turn waits inside a tool call with a line you sent queued behind it, the status row adds ctrl+s s sends now. Hold Ctrl and press s twice within two seconds to send the waiting line into the running turn at once. A crewmate or a shell command the turn was waiting on moves to the background and keeps running, its result arriving as a notification, a Sleep ends, and the line opens the agent’s next step. A single Ctrl+S stashes the draft. In the SDK, sendNow() and send_now() send the waiting input of a hosted session the same way.
Recover after losing the terminal
If the terminal connection is lost, Mercury closes the session cleanly and keeps its transcript. The next boot provides a way back into that conversation.
Name a session
Enter /title <words> in a session’s chat to set a custom title that takes precedence over the automatically generated title.
A session’s name updates in three stages: a ready label when created, the first line of your first prompt, and after the second reply a short title that the small model writes once into an empty name. A leading slash command stays out of the title. A name never regresses to an earlier stage. /rename <words> names the session from the chat, r on a board row renames the session there, and bare /title requests another generated title and incurs a model call.
Park a chat and start fresh
Press Esc if the session is mid-turn, then enter /clear. The old session parks with its transcript kept, and a blank session opens in the same folder on the same model (when that model cannot be reached, the fresh chat starts on the default model with a one-line warning notice naming the unreachable model and /model).
Switch a live chat to an installed build: /restart
A session keeps the build its runner started on. Within a minute of an install, a live session on an older build shows a one-time unfolded notice between turns in its chat (carried over across /clear so it does not repeat): A newer Mercury build is installed (<tree>). This chat still uses <tree>. /restart switches to it; watches and background shells will stop and be listed.
Entering /restart in that chat lists the Monitor watches and background shells that will end, stops the session's own runner before daemon handover, switches the background daemon to the installed build if needed, and resumes the session on that build. Restarting or resuming onto a new build replays the recorded tool roster (unless a bound tool is no longer offered by the build and has no recorded definition), keeping the request prefix and signed thinking intact. The resumed chat, its next turn and its receipts carry one line naming the build and every watch and background shell the restart ended. /restart checks the runner's build info first, leaves an already-current session unchanged, tells you to wait for the active turn to finish when a turn is running, and refuses a source run with no runtime manifest. If the daemon move fails, /restart reports the failure and tries to resume the session on the available daemon. A runner found dead with its daemon after the installed build changed is recorded as ended around an update with its cause unknown.
Close a session from the board
To close a session from the board, select its live row on the Session Concourse and press Ctrl+X twice. The first press shows the hint on the row and the second completes. The session stops and its row remains with the next action displayed.
The close chord has these further effects:
- Stopped row: Repeating the chord archives the session into PARKED. A chat with no messages yet is released by the chord, and its row leaves the board.
- Parked row: The chord stages deletion, and the next chord deletes the board record.
- Transcript: Deleting the board record leaves the transcript on disk and available through the home screen and
/sessions.
Restore a checkpoint
To restore a checkpoint:
- Enter
/rewind, or its alias/checkpoint. - Select a recorded turn.
- Choose the files, the conversation or both.
The session's own runner restores the checkpoint and answers with a receipt. A turn still running is interrupted first.
The File checkpointing setting controls file snapshots for each turn. Choose a file's Restore <file> row in /rewind to restore only that file at the selected checkpoint while leaving other files and the conversation untouched. Before restoring files, Mercury saves their current bytes, and /rewind offers Undo the rewind until your next prompt to restore those pre-rewind bytes without changing the conversation (in mercury runner, session/file_restore provides action: "restore" and action: "undo", with tracked files and undo reported in file_checkpoints session facts). If you edited a file by hand since the session last changed it (or since the file restore, when undoing), Mercury refuses the file restore, names the file and writes nothing until the conflict is resolved. Housekeeping caps <config-home>/file-history at 500 MB, removing the oldest session backup directories first alongside the configured age retention, and /health shows the current usage and 500 MB limit under State cleanup. A checkpoint without saved files (including one whose backups were pruned) can restore only the conversation. A checkpoint before the last /compact cannot be restored. Restoring the conversation preserves the session identity and the transcript's recorded rows. Two further choices, Create a branch session from here and Rerun from here on a new branch, leave this chat untouched and open the branch as its own session.
Temporary files and the export
Each session has a temporary folder of its own under <temp root>/mercury-<uid>/<project>/<session id>/, where the model is told to put helper scripts, intermediate results and captures. It lies outside the project, so it stays out of git status, and it is swept when the session ends; MERCURY_TMPDIR moves the root. /export <name> writes the chat to a text file, or to a JSON copy when the name ends in .json, with secrets masked, tool results trimmed and thinking left out.
Images in a conversation
Mercury sizes each image to the provider API's limit when composing a request, including in histories with more than twenty images. A conversation previously refused for image size can continue on its next send, including after a model switch, without /clear. A refusal names the image case it cannot send.