Shell Pane
The workflow comparison named the one step terminal parity could not remove: the quick git command or test run that sent the person back to a terminal. The Claude desktop app's Code tab answers it with an integrated terminal that "opens in your session's working directory and shares the same environment as Claude" (Claude Code desktop). The console's Shell tab is that terminal.
How it works
flowchart LR P["Shell tab, or Ctrl+backtick"] -->|OpenShell| H[Host] H --> PTY["Shell under a pseudo-terminal<br/>session folder, host environment"] PTY -->|ShellOutput| H -->|every page| X[xterm.js in the Shell tab] X -->|ShellInput, ShellResize| H --> PTY H -->|session closed, or host stopping| K[Shell ended, ShellClosed]
- A Shell tab in the console, after the timeline, changes and usage tabs, opened by
Ctrl+`from the world. It opens on a shell in the current session's folder, and + opens another beside it, each its own shell with its own close. - The host owns the process. The page runs nothing.
OpenShellasks the session's host to start PowerShell on Windows — PowerShell 7 or later when it is on the path, as Windows Terminal opens it, and Windows PowerShell otherwise (getShellFile) — or the person's$SHELLelsewhere, under a pseudo-terminal in the session's folder with the host's own environment (spawnPtyShell). Only "PSModulePath" is left out, so each PowerShell finds its own modules: one inherited from the other PowerShell fails to load PSReadLine. The shell's bytes reach every page asShellOutput; keystrokes and a new size go back asShellInputandShellResize. A remote connection's shell runs on that machine, since that is where its session runs. - A shell is the host's, not the driver's. The four shell commands are a union of their own (
ShellCommand) beside the driver's (DriverCommand), answered by the host's shell registry (createShellRegistry,handleShellCommand) rather than the driver, and never forwarded to a session window. A shell's output is a server message, never an agent event, so it never enters a session's event log. - A shell outlives neither its session nor the host. A session reporting itself closed ends its shells and starts none for it until it opens again, as a resume does, and the host stopping ends them all and starts no more; each end reaches every page as
ShellClosed. A shell still starting when either closes is ended as it arrives, and itsOpenShellis answered with an error. A page that reconnects is replayed every running shell with the last of its output — the host keeps a bounded amount per shell (SHELL_OUTPUT_LENGTH) — and drops what it had of that shell first, so nothing shows twice. - xterm.js draws it, loaded when first shown. The terminal renderer VS Code and the Code tab use, so colour, cursor movement and full-screen programs behave as in a terminal.
@xterm/xtermand its fit addon load with a dynamicimport()when a shell first mounts, so the console's own chunk carries none of it. The terminal fills its space and tells the shell each new size. - node-pty ships beside the executable. A pseudo-terminal needs node-pty's native addons, and on Windows it also loads a worker and forks an agent from files beside its own code, which a single executable cannot hold. The Windows build embeds node-pty's code and its Windows prebuilt binaries as assets (
packages/agent-console-server/scripts/copyNodePty.ts,packages/agent-console-server/scripts/writeSeaConfig.ts), the install writes them out into the install folder beside the Claude Code binary, and the executable loads that copy when the first shell opens (loadNodePty). The agent node-pty forks runs the executable again with the agent's path, which the executable answers itself (runConsoleListAgent). Run from the package, node-pty is an ordinary optional dependency.
Dependency admission
Both pass the admission test as ordinary keeps. node-pty is an engine over each system's pseudo-terminal API (ConPTY on Windows) — a native surface nobody would reimplement — and it is optional, so a system without a prebuilt binary or a compiler still installs the host and only its Shell tab says no shell can start. @xterm/xterm and its fit addon are the terminal emulator itself: escape sequences, input handling and accessibility are the product, which is the stop list's accessibility-shaped and engine rows.
What is deliberately not in it
- No terminal inside the world. The shell is a console tab; the world stays a place, not a second screen.
- No prebuilt shell support on Linux. node-pty ships prebuilt binaries for Windows and macOS. A Linux host opens a shell only where node-pty was built from source, and otherwise answers that no shell can start.
Key files
| File | Role |
|---|---|
packages/agent-console-server/src/models/command/ShellCommand.ts | The four shell commands, apart from the driver's |
packages/agent-console-server/src/services/shell/createShellRegistry.ts | The host's shells, their bounded output, and ending them with a session |
packages/agent-console-server/src/services/shell/spawnPtyShell.ts | The platform's shell under a pseudo-terminal |
packages/agent-console-server/src/services/shell/loadNodePty.ts | node-pty, from the install folder inside the executable |
packages/agent-console-server/src/services/shell/runConsoleListAgent.ts | node-pty's forked agent, answered by the executable |
packages/agent-console-server/src/services/server/createAgentConsoleServer.ts | The shell commands answered, output broadcast and replayed |
packages/agent-console-server/scripts/copyNodePty.ts | node-pty's Windows files, placed for the executable to embed |
apps/web/app/store/agentConsole/shell.ts | Every host's shells and the output a later terminal is written |
apps/web/app/components/AgentConsole/Panel/Shell.vue | The Shell tab: a shell per tab, + and close |
apps/web/app/components/AgentConsole/Panel/ShellTerminal.vue | xterm.js, loaded on first show, sized to its space |
Sources
- Claude Code desktop — terminal integration — "The terminal opens in your session's working directory and shares the same environment as Claude", opened with
Ctrl+`, with more tabs from +. - xterm.js — the terminal renderer used by VS Code, which the Code tab's pane also draws with.
- node-pty — pseudo-terminals for Node, with prebuilt Windows binaries over ConPTY.