Skip to content

Sessions and the server

cornercase is two programs in one binary. A server runs in the background and owns every shell, emulator and agent. The cornercase command you type is a client: it shows what the server draws and sends it your keys and clicks. Because the shells belong to the server, closing the window doesn’t close them.

your terminal ── cornercase (client) ─┐
│ Unix socket
another terminal ── cornercase ───────┤
▼
cornercase server ── shells, editors, agents
  • The first cornercase starts the server for you and attaches to it. The server opens the folder you started from as your first project, unless it restores a saved session (see below).
  • Detach by clicking Quit at the bottom of the projects column, or by closing the terminal window. Only the client goes away; everything in your panes keeps running.
  • Without a window, cornercase start-server starts the server and restores your session for scripts and other programs; the first cornercase after it attaches to that session (see Scripts and agents).
  • Reattach by running cornercase again, from any terminal and any folder. You find everything as you left it, including programs that kept printing while you were away.

This also works over SSH: run cornercase on the remote machine, close the connection when you leave, and reattach when you log in again. Or keep the window on your laptop with cornercase remote <host>, which reconnects by itself when the connection drops: see Remote machines.

Run cornercase in as many terminals as you like. They all attach to the same server and mirror each other: the same projects, the same active tab, even the same open menu. What you type in one shows up in all of them.

All clients share one screen size: the size of the terminal you used last. Attaching, typing or clicking in a terminal makes it the one in charge; moving the mouse over it does not. A larger terminal shows the session with empty space around it, a smaller one shows it cut off at the right and bottom edges. So attaching from your computer after your phone always fits the computer, even if the phone’s connection is still hanging. Programs that draw cornercase themselves can open a view instead: it picks its own tab and size, and a tab’s terminals take the size of whoever used it last, a window or a view.

The server saves your session to ~/.local/state/cornercase/session.json (or $XDG_STATE_HOME/cornercase/session.json):

  • your projects, workspaces and tabs, in the order you put them in, with their custom names;
  • your project groups, in order, with their icon, colour, which ones are collapsed and which projects they hold;
  • every pane’s folder, and how each tab is split, including the divider positions;
  • which project, workspace, tab and pane are active;
  • the width of the sidebar’s columns, the line between stacked lists, the height of the agents section and the width of the changes panel, whether it, the files panel or the TODO panel is open, and which scope and mode the changes panel shows;
  • which workspaces are collapsed, and which projects in the tree, and which agents’ teams are collapsed in the agents section;
  • the branch each workspace’s changes panel compares with, when you picked one;
  • which panes send right-clicks to their program;
  • the conversation of each Claude Code, Codex, Gemini CLI, Grok Build, Cursor CLI or GitHub Copilot CLI pane, so it can resume;
  • the issue browser’s last tab and filters.

The TODO list itself is kept apart, in todos.json next to session.json.

It saves once your layout has stayed the same for two seconds, so the burst of shells closing when you log out of your computer doesn’t overwrite a good session with an empty one.

Processes can’t be saved. When a new server starts, after cornercase kill-server, a reboot or a restart after an update, its first window, or cornercase start-server, restores the saved layout, once: the same projects, workspaces, tabs and splits, each pane with a fresh shell in its saved folder. Folders that no longer exist are skipped; a pane whose folder is gone starts in its workspace’s folder. If a shell can’t start in some folder (one you can no longer enter, say), that tab is left out, everything else comes back, and a message names the projects it was in. If no shell could start at all, a new one opens in the folder you started cornercase from. The session as it was is kept in session.json.bak, next to session.json.

A server that is already running never restores: reattaching just shows what is there, also after start-server.

A pane where Claude Code, Codex, Gemini CLI, Grok Build, Cursor CLI or GitHub Copilot CLI was running comes back in the same conversation: once its new shell is ready, cornercase types claude --resume <id>, codex resume <id>, gemini --resume <id>, grok --resume <id> or cursor-agent --resume <id> or copilot --resume=<id> into it, with the command and arguments from settings → Agents and the mode the agent was running in (plan, read only, accept edits…). The agent opens idle, with the conversation on screen, waiting for you; whatever it was doing when the server stopped is not started again.

