Date: 2026-04-22
kmux is a multi-workspace terminal app. In this phase it is implemented as a macOS-first MVP built on Electron + xterm.js + node-pty.
Core goals:
- Deliver the full
workspace + pane + surface + notification + automationloop without an embedded browser. - Reach a polished macOS UI baseline with calm density, clear hierarchy, and dependable focus affordances.
- Stay responsive at human scale across tens of workspaces and surfaces.
- Preserve an architecture where the renderer does not own PTY sessions or the source of truth for state.
Non-goals:
- Embedded browser
- SSH relay
- Exposed multi-window UI
- Windows support
The baseline architecture is defined in 0002-electron-xterm-mvp-architecture.md.
Processes:
electron-main: single writer, file-store persistence, socket API, metadata schedulingpty-host:node-ptyand@xterm/headlesssession runtimerenderer: split UI, sidebar, overlays, visible terminals, and warm pane-scoped terminal widgets used to preserve workspace switch continuity
Hard rules:
- The renderer must not own PTYs directly.
- The renderer may keep pane-scoped
xterm.jswidget instances warm across workspace switches to avoid destructive remounts, blank intermediate states, lost focus, and TUI redraw churn. - Warm terminal widgets are renderer-only caches. The
pty-hostremains the owner of PTY and headless terminal state, andelectron-mainremains the source of truth for workspace, pane, surface, and session state. - Hidden surface tabs within a pane must still detach from the visible terminal widget; switching tabs must hydrate the pane widget from the selected surface snapshot/stream.
- High-cost terminal renderer resources, especially WebGL renderers, must be bounded by a recent-pane policy and released when panes leave product state.
- All state mutation must flow through the main reducer.
- Stable
windowId,workspaceId,paneId,surfaceId, andsessionIdvalues must be preserved. - Workspace switching must preserve the active pane tree's terminal continuity without making hidden workspace widgets authoritative for session state.
- Create, select, rename, and close
- Next/previous and direct selection with
1..9 - Create a workspace from an open folder
- Toggle the sidebar
- Workspace switcher
- Preserve ordering while the app process remains alive, including close-window and reopen-on-activate flows
- Split-right and split-down UI
- Split-left, split-right, split-up, and split-down API
- Four-direction pane focus
- Pane resize
- Pane close
- Multiple surface tabs per pane
- Surface create, focus, rename, close, close-others, next/previous, and direct selection with
1..9
- Shell launch
- Resize
- Copy/paste
- IME
- Selection
- Search, find-next, and find-previous
- Copy mode
- OSC-based cwd, title, and bell handling
- Attach snapshot plus incremental output
- Pane-scoped warm terminal preservation across workspace switches
- Bounded WebGL acceleration for recently active panes, with fallback to the default renderer outside the bound
- Workspace row name; user-managed label that defaults to
new workspaceuntil explicitly renamed - Representative surface summary/title
- Cwd/path summary from the representative surface
- Git branch from the representative surface
- Up to three local ports aggregated across workspace surfaces, with the active surface taking precedence when selecting which ports to show
- Unread badge
- Pane attention ring
- Status pill
- Progress bar
- Log feed
- Notification center
- Jump to the latest unread item
- CLI
- Unix domain socket JSON-RPC
workspace.list/create/select/current/closesurface.split/list/focus/send_text/send_keynotification.create/list/clearsidebar.set_status/clear_status/set_progress/clear_progress/log/clear_log/sidebar_statesystem.ping/capabilities/identify
- Closing the last app window on macOS must keep the app process, PTY sessions, socket server, and in-memory workspace state alive
- Reopening the app from the Dock or
activateflow while the process is still alive must restore the same live workspace, pane, surface, notification, and focus state without a cold boot - Explicit app quit, including
Cmd+Q, must shut down background services and start the next launch from a fresh workspace session - Clean relaunch must preserve persisted settings and window chrome state, but must not reuse the previous workspace layout, pane graph, surface tabs, or session set
- Snapshot persistence exists for crash or unclean shutdown recovery only; a clean shutdown must not restore the previous working set on the next launch
- Preserve a polished window chrome, sidebar, pane header, split geometry, and dark palette baseline with strong readability.
- Treat pane body content as a functional verification target; it may be masked in visual diffing.
- Pass
npm run testandnpm run build. - After launch, verify workspace, split, surface, notification, socket, close-window continuity, clean-quit fresh launch, and crash-recovery behavior.
- Workspace switching validation must cover terminal continuity: no blank intermediate pane body, no lost focused terminal input, no stale active surface after returning to a workspace, and no accidental reuse after a pane or workspace is closed.
- Warm terminal validation must cover resource policy: closed panes release cached terminal widgets, WebGL acceleration remains bounded to recent panes, and inactive tab hydration still uses the selected surface's snapshot/stream.
- If a problem is found, fix it and rerun validation.
apps/
desktop/
src/main/
src/preload/
src/pty-host/
src/renderer/
packages/
core/
proto/
persistence/
metadata/
cli/
ui/
KMUX_SOCKET_PATHKMUX_SOCKET_MODEKMUX_WORKSPACE_IDKMUX_SURFACE_IDKMUX_AUTH_TOKENKMUX_PROFILE_LOG_PATHTERM_PROGRAM=kmux
- The app launches and visible terminals attach correctly.
- Workspace, pane, and surface state remain consistent across live app interactions, while persisted settings, window state, and crash recovery remain predictable.
- Workspace switching preserves terminal widget continuity while PTY/session ownership stays outside the renderer.
- Automation and notifications work correctly.
- The UI remains visually coherent, polished, and easy to read at normal working sizes.