Skip to content

About

XenTerm Next by xue-ding-e: independent next-generation SSH/SFTP terminal in Rust, with CLI/MCP, headless packaging and Next-specific enhancements. Based on XenTerm; not an official release.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

181 Commits

Folders and files

Repository files navigation

XenTerm Next (XenTerm-Next) is an independent SSH, SFTP and terminal project created and maintained by xue-ding-e, building on ixbaicn/XenTerm. We develop our own next-generation terminal experience, including Next-specific enhancements and reviewed community fixes that may not yet be in upstream. It is not an official XenTerm release or a promise of upstream’s next version; upstream authorship, copyright and the MIT license are preserved.

Our development line is main. upstream-main preserves official history; a daily read-only workflow checks drift, and verified mirror fast-forwards are handled separately. Upstream updates never automatically replace Next features. See the branch policy.

XenTerm Next independently maintains its Rust + GPUI desktop architecture and does not follow upstream’s Rust-core + Flutter migration. Any migration requires an explicit decision from repository owner xue-ding-e; until then, only independently reviewed and tested upstream fixes applicable to the current GPUI architecture are candidates for integration. The upstream-main mirror and drift reports do not authorize a migration of Next’s main.

English · 简体中文

Download / Install

XenTerm Next

A lightweight SSH / SFTP / terminal client for Windows, macOS and Linux — written in Rust, no runtime, no JVM.

Stars Release Last commit License: MIT

XenTerm — SSH Terminal · SFTP · System Monitor


What is XenTerm Next

XenTerm Next is the independent terminal project by xue-ding-e, for people who want a native Rust desktop client and scriptable CLI / MCP workflows in one codebase. “Next” describes our own development direction: a next-generation experience built on XenTerm, with independently developed enhancements and carefully integrated community contributions. It does not designate the official upstream’s next release.

Why choose Next?

Next ships its own development and release line. Examples already implemented here, beyond upstream f25f6af as checked on 2026-10-16:

  • Private, no-overwrite GUI session exports: the GUI keeps the hardened export policy and reports an existing destination instead of falling back to a plain overwrite. See the implementation and regression tests.
  • Traceable Next desktop previews: our beta release pipeline publishes cross-platform packages tied to a successful main CI run, with source SHA, build metadata and SHA256 checksums. Download the current preview.
  • Dedicated headless server packaging: our headless build and release entry point reuses the existing shared core, checks the Ubuntu 22.04 ABI/runtime dependencies and can produce fixed-source releases. The shared CLI/MCP core builds on upstream work; the Next packaging is an additional workflow, not a separate implementation.
  • Installer build tooling and lifecycle tests: Windows MSI and macOS packaging include optional integrations with Windows and macOS regression coverage. These are installer build capabilities; the current rolling beta downloads are portable archives.

Upstream may adopt or independently add similar changes later. Other improvements here include reviewed contributions from the XenTerm community; their authors retain credit. “Available in Next” does not mean every feature was originally authored by us, nor that every Next change is awaiting an upstream PR.

If these workflows help you, star XenTerm Next to support the project and help other developers find it. Try the preview, report reproducible issues and follow our independent development here.

XenTerm is a native desktop terminal client that keeps the workflow people like about FinalShell — a resource-monitor sidebar, session management, tabbed terminals, an SFTP panel that follows your shell — while dropping the part they do not: several hundred megabytes of JVM. It is a single Rust binary with the interface built directly on GPUI, so there is no interpreter, no web runtime and no garbage collector in the process.

It is a client, not a re-implementation of a shell: SSH, Telnet and serial sessions talk to whatever runs on the other end, and local shells run in a real PTY / ConPTY.

Sessions SSH, local shell (PowerShell / cmd / WSL / $SHELL), Telnet, serial
Transfers SFTP file panel, batch download, ZMODEM in the terminal, WebDAV sync
Terminals Full VT/ANSI, mouse tracking, DEC line drawing, colour emoji, split panes
Monitoring Local + remote CPU / memory / swap / disk / network, remote process list
Automation A cli for scripts and CI, and an MCP server for AI clients
Interface GPUI-rendered, English / Simplified Chinese, collapsible docked panels

The interface

