Devolutions.Terminal.Control 2026.3.6

Prefix Reserved
dotnet add package Devolutions.Terminal.Control --version 2026.3.6
                    
NuGet\Install-Package Devolutions.Terminal.Control -Version 2026.3.6
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Devolutions.Terminal.Control" Version="2026.3.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Devolutions.Terminal.Control" Version="2026.3.6" />
                    
Directory.Packages.props
<PackageReference Include="Devolutions.Terminal.Control" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Devolutions.Terminal.Control --version 2026.3.6
                    
#r "nuget: Devolutions.Terminal.Control, 2026.3.6"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Devolutions.Terminal.Control@2026.3.6
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Devolutions.Terminal.Control&version=2026.3.6
                    
Install as a Cake Addin
#tool nuget:?package=Devolutions.Terminal.Control&version=2026.3.6
                    
Install as a Cake Tool

Devolutions.Terminal.Control

A self-contained, NativeAOT-friendly Avalonia terminal control (TermControl) extracted from Devolutions Terminal.

This package bundles the VT engine, renderer, connection layer, and Windows Terminal-compatible settings parser that TermControl depends on, plus the native process hosts that local shells need, so a single package reference is enough to embed a fully functional terminal in any Avalonia application on Windows, Linux, and macOS.

Getting started

<ItemGroup>
  <PackageReference Include="Devolutions.Terminal.Control" Version="*" />
</ItemGroup>

TermControl has no parameterless constructor usable from XAML (its constructor takes an optional ITerminalEngine), so create and start it in code-behind instead of declaring it as a XAML element:

using Devolutions.Terminal;
using Devolutions.Terminal.Settings;

var terminal = new TermControl();
Content = terminal;
var profile = OperatingSystem.IsWindows()
    ? new ProfileSettings()
    : new ProfileSettings { Commandline = Environment.GetEnvironmentVariable("SHELL") ?? "/bin/sh" };
await terminal.StartAsync(profile, columns: 120, rows: 30);

ProfileSettings defaults to Windows PowerShell, so set Commandline to a Unix shell on Linux and macOS.

The columns and rows passed to StartAsync set both the engine and PTY initially, even if the control was arranged at a different size before startup. Subsequent layout passes resize both to fit the available space. You can use TermControl.MeasureCell(profile, scale) to calculate an initial grid for the profile and display; pending layout changes made while the connection starts are applied once it is ready.

Local shells and native hosts

Platform Transport Native host in the package
Windows x86/x64/ARM64 ConPTY OpenConsole.exe under tools/conpty, copied by the package's build targets
Linux x64/ARM64 forkpty relay dt-pty-host under runtimes/linux-<arch>/native
macOS x64/ARM64 (13.0+) forkpty relay dt-pty-host under runtimes/osx-<arch>/native

On Linux and macOS, a RID-specific build or publish (-r linux-x64, -r osx-arm64, and so on) places dt-pty-host next to your executable. A RID-less build keeps it under runtimes/<rid>/native/, and the control finds it there. NuGet does not preserve Unix file modes, so the package's build targets mark the host executable when you build on Linux or macOS, and the control sets the execute bit at startup if the host was deployed without it. If your app is installed somewhere the process cannot write, make sure your packaging keeps dt-pty-host executable (mode 0755). The Linux host requires glibc 2.31 or later.

Stream an asciicast recording

The control can stream a recording to a caller-supplied WebSocket push URI while retaining the recording locally for save or replay:

// The application owns endpoint discovery and authentication. For a DVLS
// recording push URL, the signed token is already present in the query string.
var recordingUri = new Uri(
    "wss://gateway.example/jet/jrec/push/session-id?token=signed-token");

await terminal.StartRecordingAsync(recordingUri);
// Terminal output is now sent as asciicast v2 JSONL text frames.
await terminal.StopRecordingAsync();

StartRecordingAsync preserves existing query parameters and adds fileType=asciicast. It opens a plain WebSocket without a subprotocol, sends the v2 header first, then streams output events with elapsed timestamps and CRLF-normalized text. The terminal's visible screen is included as the initial frame. Pass the optional path argument to save the same recording to disk when it stops.

For an official asciinema server, create a live stream through its HTTP API and pass the returned ws_producer_url with the desired format:

var producerUri = new Uri(streamResponse.WsProducerUrl);
await terminal.StartRecordingAsync(producerUri, AsciicastFormat.V3);
// Terminal output is sent using the v3.asciicast WebSocket subprotocol.
await terminal.StopRecordingAsync();

This overload supports both AsciicastFormat.V2 and AsciicastFormat.V3, negotiates the corresponding v2.asciicast or v3.asciicast subprotocol, and leaves the producer URI unchanged. V2 streams use elapsed timestamps; v3 streams use per-event time deltas as required by the asciicast v3 format.

Endpoint construction, token acquisition, and authentication remain the host application's responsibility. RecordingStreamCompletion can be awaited to confirm that queued frames were flushed, and RecordingStreamError exposes the last transport failure.

See the samples/Devolutions.Terminal.Control.Sample project in the Devolutions Terminal repository for a full working app, plus the full source and documentation.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2026.3.6 136 10/28/2026
2026.3.5 109 10/21/2026
2026.3.4 334 10/9/2026
2026.3.3 134 9/30/2026
2026.3.2 6,669 9/18/2026