Desk’s workspace model is intentionally small. A manifest contains projects; projects contain groups; groups contain sessions.

Panes

The window is a rail of subsystems on the left, one sidebar column beside it, and the working area. Split in the header divides that working area into two panes, so you can follow a channel while you edit a file, or watch a terminal while you read a note. A pane hosts one subsystem, the drag handle between the panes moves the divide, and the same subsystem is never in both. The pane you last clicked in is the focused one. It owns the sidebar, the status bar and the keyboard shortcuts, and its top edge carries a thin accent line. In the rail its icon is the lit one, while the subsystem open in the other pane is marked in grey. Clicking an icon in the rail puts that subsystem in the focused pane; clicking the icon of a subsystem already shown in the other pane moves the focus there instead. Right-clicking an icon names the pane. With one pane, a subsystem that is off screen can be opened in the other pane, which splits the window. While the window is split, an off-screen subsystem can be opened in the left or the right pane, an open one can be moved to the other side (the two panes trade places, width included), and either pane can be closed, giving the window to the other one. A pane’s own chrome has a smaller menu of its own: swap the panes, close this pane, collapse the sidebar. A window too narrow for two panes offers none of this — not even closing a pane it cannot show. Opening something from inside a pane — a file from a channel message, a note from a terminal selection, a diff from the editor — lands in the other pane, so what you opened it from stays on screen. Switching panes never reloads anything: every subsystem keeps its place in the page, so terminals keep running, editors keep their buffers and the channel feed keeps its scroll position. The sidebar stays put too: while the workspace is split the column has one width and one collapsed state, shared by both panes, so moving the focus neither resizes it nor opens and shuts it, and it keeps to a quarter of the working area so it never comes out as wide as the panes beside it. Each subsystem’s own width and collapsed state apply again once a single pane has the window to itself. The layout, the divide and both sets of sidebar preferences are remembered by your browser. A narrow window shows the focused pane alone and restores the split when there is room again.

Projects

A project represents a working tree or root directory. It gives Desk a stable scope for sessions, editor roots, Git discovery, and group organization. Use one project per repository when your agents work in different repos. Use one project with multiple groups when several agents work in the same repo.

Groups

A group is a cell-grid workspace inside a project — each cell holds a session rendered as a native agent chat or a terminal. Groups are useful for:
  • separating roles such as frontend, backend, reviewer, and release
  • keeping noisy commands away from agent sessions
  • switching between related session grids
  • preserving layout and selected sessions per workstream
Each group has a layout such as one cell, a grid, or custom split sizes. Desk persists layout changes to the manifest.

Sessions

A session describes one Moor-backed process. It can be:
  • a managed Codex session
  • a managed Claude session
  • a managed OpenCode session
  • a Bash shell
  • a custom command
Managed agent sessions get Desk launch flags, permission handling, resume capture, attention hooks, and optional LSP MCP wiring. Custom commands run as the command you provide.

Session ids

Every session has a durable sessionId. Desk preserves an existing id or mints one from the session name when you add or migrate a session. The id is the shared key for:
  • the Moor control socket
  • terminal generation and snapshot state
  • channels membership and delivery queues
  • attention, resume capture, and agent event routing

Resume ids

Resume ids belong to the agent CLI, not to Moor. Desk stores known resume ids in the manifest and can also harvest them after a first turn for managed agents. Use resume ids when you want a restarted agent CLI to reconnect to the same conversation. Bash and custom command sessions do not use agent resume ids.

Startup behavior

desk up reads the manifest, checks the configured Moor control sockets, and starts only the missing sessions. It does not replace running sessions. Use desk up --dry-run before changing a large fleet.

Browser state

The browser stores selected views, open editor tabs, panel sizes, and UI preferences separately from Moor process lifetime. If you reload the browser, Desk reconnects to the running sessions through the binary terminal transport.

Next steps