While a conversation comes back, its pane shows resuming claude… and takes no input: keys and pastes are dropped with a note saying why, since typed before the agent is back they would land in front of the resume command or in the agent’s start-up. The pane takes your keys again once the agent has drawn its screen, or once it gives up (the agent exits, or 30 seconds pass). cancel next to the note gives the pane back at once: before the resume command is typed, it is not typed and the pane stays a plain shell; after, the agent keeps starting and only the keys come back. If the agent asks whether to trust the folder, the pane takes your keys so you can answer.

Only a conversation with something in it comes back: an agent you opened and never wrote to, or one you had already quit, leaves a plain shell. To get plain shells everywhere, turn off settings → Agents → resume conversations.

Click Settings, then restart next to done, or run:

Terminal window
cornercase restart

Restarting stops every program in your terminals, agents included, so cornercase first lists what is running and asks. Then it saves your session, starts a new server and reopens every attached window on it (with no window attached, no new server starts: run cornercase start-server again): your projects, workspaces, tabs and splits come back, each pane with a new shell in its folder, and Claude Code, Codex, Gemini CLI, Grok Build, Cursor CLI and GitHub Copilot CLI resume their conversations.

An agent in the middle of a turn still loses that turn. To restart only once no agent is working, run cornercase restart --when-idle: every window says a restart is pending until then (see Command line).

Terminal window
cornercase kill-server

This ends every shell and program in every pane, and closes all attached clients. When something was running, it says what it stopped, such as stopped 1 agent and 2 other programs. If no server is running, it says no cornercase server is running. Run inside one of the server’s own panes, it asks before stopping it (this terminal closes too), and refuses without a terminal unless you pass --yes. The server also stops when it receives SIGTERM or SIGINT; it ignores SIGHUP, so a closed terminal or SSH connection doesn’t take it down.

When you update from the app, its last step, restart now, saves your session, restarts the server on the new binary and reopens every attached terminal on it. cornercase update does the same from a shell when you answer y. Your layout comes back from the saved session; programs that were running, agents included, are stopped, each pane starts a new shell in its folder, and agents resume their conversations. Before restarting, cornercase says what is running right now, so you can wait for an agent to finish first: how many agents are working or waiting for you, and which other programs run where. Panes sitting at their shell prompt aren’t listed.

A client only attaches to a server built from the same binary. If you skip the restart, or update with Homebrew or by rebuilding, the old server keeps running and the next cornercase asks:

The running cornercase server comes from another build; cornercase was probably updated.
Restarting stops every program running in cornercase's terminals. Running now: 2 agents (1 working,
1 waiting for you) and 1 other program (`npm` in orders-api › main). Your projects, workspaces, tabs and
splits come back, each tab with a new shell in its folder. 2 agent conversations resume in their tabs.
Restart it now? [y/N]

Save your work in the panes and answer y. Answer anything else to keep the old server for now; restart it later with cornercase kill-server, then cornercase.

CORNERCASE_SOCKET points cornercase at another socket, which means another, completely independent server:

Terminal window
CORNERCASE_SOCKET=/tmp/cc-demo/server.sock cornercase

That server keeps its own settings, saved tokens, session and issue cache in the socket’s folder, so it never touches your usual ones. It’s handy for trying things out, for a demo, or for keeping two unrelated sets of projects apart. Stop it with the same variable:

Terminal window
CORNERCASE_SOCKET=/tmp/cc-demo/server.sock cornercase kill-server

Every shell that cornercase starts has CORNERCASE=1 in its environment. Running cornercase from inside one of its own panes refuses with:

cornercase is already running in this terminal; nesting it is not supported

To attach a second view, use another terminal window.

The server is started by the first client (a window, or cornercase start-server), from that terminal, and keeps that client’s environment. Every shell it opens inherits it, plus TERM=xterm-256color and CORNERCASE=1. The shell itself is your $SHELL, or /bin/sh if it isn’t set.

So if you change an environment variable in your login files, open a new tab to get a shell that reads them again, and restart the server for variables cornercase itself reads, such as SHORTCUT_API_TOKEN. The full list is in Files and environment.

The agent queue is saved separately in queue.json, including its entry ids and history. Entries more than ten minutes late become missed and wait for an explicit start.