Skip to content

Architecture

TrueDeck is a desktop app: Electron main owns processes and data, preload exposes a typed IPC API, and the renderer is a React + xterm Studio UI. The Rust truedeck-backend is the main session engine.

High-level stack

LayerWhat runs there
Renderer (src/)React, zustand store, xterm panes, TaskBoard, Settings
IPCcontextBridge / preload (window.truedeck)
Electron main (electron/main/)App lifecycle, pty-manager, tasks, mcp-hub, memory, agents, session layout
Session engineRust truedeck-backend (required)
AgentsReal CLIs in ConPTY / PTY under the project root

Process roles

Main (electron/main/)

ModuleResponsibility
index.tsApp lifecycle, BrowserWindow, settings IPC, session restore orchestration
pty-manager.tsSession map, spawn/write/resize/kill, rust vs node-pty backend
resolve-command.tsPATH / known-path CLI resolve; blocks Cursor IDE
agents.tsDefault agent presets + agents.json merge
session-layout.tsPersist/load pane tree; max 16 tabs
tasks.ts / task-dispatch.ts / runs.tsKanban store, dispatch to PTY, run records
mcp-hub.tsUnified MCP config write/sync to agent clients
memory-service.ts / memory-providers.ts / mempalace.tsAuto-context, env inject, providers
agent-frame.tsWrap spawn in truedeck-frame.mjs when enabled
backend-bridge.tsJSON-RPC stdio to truedeck-backend
utf8-carry.tsShared UTF-8 chunk decoding for ConPTY streams
paths.tsApp data and memory directory helpers
projects.tsProject list CRUD
first-run.ts / onboarding.tsFirst-run / onboarding flow

Preload (electron/preload/index.ts)

Exposes window.truedeck methods (spawn, settings, MCP, tasks, restore, …) via contextBridge. Renderer never gets raw Node APIs.

Renderer (src/)

AreaRole
App.tsxShortcuts, project/session lifecycle, palette, board/settings chrome
components/TerminalPane.tsxxterm instance, fit, write IPC, shortcut filter
components/PaneWorkspace.tsx / lib/pane-layout.tsNested split tree, drag targets, max panes
components/TaskBoard.tsxKanban UI
components/SettingsMenu.tsxSettings tabs
store.tsLightweight client state (zustand)

Shared types (electron/shared/types.ts)

Single source for AgentPreset, AppSettings, SessionInfo, SessionLayout, Task, MemoryProviderConfig, etc.

PTY backends

BackendBuildDocs
truedeck-backendnpm run build:backendRUST-BACKEND.md

Env overrides:

VariablePurpose
TRUEDECK_BACKEND_BINPath to truedeck-backend executable

| TRUEDECK_DATA_DIR | Override app data directory (also used by hub MCP) |

Every session gets terminal identity env: TERM=xterm-256color, COLORTERM=truecolor, TERM_PROGRAM=TrueDeck.

Pane layout

Runtime layout is a tree of leaves (groups with tab lists) and splits (row | column + ratio).

Persisted form (SessionLayout):

  • version: 2 with paneTree when multi-pane is used
  • tabs[] as agent/command snapshots (not live PTY ids)
  • Indices map tree leaves back to restored session order

Helpers live in src/lib/pane-layout.ts (renderer) and electron/main/session-layout.ts (disk clamp/sanitize).

Session restore

  1. Renderer loads settings; if reopenLastProject, call sessions:restore
  2. Main loads session-layout.json, clamps tabs (max 16), filters install helpers
  3. For each tab, resolve agent + spawn PTY (memory env, agent frame when enabled)
  4. Renderer rebuilds pane tree from saved structure + new session ids

Memory inject

WhenWhat happens
Project openEnsure .memory/, warm MemPalace, write auto-context.md
Agent spawnonAgentSpawnFast sets TRUEDECK_* env and MCP pointers as configured

See memory-providers.md. Env bag includes TRUEDECK_PROJECT, TRUEDECK_REPO_MEMORY, TRUEDECK_PALACE, TRUEDECK_AUTO_CONTEXT, and related keys.

Agent frame wrap

If agentFrameTui is enabled (default true), pty-manager wraps the CLI with:

node truedeck-frame.mjs --agent <id> --name … --cwd <root> -- <resolved CLI> …

Shell / cmd-* panes only wrap when frameShellPanes is true. See Agent frame.

MCP hub

mcp-hub.ts merges:

  1. Built-in truedeck-hub (resources/mcp-server/truedeck-mcp.mjs)
  2. Memory-provider MCP servers
  3. User servers in mcp-servers.json

Then injects the same stdio set into Cursor / Claude Code / Grok / Codex / Gemini configs and project .mcp.json. See MCP.

Task dispatch

task-dispatch.ts:

  1. Write .truedeck/tasks/<shortId>.md + .truedeck/current-focus.md
  2. Spawn agent with TRUEDECK_TASK* env
  3. Start a run record; mark task running
  4. Best-effort seed prompt into PTY after ~1.2s
  5. On session exit → task moves toward review (or blocked on failure)

TUI mode

tui/ is a separate entry (npm run tui) that reuses agent resolve / sessions concepts without Electron’s renderer. Packaging and most docs focus on Studio.

Packaging

electron-builder packs out/**/* plus extraResources:

  • resources/bin (Rust binaries if present)
  • resources/mcp-server
  • resources/agent-frame
  • icons

See Development.

MIT Licensed · Terminal-first multi-agent deck