A cross-platform graphical terminal emulator and native SSH client, written in Rust.
A direct Dev Tunnels experiment, included in default desktop builds, exports one existing daemon session through a separate bridge. It is GitHub-provisioned and not production-qualified. Native GitHub device sign-in and tunnel-name discovery use the SDK-published Microsoft Dev Tunnels GitHub application, without a client secret or per-user registration; broader native service qualification remains open under #429; advanced scoped-token activation remains available.
The host also offers an explicitly enabled rooted filesystem protocol for enumeration and streaming transfers. Desktop/iOS file-manager integration is separate work; the grant is off by default and can be changed/revoked on an existing host.
An independent read-only observation protocol adds explicitly approved roots, revision-checked offset reads, bounded native watches and daemon generation correlation. It never grants transfer writes or MCP consent; the stacked broker integration requires separate native per-controller, exact-tab/root approval. Native service qualification remains open.
Note
AI authorship: fesTerm's code, tests, documentation, and first-party assets were written entirely by GitHub Copilot under human guidance. The human project owner defines the product direction, requirements, priorities, acceptance decisions, and release authorization. Third-party dependencies, including vendored crates, retain their upstream authorship and licenses.
Desktop split-pane composition is available as a staged feature (#65, ADR 0078). The live two-to-four-pane slice preserves existing session/document ownership and now includes transient handles, explicit rearrangement and atomic live-view swaps. Hover handles now default off; explicit rearrangement remains available. The desktop command palette uses a larger grouped layout with a category sidebar and a compact category picker in narrow windows. Named recipes, independent recovery preferences and native qualification remain open.
Synchronized terminal recording is implemented as a proposed desktop and mobile feature: selected sessions share a timeline and export separate silent MP4s. Recordings can contain sensitive terminal output; platform-native recording, export and privacy qualification remains open (ADR 0077).
An Android port now hosts the existing iOS mobile application, with native input, Keystore credentials, document imports, device authentication and on-device speech adapters. Development APKs build with the Android SDK/NDK; physical-device and live-service qualification remain separate from shared tests and emulator evidence (ADR 0073).
The iOS port has started with an isolated rendering/lifecycle
spike, reusing the terminal core and renderer.
The first input surface uses the same terminal-above-persistent-keyboard
layout on iPhone and iPad, with sticky Ctrl/Alt/Shift and a docked terminal-key row.
Long-press/drag sends arrows with a temporary helper and three repeat speeds.
Two-finger pinch scales terminal text within the shared zoom limits.
Affected PRs retain mobile unit/dependency checks, device compilation and
Simulator app builds. Nightly/manual iOS runs collect isolated iPhone/iPad
launch and screenshot evidence without gating desktop PRs.
The default remains an offline development harness. An opt-in live-ssh
prototype adds one transient connection with explicit host-key/password UI;
see the mobile host instructions.
Native/live-service and physical-device feasibility remain pending; mobile
product support is not accepted.
Milestones 0 through 5, M7, and M8 are implemented. M6 remains the open compatibility acceptance gate because fresh native-window and reference-application evidence is still incomplete; this is a formal compatibility certification and is tracked independently of whether 0.1.x development builds are packaged and released (see #50). M9 has configurable bounded logical scrollback, anchored viewport navigation, primary-screen resize reflow with selection remapping, read-only disconnected history, clear/reset commands, and eviction feedback.
The application now provides local PTY, native SSH, and serial sessions; independent session chips; Launcher, Profiles, and Settings surfaces; command palette and native macOS menus; focus mode; embedded JetBrains Mono with automatically downloaded optional terminal fonts and opt-in ligatures; deterministic UAX #29 grapheme-width allocation with pinned monochrome/color emoji fallback (ADR 0026); autosaved versioned TOML profiles/interface settings; metadata-only workspace restoration; and native secret-store references for saved SSH passwords and private keys. Persistent host-key trust is explicit and non-secret.
Explicit smart selection highlights sentences, paragraphs or indented blocks from terminal cells before a separate Copy. The local deterministic baseline conservatively isolates bordered/gapped row segments; general TUI-layout and native usability qualification remain open, without a model or network dependency.
SSH uses an in-process russh transport with fingerprint-first host
verification, password, in-memory OpenSSH-key, and transient OpenSSH
certificate authentication, remote PTY resize, periodic/on-demand liveness
probes, native wake hooks, and bounded recovery. Plain SSH reconnect always
creates a fresh shell and remains a manual action. Profiles may instead select
a named tmux or GNU Screen session; those providers launch without their own
status chrome, inherit the actual first PTY size, and may opt into bounded
automatic recovery. Controlled real-provider reattach evidence remains open in
#49. SSH-agent adapters,
keyboard-interactive/2FA, key-file references, and OpenSSH-config import remain
future work.
Native packaging and signed updates are implemented under ADR 0021: signed/notarized macOS ARM64 DMG, Authenticode-signed Windows x86_64 and ARM64 NSIS installers, Linux x86_64 and ARM64 AppImage and Debian packages, updater signatures, a protected tag-driven GitHub release workflow, and an explicit check/download/install UI. Signed production releases are published with macOS/Windows/Linux artifacts; end-to-end install/upgrade/uninstall and failure-path evidence (clean install, verified update, signature-rejection, and interrupted-download handling across all supported targets) remains tracked in #62, now scoped to that remaining evidence rather than to producing the first release itself. Custom terminfo remains #27.
An optional, fesTerm-owned local session-persistence daemon
(festerm-sessiond, ADR 0025)
ships alongside the packaged builds but is experimental: its ADR remains
Proposed pending the remaining cross-platform CP-11 package/manual
evidence and a local-IPC security review. The earlier Windows native-smoke
failure tracked in #71 is fixed,
but native local session persistence is still not a validated supported
capability until those broader checks complete and the ADR is formally
accepted. On Windows, new daemons execute release-versioned private runtime
copies and the package itself uses an immutable helper name, so
protocol-compatible sessions from 0.2.0 onward do not lock a file a later
installer must replace.
With Resume unattached local sessions from New Session enabled, Running
Sessions refreshes native sessiond, tmux and GNU screen inventories in bounded
background work. Reattach targets an existing generation only; a deleted or
recreated session produces an actionable Launcher error instead of a new shell.
Repeatable isolated provider churn is available through
python3 scripts/check_running_sessions.py and the optional-validation runners;
native GUI evidence is tracked separately in docs/manual-validation.md CP-12.
Desktop packages advertise fesTerm as an optional Open With handler for
.md and .markdown; festerm --open -- <paths...> opens the same document
tabs from a command line. Existing document views and unsaved text are preserved.
Linux AppImages require desktop integration to appear in Open With. Native
association lifecycle qualification is tracked in docs/manual-validation.md
CP-19; registration never changes the user's default Markdown application.
Markdown Preview also renders mermaid fences offline using a native renderer,
with selectable source fallback for unsupported syntax or preview limits;
see ADR 0050.
Markdown Preview and editor Preview/Split support bounded static local and inline SVG, plus native HTML links and named anchors. Other HTML stays inert; SVG cannot fetch external resources or discover system fonts. See the viewer design for the supported subset and limits.
-
PowerShell and enterprise development - experimental desktop PSRP profiles, structured sessions, enterprise discovery and generation-pinned remote sessiond attachment over SSH; not yet a supported corporate connection type.
-
Keyboard bindings and routing — persistent Settings editor, terminal-tool overlap inventory, clipboard provenance and bounded opt-in redacted input recording.
-
Agent guide — compact project map, invariants, and validation commands for coding agents and contributors.
-
Development handoff — bootstrap, current runtime behavior, diagnostics, manual checks, and resuming work.
-
Milestone progress narrative — concise story of the evidence-first process, parallel work, and current sequencing.
-
M6 compatibility checklist — reference application scenarios,
TERMstrategy, and regression triage. -
Configuration foundation — M8 schema version 1 profile document, secret boundary, atomic autosave, and restart-only external edit behavior.
-
GUI design — authoritative interaction model, independent session-chip principles, visual hierarchy, and canonical wireframe.
-
GUI SFTP design — split-pane local/remote file workflow, transfer safety policy, keyboard model, and interactive mockups.
-
Native Markdown viewer design — approved readability-first scope, resource security, lifecycle, and workflow mockups.
-
Native text editor design — one open file as one shared document, freshness and conflict policy, Save As, and vi bounds.
-
GUI exploration action graph — stable state and transition IDs with assertions, cancellation, inverse, and checkpoint recovery paths.
-
Validation traceability — machine-checked mappings from requirements and ADRs through graph edges to automated/manual evidence.
-
Native packaging — platform manifests, update trust, and package smoke workflow.
-
Signing and release operations — native signing, notarization, updater keys, publication, and credential rotation.
-
Icon system — first-party SVG sources, semantic Rust names, accessibility rules, color/state policy, and validation pipeline.
-
Terminal font assets — embedded JetBrains Mono plus pinned optional Iosevka Term, JuliaMono, and Maple Mono provenance, licensing, checksums, and reproducible selection/ligature policy.
-
UI and platform test plan — layered compatibility, interaction, rendering, PTY, and platform validation strategy.
-
Manual and usability validation registry — the canonical inventory of native, visual, accessibility, and human-use checks that cannot yet be treated as ordinary automated acceptance.
-
Project design — product direction, principles, experience, priorities, and open questions.
-
System architecture — proposed crates, dependency direction, runtime data flow, rendering boundary, concurrency, and invariants.
-
Requirements — functional, architectural, performance, security, diagnostics, and testing requirements.
-
Capability roadmap — foundation-first milestones and their completion criteria.
-
Compatibility plan — xterm-oriented behavior, feature tiers, fixtures, reference applications, PTY/SSH tests, and ligature rules.
-
Standards and implementation notes — primary specifications, interoperability guidance, security boundaries, and lessons from other terminal implementations.
-
Product positioning — terminal landscape notes and the selected middle-ground product posture.
-
MCP + JavaScript automation — owner-authorized staged campaign; default-off observation infrastructure is present, but MCP activation, JavaScript and terminal control remain unavailable until their platform security gates are qualified.
-
Architecture decision records — accepted decisions and their rationale.
-
Golden fixture format — terminal-core fixture grammar and regression guidance.
-
Original project outline — early framing retained for historical context.
- Behavioral compatibility with advanced full-screen terminal applications.
- Cross-platform
eguifront end with a GUI-independent terminal engine. - First-class local PTY and native in-process SSH session types.
- Human-readable, versioned TOML configuration loaded at startup and explicitly autosaved after profile, workspace, trust, credential-reference, and interface changes; external file edits are intentionally picked up only after restart.
- Fast interactive behavior, ligature-capable rendering, and privacy-aware diagnostics.
- Local-first operation; any future cross-machine portability should remain explicit (for example, export/import) rather than requiring an account or cloud synchronization service.
The PowerShell development workspace requires Rust 1.98 or newer (via
rustup) for its native PSRP dependencies. A named
toolchain can be used with cargo +1.98.0 without changing the global default.
cargo build --workspace
cargo run -p festermThe workspace has a large GUI/GPU dependency graph (eframe,
egui, wgpu, naga, Windows bindings, SSH dependencies), so cold and
repeated full-validation builds can be slow, especially on native Windows
ARM64. CI already caches Cargo registry/target artifacts via
Swatinem/rust-cache (see
.github/workflows/ci.yml); the following are optional, opt-in techniques for
local development. Neither is required — the repository works fine without
either configured. See docs/build-performance.md
for the full record of what has been measured and what remains open.
Optional sccache. sccache is a
compiler cache that works across separate Git worktrees of the same
repository (unlike Cargo's own incremental cache, which is keyed to a single
target directory). Install it (cargo install sccache or your package
manager), then set:
# any shell that persists env vars for your cargo invocations, e.g. ~/.cargo/config.toml:
[build]
rustc-wrapper = "sccache"or per-invocation via RUSTC_WRAPPER=sccache cargo build. sccache caches
compiled object code keyed by compiler flags/inputs, so a second worktree
building the same dependency versions reuses the cache even though it has its
own target directory. If sccache is not installed, Cargo silently ignores
an unset rustc-wrapper and behaves exactly as today.
Optional shared CARGO_TARGET_DIR. Setting CARGO_TARGET_DIR to the same
path across multiple worktrees of this repository lets them share compiled
dependency artifacts directly (no wrapper needed), which is effective when
working through feature branches sequentially in one worktree at a time:
export CARGO_TARGET_DIR="$HOME/.cargo-target/festerm"This does not eliminate lock contention for concurrent builds: Cargo takes
a file lock on the target directory for the duration of a build, so two
worktrees building against the same shared CARGO_TARGET_DIR at the same time
will serialize (Blocking waiting for file lock on build directory) rather
than run in parallel — confirmed by testing two simultaneous cargo check
invocations against a shared target directory from separate worktrees. Do not
point concurrent build agents/CI jobs at a shared CARGO_TARGET_DIR for this
reason; it is only a good fit for one developer working across worktrees one
at a time.