The window is a navigation rail and one page at a time — three pages, each owning its own state and reporting only what crosses its border to the shell:

  • Terminal — the working surface. A tab strip, nestable horizontal split panes, a floating command line with the quick-command and command-history popovers, the resource sidebar, and the file panel docked to the bottom or the right.
  • Sessions — the saved connections and the built-in local shells, with groups, import/export and the session editor.
  • Settings — everything in the table further down.

Two monitors are separate windows rather than panels, because they are tables you keep open beside the terminal while you work in it: the process monitor and the system information window. The transfer list, the tunnel list and the file panel are panels, so they stay attached to the window whose sessions they belong to.

Features

Sessions and connection

  • Four session types — SSH, local shell, Telnet and serial, in the same tabbed UI.
  • Local shells out of the box — PowerShell, cmd.exe and every configured WSL distribution on Windows; $SHELL elsewhere. Windows shells start in UTF-8.
  • Ordered SSH bastions — add saved SSH sessions on the session editor’s SSH bastions page, move any hop earlier/later, or remove it. The displayed order is outermost first; each hop uses its own credentials. Existing jump_session_id configurations still work, including nested legacy routes.
  • SSH authentication — password, private key, passphrase-protected key, and keyboard-interactive for 2FA / OTP prompts.
  • PuTTY .ppk keys — PPK v2/v3 is decrypted and verified in memory; no puttygen round-trip.
  • Outbound proxies — SOCKS5 (socks5://, socks5h://) and HTTP/HTTPS CONNECT, set per session or picked up from ALL_PROXY. Telnet uses the same plumbing.
  • Serial — configurable baud rate, data/stop bits, parity and flow control.
  • Telnet with an RFC 854/855 option state machine (SGA + NAWS window resizing).
  • Triggers — expect/send rules for interactive logins, each with its own response.
  • Session groups — create, rename and delete folders, plus per-session notes.
  • Host key verification — trust on first use with a SHA-256 fingerprint prompt, and a hard warning if a key later changes.

Session passwords and keys can also be entered without the GUI, and the config supports per-session encodings. Ordered jump routes can be edited in the GUI. Imported jump_session_ids are ordered from the outermost bastion toward the target; when present, they override legacy jump_session_id links. Invalid, repeated, missing, non-SSH or more-than-16-hop routes fail before network activity.

Terminal

  • Full VT/ANSI emulation — htop, btop, vim, tmux and friends render correctly full-screen, over a 100,000-line scrollback.
  • Mouse tracking — SGR and X10 mouse reports are forwarded to TUI applications that ask for them, so htop and mc respond to clicks.
  • DEC line drawing — the VT100 special-graphics charset, so dialog and mc frames draw properly even in UTF-8 mode.
  • Colour emoji — skin tones, flags and ZWJ sequences render in colour, from Twemoji images embedded in the binary.
  • Character encodings — the terminal decodes per-session charsets (UTF-8 by default, GBK and others) with a streaming decoder, so a multi-byte character split across packets still decodes.
  • Output highlighting — colour log levels (with a DevOps preset) and your own rules, without disturbing output that already carries its own colours.
  • Split panes — nestable horizontal splits, from the tab's context menu; drag the splitter to resize. Tabs reorder by dragging within the strip or from the same menu.
  • Find in the scrollback, paging keys that scroll the scrollback on the normal screen and reach the program on the alternate screen as they should.
  • Paste protection — multi-line pastes can require confirmation, and the extra paste shortcuts (Ctrl+Alt+V, Shift+Insert) can be turned off.
  • Font and cursor — any installed monospace family plus a bundled one, size, line spacing, bold, and block / bar / underline cursors with a custom colour.

Static terminal wallpaper (opt-in)

Open Settings → Wallpaper, import a PNG, JPEG, WebP or BMP, and enable the preview. Apply saves the complete draft; Cancel changes restores the saved settings, and Reset draft to defaults does not save. Profiles upgrading from before this feature start disabled, even with choices from the retired interface.

  • Cover, Contain, Stretch, Original and Tile; nine anchor presets, offsets and zoom.
  • Non-destructive crop, arbitrary rotation, quarter-turn shortcuts and both flips; EXIF orientation is applied before editing.
  • Separate image opacity and dark readability overlay, brightness, saturation and blur. These effects do not change text, explicit cell backgrounds, selections or cursor rendering.
  • Each terminal pane repeats the layout independently. Continuous terminal canvas aligns terminal images in window coordinates across split panes; it does not make toolbars, sidebars, settings or dialogs transparent. The editor previews one canvas. There is no automatic theme recolouring.

Imports are local, immutable content-hash copies in the profile's wallpapers/ folder. Original bytes, including metadata, are preserved; cancelling a draft may leave its imported original there. When moving a complete profile, carry this folder alongside sessions.db; session exports and WebDAV do not bundle images. Missing or invalid assets fall back to the terminal colour and report an error in the editor. No remote image URLs, animated backgrounds, SVG or video are supported.

Limits: 32 MiB per imported file, 33,554,432 decoded pixels and 16,384 pixels per source edge. Processed textures are limited to 4,194,304 pixels and a 4,096-pixel edge; Original layout retains the logical source dimensions after downsampling. Decode/transform work is debounced, serialized off the UI thread and cached; these per-image limits are not a total application-memory cap.

The control vocabulary draws on the official documentation for Windows Terminal, IntelliJ IDEA and WezTerm. No wallpaper artwork or implementation code is copied from these projects.

Verification commands: cargo check --locked, cargo test --locked wallpaper, cargo test --locked, and cargo test --locked --no-default-features --features headless. The implementation has Linux native GUI coverage; Windows and macOS native GUI behaviour still require platform testing.

Files

  • SFTP panel that follows the terminal's cd, with a lazy-loading directory tree.
  • Upload and download single files or whole directory trees, from the toolbar or the file panel's context menu.
  • Batch download — the selection is tarred on the remote side, pulled down as one file, and the remote temp file is cleaned up.
  • Built-in viewer / editor — a plain text editor for small files, read-only when the file is; opening a file in your own editor re-uploads it when you save.
  • File operations — rename, delete, create file or directory, and chmod that keeps the setuid / setgid / sticky bits.
  • Copy between sessions — move remote files from one SFTP session into another.
  • Conflict handling — replace or keep both, per download.
  • ZMODEM in the terminal: sz on the remote downloads to your Downloads folder; rz opens a local file picker and uploads over the existing PTY.
  • WebDAV sync — upload and download the connection list by hand, with an option to accept self-signed certificates.

Monitoring

  • Local system panel — CPU, memory, swap, network throughput and per-filesystem usage, with sparklines.
  • Remote monitoring over SSH — the same metrics read from /proc and df on the server, refreshed every two seconds.
  • Remote process list — CPU-sorted, with copyable PIDs and the ability to terminate a process you own (signalling another user's process asks first).
  • System information window — OS, kernel, architecture, hostname, CPU, memory, filesystems and GPU.

Automation

  • CLI — one-shot SSH commands, file listing / reading / transfer, and session inspection, with human-readable output or --json.
  • MCP server — exposes the same saved sessions to an MCP-capable AI client over local stdio: session lookup, remote commands, directory listing, bounded text reads, uploads and downloads. Each capability is behind its own permission switch, and credentials are never returned to the client.

Screenshots

XenTerm on the Terminal page with nothing connected
The landing view: the navigation rail, the status panel on the left, and Connect / New session / Import

A local PowerShell session with the file panel docked below
A local PowerShell session in a tab, with the file panel docked underneath

Install

Download the verified GPUI preview

No Rust toolchain is needed for these portable downloads. These links select source 8819e2ec1327 from the rolling beta, verified on 2026-10-30. The beta page may also contain older source versions; download the archive and manifests with the same full SHA.

Platform Direct download
Windows x86_64 ZIP
Linux x86_64 tar.gz
macOS Apple Silicon ZIP

SHA256 checksums · Build provenance

Before opening a download, compare its SHA256 with its exact filename in the checksum file: Windows PowerShell Get-FileHash -Algorithm SHA256 <archive>, macOS shasum -a 256 <archive>, or Linux sha256sum <archive>. A matching checksum detects corruption; it is not a publisher signature. These are beta previews, not a stable-release or full native-UI validation claim.

Windows: extract and open

  1. Download the Windows ZIP above and verify its checksum.
  2. Use Extract All; open the extracted XenTerm-Next-beta-8819e2ec132760047209e9dcff7341c5f8a15f94-windows-x86_64 folder.
  3. Double-click xenterm.exe. Keep the accompanying license and attribution files. Optionally create a shortcut to this executable.

This preview is unsigned. If Windows blocks it or reports a security warning, stop and review the source and release provenance; do not disable security protections. The current beta does not publish an MSI installer.

macOS: Apple Silicon only

  1. Download the macOS ZIP above and verify its checksum.
  2. Double-click it in Finder to extract XenTerm Next.app.
  3. Optionally move that app to Applications without overwriting an existing copy, then open it.

This preview is ad-hoc signed, not Developer ID signed or notarized. If macOS blocks it, stop and review the release provenance; do not remove quarantine or disable Gatekeeper as a routine installation step. No Intel Mac or PKG download is provided by this beta.

Linux: extract and open

Built on Ubuntu 22.04; requires glibc ≥ 2.35 and system GUI libraries. After downloading the Linux archive and verifying its checksum, run from the download directory:

tar -xzf XenTerm-Next-beta-8819e2ec132760047209e9dcff7341c5f8a15f94-linux-x86_64.tar.gz
cd XenTerm-Next-beta-8819e2ec132760047209e9dcff7341c5f8a15f94-linux-x86_64
./xenterm

Keep the extracted directory intact. Its RUNTIME.txt lists the build's runtime library dependencies; missing libraries must be installed with your distribution's package manager. This archive does not contain install-linux.sh; it is not a deb, Flatpak, AppImage, AUR package or a glibc 2.28 build.

Other packaging and source builds

Only assets listed in Next Releases are published Next downloads. Installer source capabilities are separate: Windows MSI, macOS PKG notes, and the Linux installation script. Their existence or CI checks do not mean an installer has been published for this preview. For developer builds, see Quick start. Official upstream releases are a different distribution and do not include all Next enhancements.

Before upgrading, close XenTerm and back up your complete profile, including external key and wallpaper files. Extract a new version separately rather than overwriting a running installation; see Configuration and data.

Quick start

Rust toolchain support

Evidence: Rust 1.99.1 Linux desktop CI, 1.88 failure, 1.92 failure, 1.93 failure.

The package's Rust 1.88 declaration is a feature-specific baseline, not a promise that every feature and platform supports Rust 1.88:

  • Linux headless: Rust 1.88 is verified with --locked --no-default-features --features headless.
  • Default Linux desktop: the current locked GUI dependencies declare a minimum of at least Rust 1.92. Actual checks reject Rust 1.88 and fail on Rust 1.92 because gpui-pre-util uses slice::as_array, stabilized in Rust 1.93. Rust 1.93 is not sufficient either: its check fails on std::hint::cold_path in gpui-pre, an API stabilized in Rust 1.95. Existing same-source Linux desktop CI passed on Rust 1.99.1; this is a verified toolchain, not proof of the minimum version.
  • Windows and macOS desktop: existing CI verifies stable Rust, not a fixed minimum Rust version. Compilation does not replace native interaction testing.

Keep Cargo.lock and use --locked. Do not ignore Rust-version checks or downgrade GPUI dependencies merely to force the headless minimum onto desktop builds. Tracking and exact evidence: issue #11.

git clone --branch main https://github.com/xue-ding-e/XenTerm-Next.git
cd XenTerm-Next
cargo run --release

On first launch XenTerm creates an empty session store. Add your first server with New Session, or import one — ~/.ssh/config, a FinalShell connection export, a previous XenTerm export, or a pasted host|port|user|password|name list are all supported.

Headless CLI / authenticated remote MCP

Build without the GPUI desktop libraries:

cargo build --locked --release --no-default-features --features headless

The default build still includes the complete GUI, CLI and stdio MCP. The opt-in HTTP service uses external OAuth access tokens, a deliberately selected private profile, and an existing HTTPS reverse proxy. See remote MCP deployment and verification, including OpenResty routing for multiple MCP services on one domain. No public listener, account or deployment is created by the build.

Building on Linux

cargo run needs the system development packages the GUI stack links against:

sudo apt update
sudo apt install -y --no-install-recommends \
  build-essential pkg-config cmake \
  libfontconfig1-dev libfreetype6-dev \
  libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev \
  libxkbcommon-dev libxkbcommon-x11-dev libwayland-dev \
  libgl1-mesa-dev libegl1-mesa-dev libgtk-3-dev \
  libudev-dev

Keyboard shortcuts

⌘ denotes Command on macOS, where other platforms use Ctrl. The clipboard set is deliberate: plain Ctrl+C stays SIGINT, which is the one shortcut a terminal must not take away.

Keys Action
Ctrl+Tab / Ctrl+Shift+Tab Next / previous tab
Ctrl+K Quick-connect palette
Enter on a dead session Reconnect it
Ctrl+Shift+C Copy selection
Ctrl+V / Ctrl+Shift+V Paste
Ctrl+Alt+V / Shift+Insert Extra paste shortcuts (switchable)
Ctrl+F Find in the terminal; Esc closes the bar
Ctrl+= / Ctrl+- / Ctrl+0 Zoom this session's font
PageUp / Home / PageDown / End Scroll the scrollback (normal screen only)

A second window is opened from the operating system's own entry point — the Windows taskbar jump list, the macOS dock menu, or the desktop action on Linux.

Settings

Interface — theme (system / dark / light), panel font size, and the interface language. Terminal

Page Settings
Font Family (any installed monospace family, plus the bundled one), size, bold, line spacing
Cursor Shape (block / bar / underline) and colour
Input Confirm multi-line paste; the extra paste shortcuts; panel strip height
Highlight Enable output highlighting, the preset (log levels / DevOps), and your own rules with add / enable / delete

Connections — import ~/.ssh/config, export every saved connection to a file. Pasting (under Connections) — paste a host|port|user|password|name list and import it in bulk. Files — a default download directory and whether to always ask where to save. Sync — WebDAV: enable, address, username, password, remote path, accept invalid certificates, and the upload / download buttons. Automation — the four switches, split by what they actually govern: Unattended access (use saved credentials, allow arbitrary SSH commands, allow file transfers) and the MCP server's own MCP server switch.

CLI and MCP

The CLI and the MCP server share the sessions saved in the GUI and the same SSH / SFTP implementation, so there is only one server list to maintain. The CLI suits scripts, CI and explicit commands; MCP lets an AI client do inspection, log analysis and file transfers from a natural-language request.

Connect to the target session in the GUI at least once first, so the host key is confirmed. Normal CLI/MCP responses do not expose passwords or private keys. Explicit CLI exports write recoverable credentials to a private file; do not put plaintext passwords into prompts or MCP configuration files.

CLI

xenterm cli help
# List saved sessions; the first column is the session-id used below
xenterm cli sessions
xenterm cli sessions --json

# Non-secret metadata for one session
xenterm cli session <session-id>

# Run a non-interactive command; the remote command follows --
xenterm cli exec <session-id> -- free -h
xenterm cli exec <session-id> --timeout 60 --json -- journalctl -n 100 --no-pager

# Browse, read and transfer remote files
xenterm cli files <session-id> /var/log
xenterm cli read <session-id> /var/log/example.log
xenterm cli upload <session-id> ./local.txt /tmp
xenterm cli download <session-id> /tmp/result.txt ./downloads

# Inspect the effective access policy without changing it
xenterm cli permissions --json

# Explicit private export: choose a new file outside the profile directory
xenterm cli export ./private-sessions.json --include-credentials

# Preview an append-only import before applying it
xenterm cli import ./private-sessions.json --dry-run --json

# Preview stable-ID migration in an independent profile with local credential storage
xenterm --data-dir ./migration-profile cli import ./private-sessions.json --preserve-ids --dry-run --json
xenterm --data-dir ./migration-profile cli sync-native ./sessions.json --dry-run --json

Downloads require an existing local destination directory and will not overwrite a file of the same name.

Portable exports contain recoverable credentials and must be kept private. They include saved sessions, not global settings, trusted host keys or external key files. Export refuses an existing destination. Import and sync-native examples above are previews; removing --dry-run writes configuration. For migration from another profile, start with a portable import. Native encrypted snapshots still require the matching local encryption key; importing portable sessions does not make another profile's ciphertext readable, and OS keyring markers cannot be imported. Headless CLI/MCP also requires an explicit independent --data-dir (before the subcommand) or XENTERM_DATA_DIR; do not point it at the desktop profile. See profile migration.

MCP

Open Settings → Automation → MCP server in XenTerm and turn on what you need: enable MCP, then allow saved credentials, arbitrary SSH commands and file transfers as your use case requires. The three unattended-access switches default to on while MCP is in preview.

Then register the stdio server in your MCP client:

{
  "mcpServers": {
    "xenterm": {
      "command": "/absolute/path/to/xenterm",
      "args": ["mcp", "serve"]
    }
  }
}

On Windows, command can be C:\\path\\to\\xenterm.exe. Restart or refresh the client and you should see an xenterm server exposing the tools registered in src/mcp/impls/tools.rs: get_access_policy, export_sessions, import_sessions, list_sessions, get_session, run_command, list_remote_files, read_remote_text_file, upload_file, and download_file. MCP configuration files live in different places per client, so check that client's documentation.

get_access_policy is read-only. import_sessions previews by default; applying an import requires starting MCP with --allow-config-import, and file-transfer permission is required for both preview and apply. export_sessions and xenterm cli export use the same shared implementation. It requires the saved-credentials permission and an explicit include_credentials: true acknowledgement. MCP callers need both saved-credentials and file-transfer permissions. The export is reversible obfuscation, not confidential encryption; treat the output as a password file. The destination must be new and outside the source profile directory.

Debugging the stdio connection

An AI client generates these requests for you. When debugging by hand, send each one as a single line of JSON, in this order:

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"example-client","version":"1.0.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}

List sessions, then run a read-only OOM diagnosis and browse the heap-dump directory:

{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"list_sessions","arguments":{}}}
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"run_command","arguments":{"session_id":"<session-id>","command":"free -h; dmesg 2>/dev/null | grep -iE 'oom|killed process' | tail -50 || true; ps -ef | grep '[j]ava'","timeout_seconds":30,"max_output_bytes":1048576}}}
{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"list_remote_files","arguments":{"session_id":"<session-id>","path":"/home/jeff/test/heapdumps"}}}

