Devolutions.Terminal.Control
2026.3.4
Prefix Reserved
dotnet add package Devolutions.Terminal.Control --version 2026.3.4
NuGet\Install-Package Devolutions.Terminal.Control -Version 2026.3.4
<PackageReference Include="Devolutions.Terminal.Control" Version="2026.3.4" />
<PackageVersion Include="Devolutions.Terminal.Control" Version="2026.3.4" />
<PackageReference Include="Devolutions.Terminal.Control" />
paket add Devolutions.Terminal.Control --version 2026.3.4
#r "nuget: Devolutions.Terminal.Control, 2026.3.4"
#:package Devolutions.Terminal.Control@2026.3.4
#addin nuget:?package=Devolutions.Terminal.Control&version=2026.3.4
#tool nuget:?package=Devolutions.Terminal.Control&version=2026.3.4
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 (ConPTY on
Windows, PTY on Linux/macOS), and Windows Terminal-compatible settings parser
that TermControl depends on, so a single package reference is enough to
embed a fully functional terminal in any Avalonia application.
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;
await terminal.StartAsync(new ProfileSettings(), columns: 120, rows: 30);
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, displayScale) to calculate an initial grid
for the profile and display; pending layout changes made while the connection
starts are applied once it is ready.
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 | Versions 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. |
-
net10.0
- Avalonia (>= 12.1.1)
- Avalonia.Skia (>= 12.1.1)
- HarfBuzzSharp.NativeAssets.Linux (>= 8.3.1.5)
- Microsoft.Windows.Console.ConPTY (>= 1.24.260710001)
- SkiaSharp (>= 3.119.4)
- SkiaSharp.HarfBuzz (>= 3.119.4)
- SkiaSharp.NativeAssets.Linux (>= 3.119.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.