Repository navigation
Decode server output, render it per output, and wire it for dependency injection - #80
Conversation
…per output Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rqqt7WGskvSsoRXvKMqybx
…res first Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rqqt7WGskvSsoRXvKMqybx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rqqt7WGskvSsoRXvKMqybx
|
Caution Review failedThe pull request is closed. WalkthroughThe pull request adds incremental terminal decoding, display rendering, picture decoding, MXP and Pueblo protocol support, configurable link policies, and dependency-injection registration. It also adds tests, API declarations, documentation, and package integration. ChangesTerminal decoding and rendering
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant Decoder
participant VtTokenizer
participant SgrPlugin
participant DecodeContext
participant DisplayRegistry
participant SpanRenderer
Caller->>Decoder: Feed terminal text
Decoder->>VtTokenizer: Tokenize input
VtTokenizer->>Decoder: Send parsed tokens
Decoder->>SgrPlugin: Dispatch matching sequence
SgrPlugin->>DecodeContext: Update style markup
Decoder-->>Caller: Return completed lines
Caller->>DisplayRegistry: Resolve line markup
Caller->>SpanRenderer: Render styled spans
Possibly related PRs
Suggested reviewers: Merge Risk:
|
… the line, prompt menus, inverse class; add decoding and display docs
…uce colours to 16 or 256 Kitty a=f adds or edits frames (base c, edit r, offset x/y, blend unless X=1, background Y, gap z) and a=a sets a frame's gap; a moving StoredPicture is given as a looping GIF. Re-sending a picture starts it over as one frame. OSC 8 id= becomes a LinkGroupMarkup pen, which Resolve turns into Interaction.Group. Degrade picks the nearest palette colour by redmean distance at Standard and Xterm256, through the IColorResolver when there is one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rqqt7WGskvSsoRXvKMqybx
IPictureCache holds decoded pictures by content key; MemoryPictureCache is the thread-safe LRU default. WithPictures(cache) shares one between decoders, so a picture sent to many connections is decoded and kept once, and a file already held is not decoded again. Frames go on a per-connection copy so a shared still picture never changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rqqt7WGskvSsoRXvKMqybx
Core: IDecoderFactory (DecoderRegistry), IStyleResolver (DisplayRegistry; the renderers take it), IUrlPolicy with UrlPolicy.Safe/WithSchemes as DecoderOptions.Links and DisplayOptions.Links, and decode diagnostics reported on the MarkupString.Decoding meter through an optional IMeterFactory. MarkupString.Extensions.DependencyInjection: AddMarkupString() registers the registries, a shared picture cache, a decoder factory, display defaults and the link policy, configured in code or bound from configuration with the source-generated binder. AOT smoke covers it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rqqt7WGskvSsoRXvKMqybx
MarkupRegistry.WithLinks sets the policy the ANSI (OSC 8, MSLP), HTML, MXP, Pueblo, BBCode and Markdown writers ask; HtmlTagPolicy.Links does the same for checked tags. DecodeDiagnostics.Dropped reports each drop, and the DI factory logs it at debug level through the host's ILoggerFactory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rqqt7WGskvSsoRXvKMqybx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rqqt7WGskvSsoRXvKMqybx
🤖 Generated with Claude Code
https://claude.ai/code/session_01Rqqt7WGskvSsoRXvKMqybx
Summary
A pipeline from raw server output to what a client draws: decode (ANSI/VT, OSC, MXP, Pueblo, Kitty/iTerm2/sixel pictures) →
MarkupTextlines → render for an output, degraded to itsOutputCapabilities.MarkupString.Decoding: VT tokenizer (DEC state machine),DecoderRegistryof plugins (handlers newest first,falsepasses on),Decoderper connection,DecodeContextwith pens and elements, overwrite on CR/BS/erase, line limits, events,ClientIdentity/ClientAnswers/MTTS,TagScannerandTagSyntaxfor tag protocols.MarkupString.Display:OutputCapabilities,DisplayStyle,DisplayRegistrywith contributors,SpanRenderer(spans, CSS, classes),CellRenderer(wide chars, tabs, wrap, picture cells, hit testing). Colours are reduced to the nearest of 16 or 256 (redmean, through theIColorResolver) atStandard/Xterm256. New core markupsCommandMenuMarkup,HighlightMarkup,LinkGroupMarkup(becomesInteraction.Group);PictureRow.FirstColumn.WithVt()(SGR with colon subparameters, C0, DEC graphics, OSC 8 withid/68/0-2/4/10-12/52/104/110-112, DA1, XTVERSION, 14/16/18t, DSR;CSI 6 noff by default),WithPictures()with PNG and sixel decoders, Kitty animation frames (a=f,a=a), aPictureStoreper connection over an injectableIPictureCache(MemoryPictureCacheby default, shareable across connections so a picture is decoded once), moving pictures given as GIF,AnsiStylescontributor, profile ↔ capability conversion,AnsiStyle.Concealed.WithMxp()decoder (line modes, open/secure tags, SEND menus and prompts, custom elements, entities, VERSION/SUPPORT). Mxp now references Ansi.WithPueblo()decoder (mudtext/HTML modes, links, sounds, panes).IDecoderFactory(aDecoderRegistry),IStyleResolver(aDisplayRegistry; the renderers take it),IUrlPolicywithUrlPolicy.Safe/WithSchemesasked by decoders (DecoderOptions.Links), display (DisplayOptions.Links), every writer (MarkupRegistry.WithLinks) andHtmlTagPolicy.Links; decode diagnostics on theMarkupString.Decodingmeter via an optionalIMeterFactory, and asDecodeDiagnostics.Dropped.MarkupString.Extensions.DependencyInjection:AddMarkupString()registers the registries, shared picture cache, decoder factory, display defaults and link policy;BindConfiguration()bindsMarkupStringOptionswith the source-generated binder;UsePictureCache<T>()/UseUrlPolicy<T>()swap implementations; drops are logged at debug level through the host'sILoggerFactory(source-generatedLoggerMessage).docs/decoding.md,docs/display.md,docs/dependency-injection.md,docs/formats.md, README tables, package READMEs, CHANGELOG. The design and plan docs were removed.Test plan
dotnet run --project MarkupString.Tests: 1524 passing.dotnet publish MarkupString.AotSmoke -r linux-x64with decoding and DI (configuration binding) sections: no IL warnings, binary prints ok.dotnet packof the new package succeeds.Known limits
a=c) is not read; playing/stopping (s,v) is left to the client.Summary by CodeRabbit