Icod.Terminal
1.3.0
See the version list below for details.
dotnet add package Icod.Terminal --version 1.3.0
NuGet\Install-Package Icod.Terminal -Version 1.3.0
<PackageReference Include="Icod.Terminal" Version="1.3.0" />
<PackageVersion Include="Icod.Terminal" Version="1.3.0" />
<PackageReference Include="Icod.Terminal" />
paket add Icod.Terminal --version 1.3.0
#r "nuget: Icod.Terminal, 1.3.0"
#:package Icod.Terminal@1.3.0
#addin nuget:?package=Icod.Terminal&version=1.3.0
#tool nuget:?package=Icod.Terminal&version=1.3.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.3.0 is the current development release line and the third additive minor release after the stable 1.0 contract.
Version 1.3 adds typed, bounded iTerm2 OSC 1337 shell-integration and semantic-history metadata without changing the meaning of existing 1.0/1.1/1.2 APIs. The new surface covers marks, current directory, remote host identity, Base64-backed user variables, the current shell-integration version form, and explicit captured-output clearing.
The stable 1.0 architecture, ownership, lifecycle, input/query, restoration, security, and compatibility guarantees remain the compatibility floor for the 1.x line. Versions 1.1 and 1.2 retain their typed OSC 633 and OSC 777 surfaces unchanged.
Full release notes and concise release history:
Installation
dotnet add package Icod.Terminal --version 1.3.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);
- typed iTerm2 shell-integration/semantic-history metadata (OSC 1337);
- 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.
iTerm2 OSC 1337
The 1.3 iTerm2 surface is explicitly vendor-specific and typed:
await session.SetITerm2MarkAsync();
await session.PublishITerm2RemoteHostAsync(
"alice",
"host.example.test"
);
await session.PublishITerm2CurrentDirectoryAsync( "/srv/repo" );
await session.SetITerm2UserVariableAsync(
"branch",
"main"
);
await session.PublishITerm2ShellIntegrationVersionAsync(
20,
"bash"
);
The six supported operations are SetMark, CurrentDir, RemoteHost, SetUserVar, the current ShellIntegrationVersion=<version>;shell=<shell> form, and ClearCapturedOutput.
User-variable values are encoded as strict UTF-8 followed by Base64. Other text is strictly validated and UTF-8 encoded. Frames use canonical ST termination, a 65,536-byte payload ceiling, the shared session output gate, and pre-commit cancellation.
OSC 7 remains the preferred portable current-location API and OSC 133 remains the portable prompt/command-region API. The library never silently aliases those protocols to OSC 1337 and does not infer iTerm2 support from terminal identity.
The public API deliberately excludes generic raw OSC 1337 dispatch and invasive/overlapping operations for profile mutation, focus stealing, URL opening, pasteboard/file transfer, custom script control, arbitrary color/cursor mutation, Unicode-version changes, or Touch Bar key labels.
See docs/ITerm2-Osc1337-Shell-Integration.md.
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 1337 current-directory, remote-host, user-variable, and shell-integration metadata;
- 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. Base64 used by OSC 1337 user variables is an encoding, not encryption.
Compatibility policy
Stable 1.0.0 remains the compatibility floor. Versions 1.1.0, 1.2.0, and 1.3.0 intentionally add compatible OSC 633, OSC 777, and OSC 1337 public methods respectively. 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
- iTerm2 OSC 1337 Shell Integration
- Security and Privacy
- Licensing
- Public API Baseline 1.0
- Public API Baseline 1.1
- Public API Baseline 1.2
- Public API Baseline 1.3
- 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, desktop notifications, and iTerm2 shell metadata.
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, OSC 777, and OSC 1337 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.3.0 is publishable only after the exact 1.3 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.3.0 adds a typed, bounded iTerm2 OSC 1337 shell-integration and semantic-history metadata surface while preserving the stable 1.x contract and the existing portable OSC 7/133 APIs. The new TerminalSession operations cover SetMark, CurrentDir, RemoteHost, Base64-backed SetUserVar, the current ShellIntegrationVersion=...;shell=... form, and ClearCapturedOutput. OSC 1337 values use strict UTF-8, complete-frame prevalidation, a 65536-byte payload ceiling, shared session output serialization, and pre-commit cancellation. Generic raw OSC 1337 dispatch and invasive profile/focus/browser/pasteboard/file-transfer/custom-script mutation surfaces remain excluded. The release retains net8.0/net9.0/net10.0, existing dependencies, and all prior 1.x semantics. Full notes: https://github.com/uniblab/Icod.Terminal/blob/v1.3.0/docs/releases/1.3.0.md ; compatibility: https://github.com/uniblab/Icod.Terminal/blob/v1.3.0/docs/Compatibility-and-Versioning.md