read_remote_text_file accepts only bounded UTF-8 text; for binaries such as HPROF use download_file, which requires an existing local directory and will not overwrite a file of the same name.

A prompt you could give an MCP-capable client:

Use the xenterm MCP to investigate an OOM on my 192.168.100.41 server. Heap dumps are in /home/jeff/test/heapdumps. Check system memory, kernel OOM records, Java processes, application logs and the HPROF files, then identify the root cause. Read-only diagnostics first — do not restart services or delete files.

The server finds the session with list_sessions and then acts within the permissions you granted. If several sessions share a host, name the GUI session in the prompt.

Configuration and data

XenTerm is portable-first: if a writable config/ folder sits next to the executable (a USB stick, an extracted tarball), everything lives there. Otherwise it falls back to the per-user OS config directory:

Platform Location
Windows %APPDATA%\xenterm\XenTerm\config
Linux ~/.config/xenterm
macOS ~/Library/Application Support/dev.xenterm.XenTerm

Upgrading from the pre-rename build (meatshell) migrates sessions.json, secret.key and known_hosts automatically — copies are left in place, and existing files are never overwritten. Diagnostics go to a separate log/ directory beside the config, with error.log capped at 50 MiB.

Security notes

  • Passwords at rest go to the OS keychain (Windows Credential Manager, macOS Keychain, Linux Secret Service) whenever it is available. When it is not, they are encrypted with ChaCha20-Poly1305 under a per-install key in secret.key, so sessions.json never contains a plaintext password.
  • Exported connection lists are portable, not secret. The export format uses a fixed key compiled into the binary so a file opens on any machine — that is obfuscation, the same level as a FinalShell export, not encryption to rely on.
  • Host keys are remembered by XenTerm itself in its own known_hosts file (a host:port <key-type> <base64> format), which is not OpenSSH's file.
  • Secrets are zeroed on drop, so plaintext credentials do not linger in freed memory.

