An open-source macOS terminal workspace with real shells, tabs, groups, and resizable split panes.
An open-source macOS terminal workspace with real shells, tabs, groups, and resizable split panes.
git clone https://github.com/qentrah/qesh.git
cd qesh
bun install
bun run build:appRead the original README for the complete repository reference.
Qentrah Shell. A clean, open-source macOS terminal workspace with real shells, tabs, groups, and resizable split panes. Use it as a desktop app or run the OpenTUI interface inside your existing terminal.
Built by Qentrah with OpenTUI, React, TypeScript, and adapted TermCN components. MIT licensed.
Download the macOS app · Report an issue · Contribute
Each launch starts fresh. Tabs and groups are not restored across launches.
Get Qesh-macOS-arm64.zip from Releases, extract it, and open Qesh.app. You can move the app to Applications or add it to the Dock. Keep qesh.config.json beside the app if you want to keep the supplied settings; the app creates defaults when it is missing.
The supplied build targets Apple Silicon macOS and includes Electron, Bun, Node.js, and native terminal dependencies. No separate runtime install is needed for the downloadable app. These early builds are locally signed and not notarized. The repository contains the source and reproducible build instructions.
Requires macOS, Bun 1.3.5+, and Node.js 22+ on PATH. Development is verified with Bun 1.3.5 and Node.js 24.12.0.
git clone https://github.com/qentrah/qesh.git
cd qesh
bun install
# Run inside your existing terminal
bun run start
# Or open the desktop development window
bun run desktopThe desktop command builds its renderer and copies the required xterm stylesheet before starting Electron. The CLI starts shells in the launch directory; the desktop uses defaultPath from the configuration JSON.
To use the short CLI command anywhere:
bun link
cd /path/to/your/project
qeshqesh --help prints usage. The older q-terminal and qentrah-terminal command aliases remain available. $SHELL selects the CLI shell, falling back to /bin/zsh; desktop settings select the desktop shell.
bun install runs the setup script to fix permissions on node-pty's macOS spawn helper. If lifecycle scripts were disabled, run bun run setup. Electron is a trusted dependency so its official binary installer can run.
If a native prebuilt dependency is unavailable:
xcode-select --install
npm rebuild node-pty --build-from-source
bun run setupSet QENTRAH_NODE to an absolute Node executable if it is not available as node on PATH. Desktop development finds Bun at ~/.bun/bin/bun by default; set QENTRAH_BUN if yours is installed elsewhere. Packaged apps use their bundled runtimes.
The three-dot menu exposes New Tab, New Window, Configure…, Split Right, Split Down, New Group…, Open / Create Folder…, Commands…, Keyboard Shortcuts, and About Qentrah.
| Desktop shortcut | Action |
|---|---|
| Cmd+T | New tab |
| Cmd+N | New independent window |
| Cmd+, | Configure JSON |
| Cmd+Shift+P | Search commands |
| Cmd+Q | Quit all windows, with confirmation |
Click a sidebar tab to switch. Double-click its name to rename it. The close button appears on hover or keyboard focus. Drag tabs to reorder them or drop them on a named group. Drag a tab or shell row to an edge of the terminal area to dock it. The Tab button beside a split shell detaches that shell into its own tab. These actions preserve shell processes.
Drag the gap between split panes to resize them, or use the prefix shortcuts below. The sidebar edge is also draggable; focus it and press Left/Right for keyboard resizing. Groups organize tabs for the current launch. Open / Create Folder uses the native macOS folder picker and starts a shell in the chosen filesystem folder.
Open Commands and type /help, /config, /new-tab, /new-window, /split-right, /split-down, /group, /folder, or /about. These are application commands entered in the Commands panel; ordinary shell input stays with the shell.
Press Ctrl+B, release it, then press a command. They work in the CLI and desktop app.
| Command | Action |
|---|---|
c | New tab |
n / p | Next / previous tab |
% / " | Side-by-side / stacked split |
| Arrows | Focus a neighboring pane |
| Shift+arrows | Resize the nearest matching divider |
r | Rename active tab |
x / w | Close active pane / tab |
| Page Up / Page Down | Scroll history |
y | Copy pane selection using macOS pbcopy |
| Enter | Restart an exited or failed shell |
? | Keyboard help |
q | Quit workspace |
| Ctrl+B again | Forward a literal Ctrl+B to the shell |
| Escape | Cancel pending prefix command |
Ordinary keys, including Ctrl+C, go to the focused shell. Click a pane to focus it; drag over text to select it. The wheel scrolls the pane under the pointer. Live-session dialogs default to Cancel. Tab changes the selected action and Enter accepts; Escape cancels.
Pane minimums are 20 columns and 5 rows. When a window is too small for the split tree, only the focused pane appears. Prefix+arrows cycles through hidden panes. Enlarging the window restores the layout and saved split ratios.
Configure… opens qesh.config.json in a JSON editor with validation, Save, and Open in Editor. In source development it is at the project root. For packaged apps it is beside the .app, outside the signed bundle.
{
"defaultPath": "~",
"shell": "/bin/zsh",
"fontFamily": "Menlo, Monaco, monospace",
"fontSize": 14,
"tabsPosition": "left",
"theme": {
"background": "#0e0d11",
"surface": "#141318",
"foreground": "#d4d4d4",
"muted": "#a09ca8",
"border": "#45414e",
"primary": "#9cdcfe",
"error": "#f48771",
"selection": "#264f78"
}
}defaultPath accepts an absolute folder path or ~/~/…. shell must be an absolute executable path. Font size is 10–28; tabs can be left or top; theme colors use #RRGGBB. Invalid edits leave the previous configuration intact. A missing starting folder falls back to the home folder.
Saving updates font and tab placement in existing windows. Open a new window to apply the full terminal theme, starting folder, or shell. Editing settings does not restart existing shells.
Zsh command names use yellow, strings orange, keywords purple, variables/options blue, comments green, and unknown commands red. Unknown-command highlighting is feedback from zsh; it does not mean typing failed. Programs control their own true-color output; plain file output is not automatically syntax highlighted.
A scoped ZDOTDIR wrapper loads the user's .zshenv, .zprofile, .zshrc, and .zlogin in order. It does not rewrite dotfiles. History stays in the user's normal location rather than the app bundle. To retain your original prompt and highlighting:
QENTRAH_SHELL_STYLE=original qeshbun install
bun run build:appThis builds ../Qesh.app and places a default qesh.config.json beside it if one does not exist. To choose another path:
node scripts/build-macos-app.mjs /path/to/Qesh.appThe build refuses to overwrite an existing app. It bundles the local Bun and Node binaries, dependencies, source, licenses, and Qentrah icon, then applies and verifies a local signature. Build on the Mac architecture you intend to distribute; the current release is arm64. Signing with a Developer ID and notarization are not part of this build script.
To regenerate the icon, install Pillow and run python3 scripts/generate-app-icon.py. To build only desktop renderer assets, run bun run build:desktop.
Current limits: macOS first; no workspace restore across launches; no AI features or website integration. Workspace mouse events support focus, selection, and resizing; mouse input is not forwarded to child terminal programs. Fonts and glyph coverage depend on the selected terminal font.
bun run check
bun test
node scripts/smoke-cli.mjs
node scripts/smoke-desktop.mjs
bun run build:desktopThe macOS checks and builds workflow runs these checks on Apple Silicon (arm64) and Intel (x64), builds a standalone app on each native runner, smoke-tests its bundled Node/Bun runtimes and shell sessions, and verifies the app signature afterward. Every push, pull request, or manual Run workflow creates downloadable Qesh-macOS-arm64 and Qesh-macOS-x64 artifacts containing an app ZIP (with the sidecar configuration) and a SHA-256 checksum. Artifacts are retained for 30 days. Push a v* tag to attach both builds to its GitHub Release; a missing release is created as a preview. Builds use a local signature and are not notarized. Tests cover shell history/completion, Unicode, colors, multiline paste, Ctrl+C, vim/top, tab isolation, PID preservation, docking/detaching, config validation, geometry, narrow-window restoration, confirmation, copying, startup, and cleanup. Clipboard tests inject an adapter without changing the system clipboard. Smoke checks run real PTYs and verify cursor placement and process cleanup.
See CONTRIBUTING.md for contributions and AGENTS.md for agent instructions. Bugs and feature requests belong in Issues.
Qesh's original source is MIT, copyright Qentrah. Third-party code retains its own licenses; see NOTICE.md, the vendored license files, and notices bundled with the desktop app. Qentrah's logo remains a brand mark; the software license does not grant trademark rights.