Icod.Terminal
1.2.0
See the version list below for details.
dotnet add package Icod.Terminal --version 1.2.0
NuGet\Install-Package Icod.Terminal -Version 1.2.0
<PackageReference Include="Icod.Terminal" Version="1.2.0" />
<PackageVersion Include="Icod.Terminal" Version="1.2.0" />
<PackageReference Include="Icod.Terminal" />
paket add Icod.Terminal --version 1.2.0
#r "nuget: Icod.Terminal, 1.2.0"
#:package Icod.Terminal@1.2.0
#addin nuget:?package=Icod.Terminal&version=1.2.0
#tool nuget:?package=Icod.Terminal&version=1.2.0
Icod.Terminal

Icod.Terminal is the managed, cross-platform live-terminal session layer for the Icod library family. It sits between Icod.TermInfo and higher-level consumers such as Icod.DCurses, terminal-aware command-line tools, monitors, editors, pagers, and REPLs.
Status
1.2.0 is the current 1.x release line and the second additive minor release after the stable 1.0 contract.
Version 1.2 adds typed, bounded urxvt-style OSC 777 titled desktop notifications without changing the meaning of existing 1.0/1.1 APIs. The existing OSC 9 notification API remains unchanged; OSC 777 is a separate explicit titled-notification path.
The stable 1.0 architecture, ownership, lifecycle, input/query, restoration, security, and compatibility guarantees remain the compatibility floor for the 1.x line. Version 1.1's typed VS Code OSC 633 surface remains unchanged.
Full release notes and concise release history:
Installation
dotnet add package Icod.Terminal --version 1.2.0
The package targets:
net8.0
net9.0
net10.0
and depends on Icod.TermInfo 1.10.0 and Icod.Timing 1.0.0.
Architecture
Icod.TermInfo
^
|
Icod.Terminal
^
|
Icod.DCurses
^
|
terminal applications
Icod.TermInfo is the immutable terminal-capability authority. Icod.Terminal owns the live terminal conversation: endpoint observation, terminal modes, input decoding, lifecycle, active query routing, semantic output, and scoped/reversible terminal state. Icod.DCurses owns the higher-level virtual-screen/curses presentation model.
PTY/process hosting remains orthogonal to this package.
Quick start
using Icod.Terminal;
await using TerminalSession session = await TerminalSession.OpenAsync(
new TerminalSessionOptions {
InputMode = TerminalInputMode.CBreak,
EchoInput = false
}
);
await session.WriteTextAsync( "Terminal session ready.\r\n" );
TerminalEvent terminalEvent = await session.ReadEventAsync(
TimeSpan.FromSeconds( 1 )
);
For a curses-style virtual screen, prefer Icod.DCurses rather than rebuilding windows/cells/diff policy directly over TerminalSession.
Core 1.x guarantees
One authoritative input path
A live TerminalSession owns the only authoritative input reader for its transport. Ordinary consumers use:
ReadEventAsync(...)for application input and lifecycle events;- typed query operations for terminal responses.
Do not run a competing Console.Read*, stream read, or retained custom-transport read on the same live terminal conversation.
Bounded query routing
Queries share the same incremental input/router domain as application input. The contract includes bounded parser state, ambiguity-aware query serialization, finite caller timeouts, pre-emission versus post-emission cancellation semantics, bounded late-response ownership, and lifecycle query generations.
A timeout is not automatically proof that the terminal does not support a feature.
Reversible ownership
Scoped state uses leases where overlapping ownership matters. The 1.x documentation distinguishes:
- exact restoration — a captured/observed external baseline is replayed exactly;
- terminal-policy reset — control returns to terminal policy without claiming the exact previous value;
- Icod-owned nested state — an outer library-owned value can be restored even when the pre-Icod state is not observable;
- ephemeral metadata — explicit output with no lifecycle replay/restoration state.
TerminalSession.DisposeAsync() remains final cleanup/restoration authority for session-owned state.
Output serialization boundary
Use session semantic operations for ordinary terminal output. TerminalSession.Output remains available only as an advanced borrowed transport and is outside normal session serialization when used directly by callers.
WriteTerminalStringAsync(...) is intended for already-resolved terminfo capability strings; it is not a recommendation to construct arbitrary OSC/CSI/vendor traffic manually.
Semantic terminal features
The supported semantic surface includes:
- application text and resolved terminfo capability output;
- terminal titles (OSC 0/1/2);
- current-location publication (OSC 7);
- hyperlinks (OSC 8);
- clipboard/selection operations and explicit reads (OSC 52);
- cursor style observation/ownership (DECSCUSR/DECRQSS);
- synchronized output (DEC private mode 2026);
- terminal progress (OSC 9;4);
- terminal pointer shape (OSC 22);
- portable semantic prompt/command metadata (OSC 133);
- typed VS Code shell integration (OSC 633);
- typed titled desktop notifications (OSC 777);
- indexed palette and selected dynamic terminal colors (OSC 4/104, 10–14, 17, 19 and resets);
- negotiated modern keyboard reporting;
- bracketed paste, focus, and mouse input protocols;
- bounded safe OSC 9 notification and Windows-CWD compatibility operations.
The safe OSC 9 subset intentionally excludes host-affecting vendor commands for sleep/blocking UI, GUI macros, process launch, environment disclosure, and emulator mutation.
Titled desktop notifications — OSC 777
The 1.2 OSC 777 API is explicit and semantic:
await session.SendTitledNotificationAsync(
"Build",
"Compilation complete"
);
It emits canonical OSC 777;notify;<title>;<message> ST framing using strict UTF-8 and a 4,096-byte complete OSC payload bound. Title and message may be empty, but semicolons, C0/C1/DEL controls, and malformed Unicode are rejected before output commitment because OSC 777 defines no interoperable field-escaping grammar.
SendNotificationAsync(message) remains the existing OSC 9 compatibility path. The library does not automatically choose between OSC 9 and OSC 777, infer support from terminal identity, or expose a generic raw OSC 777 dispatcher.
See docs/Osc777-Desktop-Notifications.md.
VS Code OSC 633
The 1.1 OSC 633 API is explicitly vendor-specific and typed. It provides semantic operations for A, B, C, D, and E command detection plus the stable documented P properties Cwd, IsWindows, ContinuationPrompt, and HasRichCommandDetection.
Command-line, Cwd, and ContinuationPrompt values use VS Code's protocol escaping before strict UTF-8 framing. Optional nonces are explicit bounded caller input for the command-line and current-directory forms that define them. The library does not expose a generic raw OSC 633 writer, does not infer VS Code support from terminal identity, and does not expose the unfinalized F/G, H/I, SetMark, or EnvJson/EnvSingle* extensions.
See docs/VsCode-Osc633-Shell-Integration.md.
Modern keyboard reporting
Modern keyboard reporting is opt-in through the compound input-protocol lease. Traditional keyboard decoding remains the compatibility floor.
The public modes are semantic:
Disambiguated
EventTypes
AllKeys
Kitty support is negotiated before reversible ownership is acquired. xterm modifyOtherKeys remains decode-only and is not blindly activated.
Security and privacy
Semantic APIs validate and bound terminal protocol data before commitment where the contract permits it. The library deliberately avoids a generic raw vendor-command API as the ordinary extension mechanism.
Several operations disclose caller-supplied metadata by design:
- clipboard contents;
- current filesystem locations;
- hyperlinks;
- OSC 133 command-line metadata;
- OSC 633 command-line/current-directory/continuation-prompt metadata and optional nonce;
- OSC 9 and OSC 777 desktop notification text/title;
- keyboard/mouse/focus/paste input.
The library does not automatically discover or redact secrets. Applications remain responsible for deciding what data is appropriate to publish.
Compatibility policy
Stable 1.0.0 remains the compatibility floor. Version 1.1.0 intentionally added the OSC 633 methods, and version 1.2.0 intentionally adds SendTitledNotificationAsync(...). Each minor release has its own machine-frozen public-API fingerprint across net8.0/net9.0/net10.0 while earlier baselines remain retained as compatibility evidence. Existing public enum numeric values remain part of the stable 1.x contract.
For the stable 1.x line:
- patch releases fix/harden the documented contract without intentionally breaking it;
- minor releases may add compatible API/semantic features with an intentional baseline update;
- ordinary removals, renames, signature breaks, enum renumbering, or incompatible ownership/security/restoration changes require a new major release.
Vendor runtime EOL alone is not sufficient reason to drop net8.0 or net9.0; a concrete security/toolchain/maintenance blocker is required.
Platform support
The built-in SystemTerminalControlProvider supports:
- Windows;
- Linux;
- macOS.
Other hosts receive controlled Unsupported results from the built-in provider. Custom implementations may be supplied through ITerminalControlProvider, ITerminalInput, and ITerminalOutput.
Permanent documentation
The permanent 1.x authorities include:
- Architecture
- Terminal Session and Ownership
- Lifecycle and Restoration
- Input and Events
- Queries and Responses
- Modern Keyboard Security and Compatibility
- Presentation and Reversible State
- Semantic Output Protocols
- VS Code OSC 633 Shell Integration
- OSC 777 Titled Desktop Notifications
- Security and Privacy
- Licensing
- Public API Baseline 1.0
- Public API Baseline 1.1
- Public API Baseline 1.2
- Compatibility and Versioning
- Migration to 1.0
Historical T-series, 0.x baselines, and the rc1 baseline remain available as design/release evidence.
Samples
Repository samples are indexed by task in samples/README.md. They cover session basics, rich input, queries, scoped presentation/state, colors, titles, location, hyperlinks, clipboard, semantic prompt metadata, and both legacy/titled desktop notifications.
Build and validation
On Windows:
build.cmd
On POSIX hosts:
sh build.sh
PR validation runs Windows/Linux/macOS runtime/source validation, the current machine public-API fingerprint, one portable package candidate, and four parallel package-contract shards retaining contracts from 0.8 through the stable 1.x release line. The package-candidate gate also verifies the exact project-appropriate GPL/LGPL header template for every tracked .cs and .csproj file.
The semantic package shard compiles and runs fresh NuGet-only OSC 633 and OSC 777 consumers on net8.0, net9.0, and net10.0 and verifies generated XML documentation for the corresponding public APIs.
The repository also runs current Icod.DCurses 0.1.0 integration/ownership acceptance, including a package-boundary soak against the freshly packed Terminal artifact. Because DCurses is still an early downstream, these checks are compatibility witnesses for the integration paths it currently exercises, not exhaustive proof of every Icod.Terminal 1.x contract. Terminal's own API, invariant, unit/hardening, and package gates remain the primary release evidence for the full surface.
After merge, Release distribution validation runs six Windows/Linux/macOS x64/ARM64 runtime jobs plus the single portable package/four-shard package contract.
Release process
1.2.0 is publishable only after the exact 1.2 PR head is green, the merge result passes Release distribution validation, and publication is explicitly authorized.
The tag-triggered workflow requires curated docs/releases/<version>.md release notes and re-runs the public API, hardening, historical package, stable release-line package, and current downstream compatibility gates before publication. It does not fall back to generic auto-generated GitHub notes.
Tagging triggers publication; no release tag should be created merely because a PR is green.
Development roadmap
Current release status is tracked in Icod.Terminal-Development-Roadmap.md. The completed rc1 program remains preserved in Icod.Terminal-1.0.0-rc1-Development-Roadmap.md.
Authors
Inspired by original work from Bill Joy, author of the original termcap; Mary Ann (born Mark) Horton, author of terminfo; Pavel Curtis, author of pcurses; and Zeyd Ben-Halim, Eric S. Raymond, and Thomas Dickey, whose work developed and maintained libtinfo and ncurses.
Managed .NET implementation by Timothy J. Bruce uniblab@hotmail.com.
Copyright
Copyright (c) 2026 Timothy J. Bruce
License
The published Icod.Terminal library package and the C# sources compiled into the library are licensed under LGPL-3.0-or-later.
Repository executable/test programs—including Icod.Terminal.Tests, samples, package smoke tests, validation utilities, and downstream acceptance tools—are licensed under GPL-3.0-or-later. Their GPL license does not change the LGPL license of the reusable Icod.Terminal library they consume.
The root LICENSE contains the LGPLv3 terms and the incorporated GPLv3 terms. See Licensing for the project-by-project policy and source-header requirements.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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
- Icod.TermInfo (>= 1.10.0)
- Icod.Timing (>= 1.0.0)
-
net8.0
- Icod.TermInfo (>= 1.10.0)
- Icod.Timing (>= 1.0.0)
-
net9.0
- Icod.TermInfo (>= 1.10.0)
- Icod.Timing (>= 1.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Icod.Terminal:
| Package | Downloads |
|---|---|
|
Icod.DCurses
Managed, cross-platform curses-like terminal UI library for .NET, built on Icod.TermInfo and Icod.Terminal. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.8.1 | 0 | 9/10/2026 |
| 1.8.0 | 0 | 9/10/2026 |
| 1.7.0 | 0 | 9/9/2026 |
| 1.6.0 | 52 | 9/9/2026 |
| 1.5.0 | 194 | 9/9/2026 |
| 1.4.0 | 512 | 9/9/2026 |
| 1.3.0 | 44 | 9/9/2026 |
| 1.2.0 | 44 | 9/9/2026 |
| 1.1.0 | 47 | 9/9/2026 |
| 1.0.0 | 1,372 | 9/8/2026 |
| 1.0.0-rc1 | 66 | 9/7/2026 |
| 0.18.0 | 65 | 9/7/2026 |
| 0.17.0 | 72 | 9/7/2026 |
| 0.16.0 | 81 | 9/6/2026 |
| 0.15.0 | 64 | 9/6/2026 |
| 0.14.0 | 72 | 9/6/2026 |
| 0.13.0 | 77 | 9/6/2026 |
| 0.12.0 | 64 | 9/5/2026 |
| 0.11.0 | 65 | 9/5/2026 |
| 0.10.0 | 70 | 9/5/2026 |
Icod.Terminal 1.2.0 adds typed, bounded urxvt-style OSC 777 titled desktop notifications while preserving the stable 1.x contract and the existing OSC 9 notification API. TerminalSession.SendTitledNotificationAsync emits canonical OSC 777;notify;title;message ST framing using strict UTF-8, complete-frame prevalidation, a 4096-byte payload bound, shared session output serialization, and pre-commit cancellation. Semicolons and C0/C1/DEL controls are rejected because OSC 777 defines no interoperable field-escaping grammar. The release retains net8.0/net9.0/net10.0, existing dependencies, OSC 633 behavior, and all prior 1.x semantics. Full notes: https://github.com/uniblab/Icod.Terminal/blob/v1.2.0/docs/releases/1.2.0.md ; compatibility: https://github.com/uniblab/Icod.Terminal/blob/v1.2.0/docs/Compatibility-and-Versioning.md