Tech stack

Layer Choice
UI GPUI via gpui-kit — GPU-rendered Rust UI, compiled in
Async runtime tokio
SSH / SFTP russh + russh-sftp — pure Rust, no libssh
Terminal emulation rio-vt native grid, scrollback and reflow
Local PTY portable-pty
Serial ports serialport
System metrics sysinfo
Encryption chacha20poly1305; PPK via aes + argon2
Serialization serde + serde_json
Logging tracing + tracing-subscriber

Project layout

xenterm/
├── Cargo.toml
├── build.rs                    # embeds assets/xenterm.ico on Windows
├── ui/fonts/                   # bundled terminal font (regular + bold) and the icon font
├── assets/                     # icons, banner, desktop entry, Linux installer
├── packaging/                  # AUR PKGBUILD and the Flatpak manifest
└── src/
    ├── main.rs                 # entry point: UI, `cli`, `mcp serve`
    ├── ui/                     # the shell — pages, panels, dialogs, detached windows
    │   ├── impls/pages/        # the three pages: terminal, sessions, settings
    │   └── impls/              # panels, dialogs, the terminal view and the shell
    ├── app/                    # session models, the PTY pump, window/jump-list plumbing
    ├── core/                   # toolkit-free state: tabs, panes, maps, histories
    ├── cli/  mcp/  automation/ # script and AI entry points over one dispatcher
    ├── config/                 # sessions.json, encryption, keychain, import/export
    ├── ssh/  sftp/  tunnel/    # protocols and plumbing
    ├── terminal/               # VT parsing, rendering, ZMODEM, serial, Telnet
    ├── resource/               # local sampling and remote metric parsing
    ├── webdav/  i18n/  layout/  logging/
    └── allocator/              # jemalloc on Unix, mimalloc on Windows

