Supported session kinds
Built-inagent values:
codexclaudeopencodeqwenkimigrokbash
command.
Session identity
Every session has a durablesessionId. Desk preserves it across edits and
uses it for the Moor control socket, terminal state, channels delivery,
attention, and agent events. The agent’s resume id remains a separate
provider-owned value.
Desk sets these environment variables for managed launches:
DESK_SESSION_GENERATION is what lets Desk reject a report from a producer
that outlived a restart: a hook stamps the generation it was launched in, and
the daemon refuses anything carrying an older one. A hook process that inherits
no generation posts nothing — silence is the correct answer when an event
cannot be attributed, and it is why a session started before its hooks existed
reads unknown rather than reporting stale state.
A session bound to an agent profile also
receives that provider’s credential-directory variable — CLAUDE_CONFIG_DIR
or CODEX_HOME — pointing at the profile root.
Codex
Codex sessions launch ascodex, with flags added for the features the session
enables. Desk no longer configures Codex’s terminal notification settings:
state comes from Codex’s own lifecycle hooks, so there is nothing to parse out
of the TUI.
When permission bypass is enabled, Desk adds Codex’s dangerous bypass flag.
When resume is set, Desk launches Codex in resume mode.
When LSP agent access is enabled, Desk passes a desk_lsp MCP server definition to Codex so the agent can call Desk’s language-server tools.
Claude
Claude sessions use Claude Code’s CLI and support:- resume ids
- dangerous permission bypass
- optional MCP config for Desk LSP tools
- hook settings for state reporting and resume capture
--settings at launch:
~/.claude/settings.json. That file is the operator’s —
their model, their hooks, their preferences — and a tool that installs its
reporting by editing it has taken something it was not given. The launch flag
achieves the same thing for the session Desk starts and leaves the operator’s
file exactly as they wrote it. desk hooks install writes Desk’s file.
OpenCode
OpenCode sessions launch through the configured OpenCode binary. Desk resolves it from:DESK_OPENCODE_BINPATH~/.opencode/bin/opencode
OPENCODE_CONFIG_CONTENT:
- bypass enabled:
permission["*"] = "allow" - bypass disabled:
permission["*"] = "ask"
ses_... ids. Desk can discover recent OpenCode sessions from opencode session list --format json and persist a matching id.
Qwen
Qwen sessions launch asqwen (Qwen Code, a Gemini-CLI fork). Desk supports:
- resume ids (
--resume <id>, a UUID) - permission bypass (
--yolo) - hook settings for state reporting and resume capture
desk_lsp for Qwen in two parts. desk hooks install registers
the server once in ~/.qwen/settings.json (Qwen has no per-session MCP flag),
unconditionally — the install command has no view of LSP settings. The
per-session part is gated: only when LSP agent access is enabled does a Desk
launch carry the session’s DESK_LSP_ENV_FILE in the environment. Without
that variable the registered tools stay visible to Qwen but every call
returns a missing-environment error — including in Qwen sessions run outside
Desk. Note that the variable lives in the Qwen process environment, so child
processes Qwen spawns inherit it; the token it points to stays bound to the
launching session’s workspace.
Qwen’s hooks are Claude-compatible and live in:
desk hooks install merges Desk’s hooks into that file and also fills two
terminal-context keys Qwen exposes only through settings —
ui.mouseTracking: false and ui.useTerminalBuffer: false, so a click does
not paste mouse-report bytes and the pane has one scrollback instead of two.
It fills only keys the operator has not set: an explicit operator value is
never overridden, and other settings are untouched. If the file is malformed
JSON it is backed up and skipped rather than overwritten. Qwen reads a
command hook’s timeout in milliseconds (unlike Claude/Codex, which use
seconds), so Desk writes 10000 there.
Permission bypass maps to Qwen’s --yolo (auto-approve all tools; needs Qwen
Code ≥0.21.13 — older CLIs reject the flag, and Qwen’s own auto-updater keeps
the effective version current).
A successful --resume keeps the conversation id. What Qwen does not do
is persist a resumable session before the first message is exchanged, and a
fresh launch mints a new id — so a Qwen pane restarted before any input
carries an id the CLI rejects. Desk keeps the pane alive (see
Resume capture) rather than letting it exit.
Qwen needs a provider credential. Point it at Alibaba ModelStudio, a third-party
key, or any OpenAI-compatible endpoint through Qwen’s own Connect a Provider
flow.
Kimi
Kimi sessions launch askimi (Kimi Code). Desk supports:
- resume ids (
--session <id>; Kimi mintssession_...values, which Desk validates as opaque tokens) - permission bypass (
--yolo) - hook settings for state reporting and resume capture
[[hooks]] blocks appended to:
desk hooks install rewrites only Desk’s own blocks and leaves operator-authored
hooks in place; a config whose hooks key is not an array of tables is skipped
rather than corrupted. Validate with kimi doctor.
Kimi’s coding endpoint needs an active Kimi (Moonshot) membership for OAuth, or
a provider key added through kimi provider.
Grok
Grok sessions launch asgrok (superagent-ai’s grok-cli, published to npm as
grok-dev; it runs under Bun). Desk supports:
- resume ids (
--session <id>; Grok mints 12-hex values, which Desk validates as opaque tokens) - hook settings for state reporting and resume capture
SessionStart lazily
on the first prompt (not at launch), so a freshly launched Grok pane reads
unknown until the first message, and its tool hooks fire only for the bash
tool. There is no periodic heartbeat to fill that gap: a long non-bash tool
run (e.g. an MCP tool from Grok’s own settings) outlives the working lease
and the session reads unknown until the next hook fires. Grok cannot join desk_lsp yet: it reads MCP servers only from its
global settings and spawns them with a sanitized environment, so the
per-session token cannot reach the server.
desk hooks install only writes a new agent’s hook config when that CLI’s
config directory already exists, so a machine that never installed Qwen, Kimi,
or Grok is left untouched.Bash
Bash sessions run:Permission bypass
The Add Session modal shows a bypass-permissions option for Codex, Claude, OpenCode, Qwen, and Kimi. The manifest field is:--yolo.
For OpenCode, Desk maps it to a per-session OpenCode permission config. Unchecking the box makes OpenCode ask for tool permissions.
Grok has no bypass flag (it has no per-tool approvals at all): the checkbox is hidden for it, and bypassPermissions: true on a Grok session is a manifest error rather than a silent no-op. (A bash session still ignores the field silently, as before.)
Resume capture
Desk can start a session withoutresume and later capture the conversation id:
- Codex: reads Codex session records and startup shell snapshots
- Claude, Qwen, Kimi, Grok: receive hook events carrying the provider session id
- OpenCode: queries OpenCode’s session list
desk reset-provider-session <sessionId> --force.
State reporting
Every supported CLI reports its own lifecycle to Desk through hooks thatdesk hooks install writes. Each hook posts a small, bounded observation —
which event fired, and the few fields Desk needs from it — to
/api/agent-event. Desk decides what that observation means server-side, so
one definition of “working” serves every provider instead of one per adapter.
The facts a provider can assert:
Anything a provider does not assert stays unknown. Desk never fills the gap
from terminal output: the OSC 9 and BEL sniffing earlier versions used is gone,
along with the screen poller that backed it, because a signal that means
“something happened” cannot be told apart from one that means “a turn ended”.
Attention is a projection of that state for the operator. It does not gate
channel delivery — see the delivery engine.
Hook configuration is read when a session launches. A session started before
desk hooks install ran reports nothing until it is restarted, and shows
unknown in the meantime.Agent LSP access
When LSP is enabled and agent LSP access is enabled, Desk wires thedesk_lsp MCP server into supported managed agents (Codex, Claude, and Qwen).
The server exposes language-server tools such as hover, definitions, references, diagnostics, symbols, completions, rename preparation, rename edits, formatting, and code actions.
The MCP surface is token-bound to the session workspace. Agents receive the token through a locked-down runtime env file or agent-specific MCP config. Tools return data and edits; they do not directly apply changes to files.