api-ergonomics-pass-2: Line shorthands, AppendRule, Collapsible.AppendLine, paste routing, multi-select Back (0.2.0-rc.3)#8
Merged
Conversation
OpenSpec change scaffold for the second public-API ergonomics pass: Line single-style factories, Scrollback.AppendRule, incremental Collapsible.AppendLine, PasteEvent editor routing, and multi-select DialogOutcome.Back via '['. Validates --strict. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ection 1) - 1.1 Line.Bold(string) — single bold segment via FromText - 1.2 Line.Dim(string) — single dim segment via FromText - 1.3 Line.Fg(string, Color) — single fg-colored segment, Format.None - 1.4 Line.Bg(string, Color) — single bg-colored segment, Format.None - 1.5 XML docs: sanitizing wrappers; no Italic/Underline/Reverse/Strikethrough/Raw - 1.6/1.7 9 LineTests: single-segment, FromText equivalence, control-byte sanitize parity Thin sanitizing wrappers over Line.FromText; Segment.Raw/LineBuilder.Raw remain the only verbatim seams. No implicit string->Line conversion. Reviewer clean. Gates: build 0 warnings, 836 tests green (+9), format clean, validate --strict clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 2.1 RuleBlock : ILineObject — width-aware horizontal rule resolved at paint time - 2.2 IScrollback.AppendRule() with XML doc - 2.3 ScrollbackSurface.AppendRule() posts private nested AppendRuleToScrollbackCommand - 2.4 removed the "// AppendRule ... deferred" documented-gap comment - 2.5/2.6 2 HeadlessTerminal/FrameSnapshot tests: render-at-width + resize re-expansion - FakeScrollback gains an AppendRule() stub for the new interface member Closes the spec/impl gap: inline-scrollback "Scrollback command surface" already mandated a rule command. Rule width resolves to model.Columns at render time, so it re-expands across resize. Loop-thread-only mutation. Reviewer: clean after rewriting the test onto the real harness. Gates: build 0 warnings, 838 tests green (+2), format clean, validate --strict clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ion 3) - 3.1 ICollapsible.AppendLine(Line)/(string) with one-way no-op-after-expand/horizon docs - 3.2 ScrollbackModel.AppendToCollapsible guards mirror ExpandCollapsible - 3.3 CollapsibleHandle posts AppendLineToCollapsibleFacadeCommand; "documented gap" remarks closed - 3.4-3.7 6 model-level tests: grow-on-expand, no-op-after-expand, no-op-after-horizon-freeze, oversized-reprint ordering regression, AppendHidden unit, ctor-copies-list Collapsible._hiddenLines becomes an owned List<Line> (.ToList() copy — also closes a latent off-thread-mutation leak). Append touches only the pre-expansion snapshot and never initiates a reprint, so it cannot worsen the oversized-reprint ordering edge (design Decision 4). Loop-thread-only mutation. Reviewer: clean after deleting an orphaned unused command file. Gates: build 0 warnings, 844 tests green (+6), format clean, validate --strict clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 4.1 LoopEngine.ApplyInputEvent gains a PasteEvent case (overlay-first intercept chain) - 4.2 base-editor paste inserts at caret via TextBuffer.Insert(string), emits InputChanged - 4.3 InputDialog.HandlePaste flips the sticky _userEdited flag (secret first-edit) - IOverlay.HandlePaste(string): InputDialog inserts+consumes, modal Dialog consumes+ignores, Autocomplete passes through (cursor stays in base editor) - 4.4-4.7 4 tests: caret-advance, multiline wrap, secret-default flip + Submit value, modal no-leak PasteEvent was previously dropped by the loop. Pasted control/escape bytes are neutralized on the render path (TextBuffer.Render / MaskLine build via the sanitizing Segment ctor; Segment.Raw is not on the paste path). Loop-thread-only mutation; no new restore-path state. Reviewer clean first pass; no HITL needed. Gates: build 0 warnings, 848 tests green (+4), format clean, validate --strict clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- 5.1 MultiSelectRequest gains AllowBack (default false; mirrors SelectRequest ctors)
- 5.2 Dialog.HandleKey: '[' -> OverlayCloseKind.Back for multi-select at any time
- 5.3 Select/Choice additionally accept '[' as a secondary Back key (movement-suppressed)
- Terminal.MultiSelectAsync passes allowBack: req.AllowBack; Back maps to DialogOutcome.Back
- 5.4/5.5 8 tests: multi '['->Back, survives Space-toggle, survives arrow-move, default-false
no-op; select/choice '['-before-move->Back, '['-after-move no-op; Backspace regression
Reverses the prior "MultiSelectRequest SHALL continue to omit AllowBack" — settled by
binding a distinct key ('[') instead of the ambiguous Backspace-at-toggle. One gated
branch handles all three dialogs (multi: any time; single/choice: before movement).
Removed the obsolete test that pinned the reversed contract. Reviewer clean (6 dims).
Gates: build 0 warnings, 856 tests green (+8), format clean, validate --strict clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tion 6) - 6.1 WizardRenderer.cs: 13 single-style LineBuilder sites -> Line.Bold/Dim/Fg (0 left) - 6.2 Program.cs: 22 single-style sites migrated; 11 multi-segment chains left untouched - 6.3 skipped (AppendRule/AppendLine demo not a natural fit) Samples-only; no library/test changes. Validates the §1 ergonomics win at the ~24 concrete call sites that motivated the headline factories. Reviewer clean. Gates: build 0 warnings, 856 tests green (unchanged), format clean, validate clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tion 7)
- 7.1-7.2 all four gates green in Release (build 0 warnings, 856 tests, format, validate)
- 7.3 Version 0.2.0-rc.2 -> 0.2.0-rc.3 in Dcli.csproj + Dcli.Testing.csproj
- 7.4 dotnet pack produced dcli.0.2.0-rc.3.{nupkg,snupkg} + dcli.testing.0.2.0-rc.3.{nupkg,snupkg}
- 7.5 per-section commit hashes recorded in DEVLOG
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
All 7 sections landed; released as dcli + dcli.testing 0.2.0-rc.3. DEVLOG flipped to shipped framing ahead of /opsx:archive. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move change to openspec/changes/archive/2026-05-29-api-ergonomics-pass-2/ and sync the delta specs into the live specs: - styled-text: + Single-style line shorthand factories - inline-scrollback: ~ One-way collapsible, ~ Scrollback command surface - fixed-region: ~ Owned input editor, ~ Awaitable modal dialogs Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second dcli public-API ergonomics pass (follows
api-ergonomics-pass-1rc.1 andmulti-line-dialog-promptsrc.2). Closes the remaining §14.4 dmon-wizard-port friction plus three contracts the specs already named but the code never satisfied. Released asdcli+dcli.testing0.2.0-rc.3. No breaking changes — every addition is a new factory, overload, method, or opt-in flag.Sections (one commit each, worker→reviewer→gates per the OpenSpec apply workflow)
Line.Bold/Dim/Fg/Bg(string)single-style factoriesIScrollback.AppendRule()— width-aware rule resolved at paint timeICollapsible.AppendLine(Line)/(string)— incremental hidden-line appendPasteEventrouting into the owned input editor (+ secret first-edit flip)MultiSelectRequest.AllowBackvia[(the contended edit)Linefactories0.2.0-rc.3)Notable
fixed-regionsentence "MultiSelectRequest SHALL continue to omit AllowBack" — settled by binding a distinct key ([, not the ambiguous Backspace-at-toggle). Multi-select[fires at any time; Select/Choice additionally accept[(movement-suppressed like their pass-1 Backspace).AppendRulewas mandated-but-unimplemented;Collapsible.AppendLinewas a documented gap).Segment.Rawis not on the paste path); paste flips the secret-default_userEditedflag.Quality
dotnet formatclean,openspec validate --strictclean.HeadlessTerminal; an orphaned never-instantiated command file; a missing multi-select regression guard).dcli/dcli.testing.nupkg+.snupkg).openspec/changes/archive/2026-05-29-api-ergonomics-pass-2/(with DEVLOG); delta specs synced intoopenspec/specs/{styled-text,inline-scrollback,fixed-region}/.🤖 Generated with Claude Code