Development

Windows local update and build

For XenTerm Next, install Git for Windows, Rust with the MSVC target, and Visual Studio C++ Build Tools, then run Update-Local.cmd from a checkout directly below your workspace directory. It pulls xue-ding-e/XenTerm-Next main into a separate source-next checkout, builds the desktop with --release --locked, and installs desktop shortcuts. Existing development changes are left in their checkout. An unchanged, verified commit reuses its build.

The executable stays at <workspace>\runtime\current\xenterm.exe and uses the existing <workspace>\data profile. One previous package is retained. If current GUI/MCP processes are running, the update waits in pending; close those processes and open the desktop shortcut to apply it. Preview with powershell -NoProfile -File scripts\update-local.ps1 -WorkspaceRoot <workspace> -DryRun.

scripts\clean-local.ps1 -WorkspaceRoot <workspace> previews obsolete local artifacts; add -Apply to remove them. It retains the reusable release cache, profile directories, directory links and registered WSL disks. Runtime handoff and cleanup tests are tests\local_runtime_test.ps1 -Exe <portable-exe> and tests\local_cleanup_test.ps1.

Before contributing, read the contribution guide (also available in 简体中文) for PR scope, conflict handling, review readiness, and API compatibility checks.

  • The interface is GPUI only. There is no feature flag to build against and no second frontend to keep in step. A bare xenterm launch and the migration-era xenterm gpui argument both open the same shell.
  • A page is a view with its own state, built on first entry and kept after that, so a half-typed filter or a scroll position survives switching away. The shell renders exactly one page per frame; anything that cannot be done inside the page is queued and drained by the shell at the top of the next frame, which is also why a click is never carried out inside the render that received it.
  • The interface uses icon-font glyphs and words, never emoji — enforced by a test that scans src/ui, because a check that ran once is a fact about that day rather than a property of the code.
  • Translations are pairs of literals, not a catalogue: crate::i18n::t("中文", "English") picks by the current language flag, and both languages ship in the binary.
  • cargo check is the fastest feedback loop while editing the UI.
  • Run the test suite with cargo test; the integration tests live under tests/app/. Only the three suites wired in through #[path] are actually compiled today, so add a new module to mod.rs rather than only creating the file.

Release

Do not bump Cargo.toml by hand and then tag it. Use the release script, so the tag points at a commit that already carries the matching version:

.\scripts\release.ps1 v0.7.4 -Push

It requires no uncommitted tracked-file changes, updates Cargo.toml and the xenterm entry in Cargo.lock, runs cargo check --locked, verifies xenterm --version, commits Release v0.7.4 and creates an annotated tag, then pushes the branch and tag. See docs/release.md.

Release build requirements: Linux runners need development packages for GPUI's platform libraries, and GPUI's Windows release build requires fxc.exe from the Windows SDK (debug builds skip that step). The existing beta workflow provisions these prerequisites; local release builds must provide them too. See Cargo.toml and the release workflows.

Community

QQ group QR code
Scan to join the QQ group for usage questions, bug reports and release news

Acknowledgements

License

Released under the MIT license. Contributions are accepted under the same terms.

Third-party attributions — including the Twemoji artwork used for colour emoji — are in THIRD_PARTY_NOTICES.md.

About

XenTerm Next by xue-ding-e: independent next-generation SSH/SFTP terminal in Rust, with CLI/MCP, headless packaging and Next-specific enhancements. Based on XenTerm; not an official release.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages