Skip to content

Releases: uniblab/Icod.Terminal

Icod.Terminal 1.21.0

Choose a tag to compare

@github-actions github-actions released this 28 Sep 02:43
24295f8

Icod.Terminal 1.21.0

Rich input and keyboard

Kitty legacy functional-key CSI sequences with an explicit event-type suffix now reach the authoritative ReadEventAsync stream as semantic key events. For example, CSI 1;1:3 D reports Left release, and CSI 2;5:2 ~ reports Control+Insert repeat. Supported letter finals are A B C D E F H P Q S with key number 1, and supported numeric ~ forms include insert, delete, page up/down, home/end, and F1–F12. R remains excluded because it overlaps cursor-position responses. Invalid or oversized phase-bearing frames recover at the next event instead of presenting invented keys.

The public TerminalInputEvent and TerminalKey vocabulary is unchanged. CSI-u, associated text, traditional terminfo keys, mouse, focus, and bracketed paste retain their existing routing. Kitty reporting still requires the existing explicit, reversible input-protocol acquisition; unnegotiated traditional input remains available. Associated text may contain user input and should be handled with the same care as other keystrokes.

Cursor visibility around a screen frame

TerminalScreenOutputTransaction.SetCursorVisibilityForCommit(TerminalCursorVisibility) requests a temporary cursor presentation for one transaction. The setting emits nothing when called. At commit, Terminal checks advertised entry and restoration capabilities, serializes against presentation leases and screen output, applies the requested visibility before frame items, and restores the effective lease owner or ordinary cursor afterward. A persistent cursor preference still belongs in AcquirePresentationAsync.

Unsupported capabilities, pre-cancelled work, and stale output epochs reject without frame output. If a committed write fails, cleanup attempts the return without using the caller's cancellation token and reports the failure. A failed cursor return or flush makes the presentation uncertain; later temporary visibility is rejected, and session cleanup attempts baseline restoration again. An emitted prefix cannot be rolled back, so callers own repaint decisions. The screen-output guide and input-driven sample show the pattern and fallback.

Compatibility and qualification

Target frameworks are net8.0, net9.0, and net10.0. The only additive public signature is the transaction visibility setter, with equal API fingerprint on all three frameworks:

939649e1d5c110039cfb3e5057561f8ef7fcb4de20af2de2152f9ec6ab357824

Production dependencies remain Icod.TermInfo 1.16.0 and Icod.Timing 1.0.0; optional test/sample Inspection remains 1.16.0. The 1.0 stable compatibility floor and all 1.20 public signatures and enum values remain intact. Fresh-package checks cover the input fixture, screen sample, DCurses 1.6.0/2.2.0, and the Terminal-only renderer. See Public-API-Baseline-1.21.md, Compatibility-and-Versioning.md, and the 1.21 development roadmap for exact CI and artifact evidence. Scripted tests do not certify a physical terminal emulator.

Icod.Terminal 1.20.0

Choose a tag to compare

@github-actions github-actions released this 27 Sep 08:36
8aa6d05

Icod.Terminal 1.20.0

Profile and capability decisions

Version 1.20 implements 3 + focused 6 + 10: static screen-profile refinement, hardening of the existing support-verification paths, and executable documentation/samples. The stable compatibility floor remains 1.0.0.

TerminalProfile.Screen adds nine immutable advertisement properties for existing cursor routes and scroll-region selection, plus AdvertisesErase, AdvertisesCharacterShift, and AdvertisesLineShift queries using the existing operation enums. These describe representation presence, including empty or malformed sources. They do not expand arguments, probe a terminal, or guarantee a concrete plan. Existing Supports... properties keep their meaning. Default values advertise nothing; unknown operation kinds throw ArgumentOutOfRangeException.

Applications should request a concrete plan using their actual parameters and distinguish unavailable, valid zero-byte, and rejected requests. Missing absolute cursor addressing does not exclude existing home/relative or row/column routes. Plans remain opaque and session-owned; advertisement and planning do not commit output or invalidate a pending transaction.

Existing verification and evidence ownership

Only KeyboardReporting, RasterGraphics, and PersistentRasterGraphics have live verification paths. The other nine current values remain inspection-only through VerifyCapabilityAsync. Sixel support alone cannot establish persistent raster support, and a generic graphics observation does not establish placeholder or animation support.

A regression allowed a reply to a pending support query to update evidence after InvalidateState() advanced the session generation. Included keyboard, Kitty graphics, Sixel, and shared Primary DA observations now record against their originating generation; the ledger atomically ignores expired observations. Aggregate raster verification stops its fallback sequence when it detects the generation change. A subsequent explicit request can establish fresh support. Previously returned statuses remain snapshots.

Existing query framing, admission, cancellation, response ownership, and exceptions remain intact. Silence remains inconclusive. Keyboard, Kitty graphics, and Sixel retain one-second per-query deadlines; aggregate verification and scheduling can take longer. There is no new protocol family, timeout API, scheduler, background discovery, or presentation-mode probe.

Runnable guide and sample

The capability sample reports profile facts, concrete plan availability and byte counts, and all twelve status rows. Default reporting performs no explicit support queries and commits no demonstration plan. --verify selects the three existing paths and then re-inspects. --help/-h work headlessly, invalid arguments return 2, runtime failures return 1, and cancellation returns 130 after cleanup. Session startup still owns its ordinary input-mode transition.

The tests and fresh-package consumer execute the same report routine with scripted sessions. They qualify alternative cursor planning, zero-byte plans, missing operations, available/unavailable endpoints, the complete no-probe matrix, and opt-in verification without clipboard, resource, or reporting-mode mutations. The permanent capability guide separates static advertisement, plans, live evidence, and endpoint availability.

Compatibility and qualification

Target frameworks remain net8.0, net9.0, and net10.0. Dependencies remain Icod.TermInfo 1.16.0 and Icod.Timing 1.0.0; optional test/sample Inspection remains 1.16.0 and stays outside the production graph. All 1.19 public signatures and enum values are retained; twelve additive members produce the identical all-framework fingerprint:

d308fb6ead5bd24c564d159297e6d08793c08eb4db21418eca6a5563aa5c4cbf

The 1.20 roadmap records regression evidence and qualification status. Required package witnesses retain DCurses 1.6.0, DCurses 2.2.0, the Terminal-only renderer, and the actual screen-output sample. Scripted coverage is not physical-emulator certification, performance benchmarking, or a fresh six-runner architecture matrix. Merge, tagging, release creation, and publication remain maintainer actions.

See Compatibility-and-Versioning.md, Public-API-Baseline-1.20.md, and PR #65.

A second late-response regression is also corrected: keyboard flags belonging to a cancelled request cannot verify a newly queued request. Observation starts with that request's emission; earlier flags are drained under existing wire ownership without becoming new positive evidence. A negative Kitty observation still leaves independent keyboard backends unknown.

The stable checkpoint passed all nine jobs in workflow 36302907074: 2,465 unit tests and 15 integration tests per framework on Windows, Linux, and macOS, plus all package/sample/downstream gates. The stable qualification record identifies the source, synthetic merge, artifact, package/symbol hashes, and final documentation-head validation policy.

Icod.Terminal 1.19.0

Choose a tag to compare

@github-actions github-actions released this 27 Sep 05:27
b3f7adf

Icod.Terminal 1.19.0

Screen-output planning and downstream hardening

Version 1.19 implements the selected downstream hardening, semantic planner expansion, transaction qualification, and documentation/sample workstreams. The stable compatibility floor remains 1.0.0.

PlanCursorMove(...) now considers home followed by relative down/right movement and, on a known current row, carriage return followed by relative right movement. Complete expanded/padded costs determine selection; existing candidates win ties. Missing, malformed, oversized, or unevaluable optional routes do not invalidate independent usable candidates. Planning remains side-effect free, bounded, opaque, and session-owned.

Executable downstream qualification

The formerly compile-only renderer path now runs in a synthetic package harness. It verifies exact mixed output, rejects an unavailable unknown-rendition baseline before emission, and exercises stale-transaction rejection and fresh recovery. The controlled renderer remains directly dependent only on the candidate Terminal package; synthetic TermInfo setup stays in a separate test host and uses Terminal's transitive dependency.

Published DCurses 2.2.0 is exercised through initial and unchanged refreshes, changed text/rendition, resize/repaint, committed output failure, recovery, and close. The separate DCurses 1.6.0 compatibility witness remains required.

Transactions, documentation, and sample

Existing transaction bounds, single-use commitment, output epochs, manager ownership, cancellation, serialization, cleanup, and ordered failures remain unchanged. Additional tests distinguish dimension/resize observation without output from presentation restoration during resume, which invalidates previously created work.

The screen-output guide explains unavailable versus zero-byte plans, known versus unknown physical state, safe frame construction, and caller-owned recovery. The runnable sample owns an alternate-screen scope, demonstrates a safe frame or deliberate stale-transaction rejection followed by a fresh frame, and waits for q/Escape before cleanup. Its actual routines also run headlessly against the candidate package, covering unavailable dimensions/plans, input, cancellation, and transport failure. Failure reporting and selection of a subsequent repaint remain the host application's responsibility; the sample does not automatically retry failed output. The raster-placeholder sample now combines semantic cursor plans and opaque cells in screen transactions without direct TermInfo expansion.

Cursor-visibility composition remains deferred because presentation leases already own visibility restoration. No retained-screen/layout engine, keyboard/query redesign, new raster protocol family, or public extensibility mechanism is introduced.

Compatibility and qualification

Target frameworks remain net8.0, net9.0, and net10.0; the production TermInfo dependency advances to Icod.TermInfo 1.16.0 while Icod.Timing 1.0.0 remains unchanged. Optional integration tests and samples align with Icod.TermInfo.Inspection 1.16.0; Inspection and Source remain outside the production graph. No public library member or enum value changes. All three framework snapshots retain fingerprint:

48975f2c42f6c544e9c574a9b3d79f7e2b7b3ecb10ab1a5a0b7067749e38e65d

The stable candidate passed all nine jobs in workflow 36290312908. Windows, Linux, and macOS each passed 2,402 unit tests and 15 integration tests per framework. Candidate-package, public-API, XML, dependency, downstream, and cross-platform evidence is recorded in the 1.19 roadmap and PR #64, with exact source and artifact hashes. Merge, tagging, release creation, and publication remain maintainer actions.

See Compatibility-and-Versioning.md, Architecture.md, and Public-API-Baseline-1.19.md.

Icod.Terminal 1.18.0

Choose a tag to compare

@github-actions github-actions released this 18 Sep 19:29
3e15037

Icod.Terminal 1.18.0

Unknown-rendition baseline recovery

Icod.Terminal 1.18.0 adds the missing recovery primitive required by a Terminal-only retained renderer: TerminalScreenPlanner.PlanRenditionBaseline() safely plans a return from unknown physical rendition state to Terminal's normalized default.

The release is additive over the stable 1.0.0 compatibility floor and the complete 1.17 API.

Baseline planning

  • Derives restoration obligations from the selected profile's attribute-entry and color-selection evidence before reversible normalization can suppress unsafe requests.
  • Prefers one global attribute reset when available; otherwise emits every required unconditional specific exit in stable underline, standout, italic, then strikeout order.
  • Restores selectable foreground/background color state through original-color-pair restoration after attribute restoration.
  • Returns null instead of a partial plan when any exposed rendition axis cannot be restored unconditionally.
  • Returns a valid zero-byte Rendition plan when no attribute entry or color selection is exposed, including reset-only profiles.
  • Reports exact emitted-byte cost after TermInfo padding interpretation and one affected line.

Planning remains side-effect free. The returned opaque plan belongs to the originating TerminalSession and can be emitted only through the existing same-session screen-output transaction.

Compatibility and ownership

Existing rendition normalization, PlanRenditionTransition(...), PlanRenditionReset(current), operation-plan ownership, output-epoch validation, cancellation, serialization, and cleanup semantics are unchanged.

The new signature exposes no Icod.TermInfo type, capability identifier, terminal string, or expansion API. TermInfo remains Terminal's private capability-data, expansion, padding, and color authority. Cells, windows, layout, Unicode width, clipping, damage, desired-versus-physical comparison, and repaint policy remain higher-layer responsibilities.

Production dependencies remain Icod.TermInfo 1.15.0 and Icod.Timing 1.0.0.

Qualification

The public API snapshots are identical across net8.0, net9.0, and net10.0. The 1.18 fingerprint is:

48975f2c42f6c544e9c574a9b3d79f7e2b7b3ecb10ab1a5a0b7067749e38e65d

Qualification covers attribute-only, color-only, combined, specific-exit, unsafe, empty, reset-only, padding, determinism, side-effect, same-session, foreign-session, stale-epoch, and cancellation cases. Fresh package consumers validate API/XML/package behavior on all target frameworks. Published Icod.DCurses 1.6.0 compatibility and a separate TermInfo-free future-renderer package consumer are also exercised on all three frameworks.

The stable candidate at source commit 56bbc011325e5c88e67f243a9b882b97bae9aac7 passed all nine jobs in workflow run 35382158657. Each target framework passed 2,383 unit tests and 15 TermInfo integration tests with zero failures. The validated Icod.Terminal.1.18.0.nupkg SHA-256 is e8f2b374fd0865aa151910686197096b344f7daf8d0ef72331520d944b322932; the .snupkg SHA-256 is 8a14d163f2ea0bf030bea0416e0a84a919a2e8c83c692956b3a2a98470d78422.

The candidate artifact is ID 10563191796 with uploaded ZIP SHA-256 b0fc9e57dcd0ccf42befc7d8d6fe91e9b0e19b62691fbfb775164252147fa028. The validated artifact is ID 10562732859 with uploaded ZIP SHA-256 1ddf8f76fbb6131271dd9123d5cab8043ddc68fd0084dfc1d1e84e8916121537.

The future-renderer witness proves that the candidate Terminal package supplies the required boundary. It does not claim that DCurses 2.0 has shipped; the retained DCurses T2001 package witness resumes after this package is published.

Tagging, GitHub Release creation, and NuGet publication remain explicit maintainer actions after candidate acceptance.

See Architecture.md, Compatibility-and-Versioning.md, Security-and-Privacy.md, Public-API-Baseline-1.18.md, and Icod.Terminal-1.18.0-Development-Roadmap.md for the permanent contract and development evidence.

Icod.Terminal 1.17.1

Choose a tag to compare

@github-actions github-actions released this 18 Sep 16:04
2d595c8

Icod.Terminal 1.17.1

Packaged README and release metadata correction

Icod.Terminal 1.17.1 is a documentation-only patch for the stable 1.17 line. It corrects the README that is displayed on GitHub and embedded in the NuGet package; it does not change runtime behavior or the public API released in 1.17.0.

Corrections

  • Identifies 1.17.1 as the current stable release and updates the explicit installation command.
  • Removes obsolete pre-release candidate, merge, tagging, and publication language from the consumer-facing README.
  • Separates the published Icod.DCurses 1.6.0 dependency graph from the intended Icod.DCurses 2.0 architecture. DCurses 1.6 still directly references both Terminal and TermInfo; the planned 2.0 line will reference only Terminal.
  • Adds a compact 1.17 example covering TerminalSession.Profile, GetDimensions(), TerminalSession.Screen, and CreateScreenOutputTransaction(...).
  • Synchronizes package release notes, the changelog, compatibility guidance, and the main development roadmap with the published 1.17 line.

Compatibility

The patch targets:

net8.0
net9.0
net10.0

There are no source, binary, behavioral, or public-API changes from 1.17.0. The public API fingerprint remains:

c0a051a925d551e526343ef59d8c47d75e41868d84235fa30bfa7debe1b3ceb9

Production dependencies remain Icod.TermInfo 1.15.0 and Icod.Timing 1.0.0. Optional integration tests and samples continue to use Icod.TermInfo.Inspection 1.15.0 without adding it to the production dependency graph.

See 1.17.0.md for the screen-planning and output-transaction feature contract, Compatibility-and-Versioning.md for stable 1.x policy, and Architecture.md for permanent ownership boundaries.

Icod.Terminal 1.17.0

Choose a tag to compare

@github-actions github-actions released this 18 Sep 15:01
ce2d76d

Icod.Terminal 1.17.0

Terminal-owned screen planning and output commitment

Icod.Terminal 1.17.0 adds the semantic live-terminal boundary needed for a later Icod.DCurses release to render through Terminal without directly consuming Icod.TermInfo. TermInfo remains Terminal's internal immutable capability-data, expansion, padding, and color authority.

The public surface is additive over the stable 1.0.0 compatibility floor and the complete 1.16 API.

Dimensions and semantic profile

  • Adds positive TerminalDimensions and TerminalSession.GetDimensions() while retaining the existing TermInfo-bearing GetSize() compatibility API.
  • Adds TerminalLifecycleEvent.Dimensions alongside the existing Size projection.
  • Adds immutable TerminalProfile and TerminalScreenCapabilities facts for selected-profile identity, color models/counts/selectors, reversible rendition attributes, ACS line glyphs, cursor visibility, and cursor addressing.
  • Keeps raw capability identifiers, terminal strings, expansion programs, and TermInfo types out of the new screen contracts.

Profile facts describe the selected terminal profile. They are not authenticated live-terminal claims and do not replace explicit bounded capability verification where verification exists.

Semantic screen planning

The new Terminal-owned vocabulary includes:

  • screen positions and cursor movement;
  • indexed and direct RGB colors;
  • normalized rendition attributes and transitions;
  • ACS line glyphs and alerts;
  • erase, character shift, line shift, scrolling, and scroll regions;
  • opaque TerminalScreenOperationPlan results.

TerminalSession.Screen exposes a session-bound, side-effect-free planner. Plans report semantic operation kind, exact encoded-byte cost, and padding-sensitive affected-line count without exposing their terminal strings or capability identities.

Candidate selection is deterministic: shortest encoded byte cost wins and stable candidate order breaks ties. Unsupported, invalid, unsafe, or non-reversible requests return controlled planning results rather than emitting partial output.

Session-bound output transactions

TerminalSession.CreateScreenOutputTransaction(...) creates a bounded, single-use transaction that can compose, in caller order:

  • same-session screen-operation plans;
  • application text;
  • strict OSC 8 hyperlink text;
  • current same-session raster-placeholder cells.

Creation captures the serialized-output epoch. Commit validates the full retained batch, rejects intervening session-owned activity before output, acquires the existing output gate, optionally frames synchronized output, writes without interleaving, performs required non-cancellable cleanup after commitment, flushes once, and releases the gate.

Pre-commit cancellation emits nothing. Ordinary cancellation after commitment does not intentionally truncate logical output or required cleanup. Independent primary and cleanup failures remain visible in deterministic order; no blind replay is attempted.

Ownership boundary

Version 1.17 does not move retained-screen policy into Terminal. Higher layers continue to own:

  • cells, windows, pads, and panels;
  • layout, clipping, wrapping, and Unicode display width;
  • desired-versus-physical screen comparison;
  • damage tracking, refresh strategy, and repaint policy.

Terminal resolves safe terminal operations and owns serialized output commitment. A renderer decides which safe operation reproduces its desired screen and whether it is preferable to rewriting.

Compatibility and qualification

The release targets:

net8.0
net9.0
net10.0

The public API snapshots are identical across all three target frameworks. The final 1.17 fingerprint is:

c0a051a925d551e526343ef59d8c47d75e41868d84235fa30bfa7debe1b3ceb9

Production dependencies are Icod.TermInfo 1.15.0 and Icod.Timing 1.0.0.

Release qualification covers Windows, Linux, and macOS runtime validation; package/API/XML/license and artifact gates; TermInfo integration; fresh package-only screen-planning and transaction consumers; published stable Icod.DCurses 1.6.0 compatibility; and a separate future-renderer consumer whose only direct package dependency is Icod.Terminal and whose source uses no TermInfo contracts.

The future-renderer witness proves API sufficiency at the package boundary. It does not claim that DCurses 2.0 has shipped.

Upgrade guidance

Existing 1.x consumers do not need to adopt the new APIs. Existing GetSize(), lifecycle Size, TerminalSession.Terminal, low-level terminal-string output, raster, persistent-resource, placeholder, and animation contracts remain available.

New rendering code should prefer GetDimensions(), Profile, Screen, and CreateScreenOutputTransaction(...) when it needs a TermInfo-free semantic screen boundary. Callers must still retain their own cell model, width policy, layout, clipping, damage, comparison, and repaint decisions.

See Architecture.md, Security-and-Privacy.md, Compatibility-and-Versioning.md, Public-API-Baseline-1.17.md, and Icod.Terminal-1.17.0-Development-Roadmap.md for the permanent contract and development evidence.

Icod.Terminal 1.16.0

Choose a tag to compare

@github-actions github-actions released this 17 Sep 17:41
5e28d48

Icod.Terminal 1.16.0

Persistent raster animation and frame lifecycle

Icod.Terminal 1.16.0 adds backend-neutral ownership of terminal-resident raster animation frames and playback while preserving private protocol identity, caller-owned screen layout, and the established persistent-resource lifecycle.

The public surface is additive over the stable 1.0.0 compatibility floor and the complete 1.15 API.

Highlights

  • Adds TerminalCapability.PersistentRasterAnimation = 11 without changing any previously released capability value.
  • Gives every TerminalRasterResource one side-effect-free Animation controller and opaque RootFrame representing the resource's original pixels.
  • Adds acknowledged full-size frame append through AddFrameAsync(...); a public frame token is returned only after a successful correlated result.
  • Adds exact positive whole-millisecond timing through SetFrameDurationAsync(...).
  • Adds semantic current-frame selection through SelectFrameAsync(...).
  • Adds terminal-driven stop, loading-mode playback, and normal finite/indefinite playback through StopAsync(...), RunLoadingAsync(...), and RunAsync(...).
  • Keeps image ids, image numbers, frame numbers, generation ids, raw animation commands, and backend selection private.

Ownership and sequence certainty

The animation controller is owned by its raster resource and is not independently disposable. Resource disposal remains final authority for terminal-resident image and frame data. Physical placements and virtual placeholders continue to refer to the same resource and do not acquire frame ownership.

Animation certainty is observed separately from raster-resource ownership:

Current
SequenceUncertain
Stale
Released
OwnerDisposed

If a committed frame append may have reached the terminal but its final result cannot be proven, the animation becomes SequenceUncertain / FrameSequenceAmbiguous. Terminal publishes no guessed token and performs no blind retry. The owning resource may remain current.

After sequence uncertainty, already-known frame timing/selection and stop remain available. New appends and run modes that depend on a known sequence tail return controlled unavailability.

Bounds, validation, and playback

Version 1.16 accepts full-size appended frames only. Each frame must match the owning resource's intrinsic dimensions.

session-wide known animation frames, roots included    4096
pending append reservations per animation                 1
frame duration                                  1..Int32.MaxValue ms
finite additional repeat count                   1..Int32.MaxValue-1
null repeat count                                indefinite looping

Root frames, acknowledged appended frames, and active append reservations participate in bounded capacity accounting. Stale, released, and owner-disposed animations release their registry capacity; sequence-uncertain animations retain acknowledged tokens.

Partial frames, delta editing, frame composition, and gapless composition frames are not exposed in 1.16.

Transport, failure, and cleanup

Animation uses the reviewed direct persistent-raster transport, serialized output gate, authoritative input/query reader, and correlated graphics-response parser.

Locally knowable invalid dimensions, durations, repeats, tokens, ownership, and capacity are rejected before private identity is emitted. Wrong/malformed identities, timeouts, late responses, terminal-negative responses, storage pressure, and pre/post-commit failures remain bounded.

Committed logical output is not intentionally truncated by later caller cancellation. Failure does not trigger blind replay, backend switching, hidden raster reconstruction, or a second input reader.

Session generation loss, resource-missing evidence, intentional resource release, and explicit resource-wrapper disposal propagate monotonically to animation/frame state. Placement or placeholder disposal does not delete animation frames.

Sample and qualification

Icod.Terminal.RasterAnimation.Sample demonstrates:

  • capability inspection;
  • resource creation and root-frame access;
  • root timing and acknowledged full-size frame append;
  • ordinary placement of the animated resource;
  • loading-mode playback while appending another frame;
  • stop and explicit frame selection;
  • finite and indefinite normal playback;
  • resource-owned deterministic cleanup.

The sample emits no raw Kitty commands and does not branch on protocol identities.

The release is qualified for:

net8.0
net9.0
net10.0

across Windows, Linux, and macOS, with fresh packed-NuGet consumers, generated XML-documentation checks, public API fingerprint verification, package contract shards, fixed-count concurrency/hardening, validated artifacts, and stable Icod.DCurses downstream acceptance.

The final 1.16 public API fingerprint is:

d2acfa85aad87c739b3f682096d4d7139627f12bc9d8981b65529eeb79a2da8d

Historical API baselines remain unchanged. Production dependencies remain Icod.TermInfo 1.14.0 and Icod.Timing 1.0.0.

Compatibility and deliberate exclusions

Version 1.16 is additive. Existing consumers that do not use animation APIs retain the released resource, physical/relative placement, virtual-placeholder, lifecycle-observation, generation-invalidation, capacity, cleanup, committed-output, and no-replay semantics.

Version 1.16 does not add partial-frame updates, frame composition/delta editing, gapless composition frames, absolute screen-coordinate placement, pixel-within-cell positioning, GIF/APNG or other image decoding, audio/timeline synchronization, Terminal-owned scene/window/cell/damage/layout policy, public protocol identities, generic raw Kitty dispatch, hidden replay caches, or PTY/ConPTY hosting.

See Persistent-Raster-Ownership.md, Architecture.md, Security-and-Privacy.md, Compatibility-and-Versioning.md, Public-API-Baseline-1.16.md, and Icod.Terminal-1.16.0-Development-Roadmap.md for the permanent contract and development evidence.

Icod.Terminal 1.15.0

Choose a tag to compare

@github-actions github-actions released this 15 Sep 17:37
1b0a710

Icod.Terminal 1.15.0

Unicode placeholder and virtual raster placement

Icod.Terminal 1.15.0 adds a backend-neutral semantic abstraction for terminal-resident raster presentation through Unicode placeholder cells while preserving caller ownership of cursor position, clipping, scrolling, damage, and layout.

The new public surface is additive over the stable 1.0.0 compatibility floor and the complete 1.14 API.

Highlights

  • Adds TerminalCapability.UnicodeRasterPlaceholders = 10 without changing any previously released capability value.
  • Adds opaque TerminalRasterPlaceholder ownership with required Columns / Rows in 1..256 and the existing TerminalRasterOwnershipState lifecycle vocabulary.
  • Adds immutable TerminalRasterPlaceholderCell semantic row/column tokens through TerminalRasterPlaceholder.GetCell(...).
  • Adds typed current-cursor single and bulk placeholder-cell output through TerminalSession.WriteRasterPlaceholderCellAsync(...) and WriteRasterPlaceholderCellsAsync(...).
  • Adds TerminalRasterResource.CreatePlaceholderAsync(...) for acknowledged virtual-placement creation.
  • Adds TerminalRasterResource.CreateRelativePlacementFromPlaceholderAsync(...), allowing a physical placement to use a current virtual placeholder as its immutable relative parent without exposing protocol identities.
  • Keeps terminal image ids, image numbers, physical/virtual placement ids, session-generation ids, Unicode placeholder encoding details, combining-mark tables, SGR identity packing, raw APC commands, and production backend selection private.

Rendering and ownership contract

Every generated placeholder cell is self-contained: it carries enough private identity and coordinate information to render independently, with no left-neighbor shorthand. This preserves clipping, sparse redraw, scrolling, arbitrary cell ordering, overlapping rasters, and higher-level virtual-screen diffing.

Placeholder-cell output uses the caller's current text cursor. Icod.Terminal does not choose absolute screen coordinates and does not take ownership of windows, cells, clipping, scrolling, damage, or scene layout.

Virtual placements share the existing bounded persistent-placement registry:

maximum live persistent resources              256
maximum live physical + virtual placements     4096
maximum relative-placement depth                  8
placeholder rows                               1..256
placeholder columns                            1..256
private virtual-placement id            1..0x00FFFFFF

TerminalRasterPlaceholder reuses the 1.14 lifecycle model:

acknowledged placeholder             Current / None
session-generation invalidation      Stale / SessionStateLost
correlated missing resource          Stale / ResourceMissing
owning-resource release              Released / ResourceReleased
explicit wrapper disposal            Disposed / ExplicitDisposal

Stale, released, disposed, cross-session, and invalid-generation placeholder tokens are rejected before private identity is emitted.

Acknowledgement, failure, and cleanup

Placeholder creation reuses the authoritative session query/input transaction manager. A public placeholder is published only after a successful correlated acknowledgement.

Locally knowable invalid operations are rejected before output. Wrong identities, malformed responses, timeouts, late responses, and generic transport failures do not manufacture missing-resource truth. A correlated ENOENT follows the established missing-resource invalidation model.

Committed-output semantics remain unchanged: post-commit failure is surfaced without blind retry, backend switching, or hidden raster replay/re-upload.

Virtual-parent descendant cleanup remains deepest-first. Releasing a virtual parent releases dependent physical descendants while independently owned child raster resources remain independently owned unless separately released or invalidated.

Icod.TermInfo 1.14 integration

The direct production dependency advances to:

Icod.TermInfo 1.14.0
Icod.Timing   1.0.0

Optional integration tests and the Icod.Terminal.TermInfoPersistentRaster.Sample use Icod.TermInfo.Inspection 1.14.0; Inspection remains outside the production package graph.

The optional integration now exercises TermInfo 1.14's advisory Sixel/Kitty raster-backend evidence and selection planner while preserving the architectural boundary:

  • backend availability remains separate from lifecycle and placement capability truth;
  • only conclusive live PersistentRasterGraphics evidence is caller-mapped to Kitty availability;
  • ordinary RasterGraphics does not identify one concrete backend;
  • UnicodeRasterPlaceholders is not treated as TermInfo 1.14 lifecycle/placement evidence;
  • Sixel and Kitty keep separate evidence/integration contexts;
  • explicit backend preference remains caller policy;
  • RasterBackendPlanner is not used by Icod.Terminal's production router.

Samples and qualification

The new Icod.Terminal.RasterPlaceholder.Sample demonstrates:

  • semantic capability inspection;
  • opaque resource and virtual-placeholder creation;
  • complete and sparse placeholder-grid rendering;
  • caller-controlled cursor positioning;
  • out-of-order semantic cell emission;
  • physical placement relative to a virtual placeholder;
  • deterministic cleanup without raw protocol identities or backend branching.

The optional TermInfo persistent-raster sample demonstrates the 1.14 backend-planning boundary while Terminal retains live routing and execution authority.

The release is qualified on:

net8.0
net9.0
net10.0

across Windows, Linux, and macOS, with fresh packed-NuGet consumers, generated XML-documentation checks, public API fingerprint verification, package contract shards, and stable Icod.DCurses downstream acceptance.

The final 1.15 public API fingerprint is:

eb361cef615fda97ac2c0ef9da8ea3d63fdc1f537ec438164bcb93694eecd13d

Historical API baselines remain unchanged.

Compatibility and deliberate exclusions

Version 1.15 is additive. Existing consumers that do not use placeholder APIs retain the released persistent-resource, ordinary/relative placement, source-crop, signed-z-order, lifecycle-observation, generation-invalidation, capacity, cleanup, and no-replay semantics.

Version 1.15 does not add animation/frame ownership, absolute screen-coordinate layout, pixel-within-cell positioning, a scene graph, Terminal-owned windows/cells/damage, public protocol identities, generic raw Kitty dispatch, Sixel placeholder emulation, hidden replay caches, image decoding/transcoding, or PTY/ConPTY hosting.

See Persistent-Raster-Ownership.md, Architecture.md, Security-and-Privacy.md, Compatibility-and-Versioning.md, Public-API-Baseline-1.15.md, and Icod.Terminal-1.15.0-Development-Roadmap.md for the permanent contract and development evidence.

Icod.Terminal 1.14.0

Choose a tag to compare

@github-actions github-actions released this 14 Sep 14:30
b6284fd

Icod.Terminal 1.14.0

Icod.Terminal 1.14.0 is the persistent-raster lifecycle-observability release for the stable 1.x line.

It builds directly on 1.13 relative placement ownership. The release does not add a terminal-side object database or passive remote existence probe. Instead, it exposes the lifecycle certainty that Icod.Terminal already owns locally through one immutable, backend-neutral snapshot on each persistent resource and placement handle.

Public API additions

Version 1.14 adds:

public enum TerminalRasterOwnershipStatus {
	Current,
	Stale,
	Released,
	Disposed
}

public enum TerminalRasterOwnershipLossReason {
	None,
	SessionStateLost,
	ResourceMissing,
	ParentPlacementLost,
	AncestorReleased,
	ResourceReleased,
	ExplicitDisposal
}

public readonly record struct TerminalRasterOwnershipState(
	TerminalRasterOwnershipStatus Status,
	TerminalRasterOwnershipLossReason LossReason
);

and one synchronous read-only property on both opaque persistent handle types:

public TerminalRasterOwnershipState OwnershipState { get; }

No other public API is required for the release.

What the states mean

Current means the handle remains current under Icod.Terminal's local ownership model. It is not authentication and is not proof that terminal-resident storage or placement still exists at the instant of observation.

Stale means terminal-resident certainty was lost. The semantic reason distinguishes:

  • SessionStateLost — explicit/session lifecycle generation invalidation;
  • ResourceMissing — correlated evidence that the resource identity is missing;
  • ParentPlacementLost — correlated evidence that the parent-placement relationship is missing.

Released is placement-specific local lifetime loss caused by another owner:

  • AncestorReleased — an ancestor placement lifetime ended;
  • ResourceReleased — the placement's owning raster resource ended its direct placement lifetime.

Disposed / ExplicitDisposal means the caller explicitly disposed that public wrapper.

Status and reason are returned in one immutable snapshot. The internal lifecycle state is monotonic; stale or released ownership is not resurrected by late acknowledgement or later observation.

Side-effect-free observation

Reading OwnershipState is synchronous and bounded. It does not:

  • emit terminal traffic;
  • register or allocate a query;
  • acquire the output gate;
  • verify a capability;
  • trigger cleanup;
  • mutate registry ownership;
  • replay/re-upload raster content;
  • select or expose a graphics backend.

The release deliberately does not add ExistsAsync(), VerifyExistsAsync(), or another API that would imply a truthful passive terminal-side object-existence query where the reviewed backend provides none.

Two-axis resource and placement lifetime

Version 1.13 separated raster-resource ownership from relative parent-placement lifetime. Version 1.14 makes that separation directly observable.

The canonical example is:

Resource A      Current / None
  Placement A1 Current / None
Resource B      Current / None
  Placement B1 Current / None, relative to A1

Dispose A1
  Placement A1 Disposed / ExplicitDisposal
  Placement B1 Released / AncestorReleased
  Resource B    Current / None

Resource B remains usable for another ordinary placement if no independent evidence invalidated or disposed it.

Existing protocol-loss semantics become observable

The release reuses the existing narrow persistent-raster response classification instead of adding a parallel classifier.

A correlated ENOPARENT publishes Stale / ParentPlacementLost for the affected placement subtree while leaving raster-resource ownership current unless separately invalidated.

A correlated missing-resource ENOENT publishes Stale / ResourceMissing for the affected resource and dependent placements while preserving unrelated resources/placements.

ECYCLE, ETOODEEP, malformed replies, wrong identities, timeout, late responses, and transport failure do not manufacture lifecycle loss merely because an operation failed.

Correlation remains transaction ownership, not terminal authentication.

Internal lifecycle model

Resources and placements carry one packed atomic lifecycle value. Observation uses local atomic reads; lifecycle publication uses compare/exchange transitions.

This provides:

  • one indivisible status/reason pair;
  • first-transition monotonicity;
  • no stale/released-to-current resurrection;
  • safe concurrent readers while session/resource/placement ownership changes;
  • no new lock or output-gate dependency for observation.

Public wrapper disposal remains separate from the underlying shared ownership state. This allows a descendant wrapper to remain observable as Released until its caller explicitly disposes that wrapper, at which point the wrapper reports Disposed / ExplicitDisposal.

Sample

Icod.Terminal.PersistentRaster.Sample now demonstrates the complete 1.11–1.14 persistent stack:

  1. verify PersistentRasterGraphics;
  2. create Resource A and an ordinary placement;
  3. create independently owned Resource B;
  4. create a Resource B placement relative to Resource A's placement;
  5. observe current ownership without extra terminal traffic;
  6. update common placement geometry and relative offsets;
  7. dispose the parent placement;
  8. observe parent Disposed, child Released, and Resource B still Current;
  9. explicitly dispose the released child wrapper;
  10. create a fresh ordinary placement from Resource B.

The sample remains backend-neutral and exposes no protocol-private image, placement, parent, or generation identity.

Package and public API qualification

The persistent-raster package verifier now requires generated XML documentation for the complete lifecycle-observation surface and compiles/runs a fresh NuGet-only consumer on:

net8.0
net9.0
net10.0

The deterministic public API snapshot is identical across all three target frameworks. The final 1.14 fingerprint is:

2a23205217183a602f8fc454c49b47d278ebdc26b5e358c0384ed0d692405696

The machine fingerprint is stored in docs/Public-API-Baseline-1.14.sha256 and the human-readable contract in docs/Public-API-Baseline-1.14.md. Historical fingerprints remain unchanged.

Downstream compatibility

The stable 1.x package-contract shard continues to exercise current Icod.DCurses acceptance/hardening. Version 1.14 does not require DCurses source adoption in order to consume the package successfully.

Higher-level consumers may adopt OwnershipState when useful, while existing consumers that never read it retain the existing 1.13 behavior.

Production dependencies

The direct production package graph is:

Icod.TermInfo 1.13.0
Icod.Timing   1.0.0

Icod.TermInfo.Inspection 1.12.0 remains test/sample-only where used and is not added to the production package graph.

Compatibility

The stable 1.0.0 compatibility floor remains unchanged.

Existing behavior remains intact for consumers that do not read OwnershipState, including:

  • acknowledged persistent resource creation;
  • ordinary current-cursor placement;
  • source rectangles and signed z-order;
  • immutable relative parentage and signed cell offsets;
  • UpdateAsync(...) / UpdateRelativeAsync(...) semantics;
  • depth-8 portable relative graph limit;
  • 256-resource / 4096-placement local capacity ceilings;
  • generation-scoped certainty;
  • descendant-before-parent cleanup;
  • one authoritative query/input path;
  • no automatic raster replay.

See docs/Compatibility-and-Versioning.md for the stable-versioning and compatibility policy.

Explicit non-goals

Version 1.14 does not add:

  • passive remote ExistsAsync() / VerifyExistsAsync() semantics;
  • terminal-authenticated object existence;
  • mutating reconciliation probes presented as inspection;
  • automatic replay/re-upload/rebind;
  • hidden source-image caching;
  • public generation numbers;
  • public image/placement/parent protocol identities;
  • backend selection or raw Kitty dispatch;
  • reparenting;
  • Unicode placeholder / virtual placements;
  • animation/frame lifecycle;
  • absolute screen-coordinate placement;
  • pixel-within-cell positioning;
  • image decoding/transcoding;
  • PTY/ConPTY hosting;
  • cell/window/layout/damage/scene ownership.

Release qualification

The stable release candidate must pass the complete nine-job PR matrix on its exact final head:

Runtime Windows
Runtime Linux
Runtime macOS
Package candidate / public API freeze
Package Foundation
Package Presentation
Package Semantic and hardening
Package Stable 1.x release line
Validated package artifact

This release-note file deliberately does not self-certify the commit that contains final release closure. Exact-head qualification is recorded on PR #58 after CI completes. Merge, tag, and publication remain maintainer actions.

For the permanent ownership contract, see docs/Persistent-Raster-Ownership.md. For tranche history and design constraints, see Icod.Terminal-1.14.0-Development-Roadmap.md and the 1.14 design/implementation-plan documents under docs/superpowers/.

Icod.Terminal 1.13.0

Choose a tag to compare

@github-actions github-actions released this 13 Sep 17:51
096321a

Icod.Terminal 1.13.0

Icod.Terminal 1.13.0 extends the opaque persistent-raster placement model with bounded relative placement ownership. A placement may now be positioned relative to one existing placement while retaining a separate raster-resource ownership relationship.

The package targets:

net8.0
net9.0
net10.0

The stable compatibility floor remains 1.0.0.

Relative persistent-raster placement

Version 1.13 adds two public operations:

TerminalRasterResource.CreateRelativePlacementAsync(
	TerminalRasterPlacement parent,
	int columnOffset,
	int rowOffset,
	TerminalRasterPlacementOptions? options = null,
	CancellationToken cancellationToken = default
)

TerminalRasterPlacement.UpdateRelativeAsync(
	int columnOffset,
	int rowOffset,
	TerminalRasterPlacementOptions? options = null,
	CancellationToken cancellationToken = default
)

Parentage is immutable. It is selected during successful relative creation and cannot be changed through a public reparenting operation or mutable parent property.

columnOffset and rowOffset are signed terminal-cell offsets. The full signed int domain is retained. They are not source-image pixels, absolute terminal coordinates, or pixel-within-cell offsets.

The portable relative-depth ceiling is 8. Ordinary current-cursor placements have depth 0; a direct relative child has depth 1. Creation that would produce depth 9 is rejected locally before output.

Two independent ownership axes

Relative placement deliberately separates raster-resource ownership from parent-placement lifetime:

TerminalRasterResource
    -> owns placement resource/storage membership

TerminalRasterPlacement parent
    -> owns relative-placement lifetime subtree

A placement of Resource B may therefore be relative to a placement of Resource A.

Disposing a parent placement removes its relative descendants, deepest-first, but does not automatically dispose descendant raster resources. A child resource remains independently owned and may participate in other placements.

Disposing a resource removes its own placements and any relative descendant placements whose lifetime depends on them, including descendants that place other still-live resources. Those descendant resources themselves remain independently owned.

Updates and common geometry

TerminalRasterPlacementOptions remains the single common crop/extents/z-order contract.

UpdateAsync(...) preserves the placement's established positioning mode:

  • ordinary placements continue to update at the current cursor location;
  • relative placements preserve their immutable parent and last acknowledged offsets while replacing common geometry.

UpdateRelativeAsync(...) changes signed offsets plus common geometry while retaining the same parent.

No API silently converts an ordinary placement to relative placement or reparents an existing relative placement.

Acknowledgement and protocol behavior

Relative create/update operations use the existing serialized acknowledged persistent-placement transaction path and the same authoritative terminal input/query stream.

The private Kitty encoding adds parent image/placement identity and signed offset fields while retaining child image/placement identity as the response-correlation authority. Relative offsets are committed locally only after a successful acknowledgement.

Existing 1.12 current-cursor placement bytes and behavior remain unchanged when the relative APIs are unused.

Cleanup and lifecycle

Current parent/subtree cleanup is descendant-before-parent and deepest-first. Each placement delete uses that placement's own owning-resource image identity, including cross-resource relative graphs.

Placement and resource disposal remain locally idempotent. A child handle already closed by parent cascading cannot double-release terminal identity.

Generation invalidation stales the complete graph. Stale cleanup is local-only and emits no stale numeric terminal identities. No hidden raster replay, re-upload, or rebind is introduced.

Session teardown drains current placement graphs deepest-first before resource data and preserves the existing restoration/failure-aggregation model.

Terminal-negative responses

Version 1.13 narrows graph-related terminal failure classification:

  • correlated ENOPARENT invalidates certainty for the affected parent placement subtree without automatically declaring its raster resource missing;
  • correlated ECYCLE remains a controlled failure because supported public construction cannot form a cycle;
  • correlated ETOODEEP remains a controlled failure because local depth 8 prevents deeper supported construction;
  • correlated ENOENT retains established missing-resource/identity invalidation where the response denotes missing resource identity;
  • malformed correlated responses, wrong child identities, late responses, and transport failures retain the established bounded transaction-manager behavior.

Correlation establishes transaction ownership, not terminal authenticity.

Bounds and compatibility

The existing registry ceilings remain unchanged:

maximum live persistent resources   256 per session
maximum live persistent placements 4096 per session
maximum relative placement depth       8

Private placement-id wrap/collision rules remain nonzero and collision-safe. Existing generation, acknowledgement, committed-output, capacity, crop, and signed z-order contracts are preserved.

Version 1.13 is additive over the published 1.12 public surface and the stable 1.0.0 compatibility floor.

Sample and package qualification

Icod.Terminal.PersistentRaster.Sample demonstrates:

  1. Resource A with an ordinary current-cursor parent placement;
  2. independently owned Resource B;
  3. a Resource B placement relative to Resource A's placement;
  4. signed relative offsets plus 1.12 crop/extents/z-order geometry;
  5. ordinary UpdateAsync(...) preserving the relative parent and acknowledged offsets while replacing common geometry;
  6. UpdateRelativeAsync(...) replacing offsets/common geometry without reparenting;
  7. parent disposal cascading descendant-placement cleanup while Resource B remains independently owned; and
  8. successful creation of a fresh ordinary placement from Resource B after the parent cascade.

The optional Icod.Terminal.TermInfoPersistentRaster.Sample and dedicated integration tests consume Icod.TermInfo.Inspection 1.12.0. They retain the 1.11.1 lifecycle-planning boundary and additionally qualify the additive TermInfo 1.12 source-rectangle/signed-z-order placement planner without adding Inspection to the production package graph. TermInfo 1.12 does not plan the relative-parent graph introduced by Terminal 1.13.

The fresh NuGet-only persistent-raster consumer compiles and executes the new public surface on net8.0, net9.0, and net10.0. Generated XML documentation is verified for both new methods on every supported TFM.

The stable 1.x package shard continues to run the published Icod.DCurses acceptance/hardening witness. No DCurses source change is required merely to consume the additive 1.13 package.

Public API

The intended public additions over 1.12 are exactly:

TerminalRasterResource.CreateRelativePlacementAsync(
    TerminalRasterPlacement,
    int,
    int,
    TerminalRasterPlacementOptions?,
    CancellationToken
)

TerminalRasterPlacement.UpdateRelativeAsync(
    int,
    int,
    TerminalRasterPlacementOptions?,
    CancellationToken
)

The final 1.13 public API fingerprint is:

c9dc8b86dc1e8beed7161f1f5a122dce67a9187d3f4ee0b85ad5b49f09bd0da9

Historical public API baselines remain unchanged.

Dependencies

The production dependency graph is:

Icod.TermInfo 1.12.0
Icod.Timing   1.0.0

No Inspection, Source, graphics-codec, or scene-layout dependency is added to the production package.

Deliberate exclusions

Version 1.13 does not add:

  • reparenting or mutable parentage;
  • public parent/image/placement numeric identities;
  • Unicode placeholder / virtual placements;
  • animation or frame lifecycle;
  • absolute screen-coordinate placement;
  • pixel-within-cell positioning;
  • automatic replay/re-upload/rebind;
  • retained source-image caches;
  • caller-selected graphics backends or generic raw Kitty dispatch;
  • Sixel persistent-resource emulation;
  • image-file decoding/transcoding;
  • PTY/ConPTY hosting;
  • cells, windows, damage, layout, or scene ownership.

Relative placement is a bounded positioning/lifetime relationship, not a general scene graph.

Qualification

The final stable release candidate must pass the ordinary exact-head matrix:

Runtime Windows
Runtime Linux
Runtime macOS
Package candidate / public API freeze
Package Foundation
Package Presentation
Package Semantic and hardening
Package Stable 1.x release line
Validated package artifact

See Persistent-Raster-Ownership.md, Compatibility-and-Versioning.md, Public-API-Baseline-1.13.md, and Icod.Terminal-1.13.0-Development-Roadmap.md for the permanent contract and development evidence.