Repository navigation
Integrate triage fixes: #62, #63/#64, #65, #66, #68/#73, #74 and CI lint - #76
Merged
Merged
Conversation
Narration (assistant body segments) is display content, not process detail. It now stays visible as ordinary body prose when the process folds, and the folded reasoning/tool run between two body blocks becomes a compact process-chain summary in the gap: 1px --reader-rail rule plus the familiar 思考×N · 工具×K label with a chevron that expands the real rows in place. - projection: hasProcessContent only advertises literal reasoning; earlier body steps no longer count as foldable process content. - Reader: body segments render with normal answer typography (no annotation colour, indent or per-block left rule); only the final answer keeps copy/fork actions. A per-turn seam plan counts the rows folded between consecutive body blocks and renders the process-chain summary seam. - live-turn: body narration is a fold-chain boundary; fold boxes contain only reasoning/tool/record steps and summaries never count narration as 输出×N. - tests: projection/live-turn/fold-choreography contracts updated; a real-Reader browser fixture verifies red (both 0.3.4 and 0.3.9 baselines hide narration) and green (always-visible body, seam geometry, expand/collapse interaction, auto-fold off, failed and interrupted turns).
Live folding used to break its chain at every narration block, so any turn that alternated thinking and report text left every past reasoning card expanded while it ran (only folding again after the turn closed). presentLiveTurn now splits at user inserts and, once a later reasoning step exists, folds each earlier reasoning/tool run at its own source position. The latest reasoning and everything after it stay open; narration continues to render in place and never enters a fold box. - live-turn: replace splitChain with the per-segment run folding described above (fold keys remain live-fold:<first step key> so rows keep identity). - tests: live-turn/fold-choreography/fold-intensity contracts updated for cross-narration folding and user-insert chain resets. - fixture: open-turn check now requires exactly one 思考×1 fold, the earlier reasoning hidden, and narration visible between the folds and latest reasoning. - docs: lifecycle wording updated.
.userCluster was align-self:flex-end with only a max-width, so it shrank to the text and the host .userStack 82% resolved against that shrink-wrap. Give the cluster the host min(column * 0.702, 82%) width. The slot outlet is display:contents, so the cap has to reach the host row and stack, not the direct child. Pending bubbles use the host 14px/22px metrics. #74
These symbols were already unused at fbf7bae. npm run lint is a required check for this branch, and it failed before the reader change.
An open turn folds an earlier reasoning/tool run in place. The narration seam counted that same run again and, via data-reader-seam-after, dropped the previous body's bottom spacing. Skip the seam only when every folded step is already inside a live-fold cell. Closed turns still show the seam. DESIGN.md now matches per-run live folds, and the Unreleased notes credit @Adamaik (#68) and @sugar-syl (#73). Also clear unused bindings that already failed eslint on main, including the unused toolSummary helper, so npm run lint exits 0.
A conversation.chat.node registration for assistant-step whose priority is below the official renderer (0) is a replacement. Reader mirrors that winner and gives it each answer-body segment, with groupPart response and only that segment's blocks. Reasoning, folding, and process motion stay on the reading view, so dsh-raw-html-v2 can draw raw HTML cards without taking over the reading layout. Also remove unused symbols that already failed npm run lint on main, and count non-text blocks on pending inbox rows. #65
Issue #62. Another client plugin can register dsh-better-display.text-transform and rewrite reasoning or answer text before the reveal. The session, the transcript, and the fold stay on the original blocks. Copy still uses the original answer. An appended batch keeps the reveal instead of starting it over. The block chain owner now also receives presentation, holdFormatting, and liveText. Clear unused names that already failed npm run lint on main. Thanks @lin636.
Wallpaper themes clear --dsw-alias-bg-base, so the elapsed-time row and the closed process summary no longer mask the answer heading that scrolls under them. Lane offsets follow the measured row and --dsh-content-font-delta, and a transparent canvas falls back to the opaque surface token. Drop unused bindings that already failed npm run lint on fbf7bae.
Drop bindings nothing reads, and raise the host-bundle budget to the size a fresh tsdown build emits now that flags, log, and metrics are included.
A successful rewind still rolls the Reader back to before the target message. The cut is the plugin's closed range [target, marker]: previews and a target past the marker do not open a span, and a turn loses its process and tail rows only when every content row of that turn is gone. Streaming, a reconnect, and a plain re-render do not withdraw rows. The collapse stays 220ms, still dies on the #60 deadline, and settles at once when motion is off or the page is hidden. User and steering chat seats stay, so the rewind control still shows. Also drop unused bindings that already failed eslint, and keep historical files out of printWidth 100 so the max-lines cap still holds.
The narration port renamed the body article marker to data-reader-body, but usePinnedSelection still only queried data-reader-answer, so a live selection in streaming body text was cleared when final formatting landed. Query both markers and lock it with a test.
…r throws A throwing read() reached the Reader's error boundary and replaced both reasoning and answer with error notices that never recovered. Catch read/subscribe/unsubscribe failures, show the original text, and re-read on the next change or notify so a recovered transformer takes over.
…ween body blocks (fixes #73)
The lint cleanup removed inboxAttachmentCount while nothing called it. The assistant-step merge counts non-submission inbox rows with it.
The mirrored seat is dsh-better-display.official.nodes/conversation.chat.node, so a selector for conversation.chat.node matched nothing. The host row shrink-wrapped and its own 82% ran a second time. Stretch that row to the column and leave .userStack alone. Pending bubbles carry the same cap directly.
A theme that clears or fades the background token was painting the text colour into the lane, and one global height map let a second Reader freeze the first row. Underlay the lanes with Canvas, keep the 40px floor, and give each Reader its own lane-height map.
…tory A supplementary rewind still rolled the chat keys back, then readerFlow put the cut step's tool draft back on screen. Loading older history appended the new turns after the ones already shown. Reduced motion unmounted focused cut content and left focus on the document. Live slots now follow the incoming group order, and a departing slot stays next to the live neighbour that preceded it. A draft with no tool-call node yet still shows while its step is outside the cut. Reduced motion moves focus to a surviving turn or the reading column before the cut unmounts, and still does not pin the collapse.
…rty themes (#66) Conflicts were the lint cleanup both sides made independently. Keep the integration side, plus two semantic repairs the textual merge missed: restore inboxAttachmentCount (#65 calls it, #66 deleted it as unused) and restore the raw-key fallback in redactString (each side fixed the lint warning differently and the combination left `key` unassigned). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The animated path returned early while focus sat inside cut content, before the visibilitychange listener was registered, and document.hidden is not state. A page hidden while the collapse waited kept the rows mounted. The focus-held branch now listens too and retires at once, moving focus with focusSurvivesRetire like the hidden-page path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reading column is a tabIndex -1 target for focus that leaves cut content. In keyboard modality a programmatic focus matched :focus-visible and the host drew the UA outline around the whole transcript. Suppress the outline on the column itself only; descendants keep their rings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts were again the shared lint cleanup, the AssistantNode that #65 moved to AssistantNode.tsx (#64 did not change it), and the sticky-lane rule #66 rewrote next to #64's retiring-lane margin; keep both CSS intents. Restore inboxAttachmentCount, which #64 deleted as unused while the pending-inbox row still calls it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ula (#74) Conflicts were the shared lint cleanup (McpAppFrame setReady, live-turn foldableRun, GroupStatus props), the AssistantNode move from #65, and the #66/#64 sticky-lane and turn-spacing rules next to the new .userCluster rules. Kept the integration side for all of those and took #74's bubble rules. Restored inboxAttachmentCount, which #74 also dropped as unused while #65 still calls it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 26, 2026
This was referenced Oct 26, 2026
Closed
Closed
Merged
LingMoe404
added a commit
to LingMoe404/dsh-better-display
that referenced
this pull request
Oct 29, 2026
The official COT translation bundle registers translated reasoning on `conversation.chat.reasoning.body`, and the reading view replaces that view, so enabling the bundle cannot paint translation here. aa2246740#76's text-transform seam is the supported way in, but the docs only sketch a synchronous uppercase example. Add a worked adapter under `examples/cot-translation-reader/` that registers `reasoning`, reads `ctx.cotTranslation` lazily, splits completed paragraphs to `maxTextChars`, caches results per block, and leaves the source on screen when a request fails. The new section in `docs/extension-points.md` records the four traps: synchronous `read`, no half-written streaming tail, per-block caching, and `undefined` on failure.
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.
Description
Integrates every open issue and contributor PR that triage confirmed as a real defect or a wanted feature. Each item was developed and verified on its own branch first, then merged here with
--no-ff:npm run lintpasses onmainagain.思考×N · 工具×K · 记录×Mseam between body blocks expands in place. A live turn no longer draws a second summary row when its live-fold cell already counts the same steps ([0.3.11] 进行中的轮次里同一段过程出现两行相同摘要(live-fold 标题 + narration 接缝行重复统计) #73). Contributor commits from PR feat(reader): keep narration visible and summarise folded process between body blocks #68 are kept with their original authorship.dsh-better-display.text-transform). Another plugin can rewrite reasoning and answer text before the reading reveal. Copy, transcript and folding keep the original text, and a transformer that throws falls back to the original.conversation.chat.noderenderer forassistant-step(for exampledsh-raw-html-v2) now renders the answer body inside Reader, so HTML cards no longer degrade to code blocks. Reasoning and folding stay with Reader.--dsw-alias-bg-base/--dsw-alias-bg-layer-1. They sit on aCanvasunderlay, stay at least 40px tall, follow content font size, and each Reader owns its own lane heights.dsh-rewind-pluginrewind rolls the cut range out of Reader with a 220ms collapse (instant under reduced motion). Focus moves off retiring content and the column draws no focus ring. Failed or cancelled rewinds leave everything in place. Contributor commit from PR fix(reader): roll back rewound conversation turns #64 is kept with its original authorship.min(axis × 0.702, 82%)against the full column, and the host 14px/22px metrics. They now match native Chat exactly and no longer jump when a pending bubble becomes official.lib/is rebuilt once at the end (81b9b93).Not included: Dependabot #70 (tsdown) waits for the repo's 7-day rule; #69 (katex 0.19) needs a host katex upgrade first.
Testing
npm run lint,npm run typecheck,npm test(44 files, 259 tests) andnpm run buildpass on the head. Test declarations were counted after every merge so none were lost.lib/. All items passed:dsh-raw-html-v20.8.0 card renders inside Reader (about 717×153px), with the 建议:给阅读页加一层「思考链 / 回答」实时翻译(对标 dsh-think-translate) #62 transformer installed at the same time.dsh-rewind-plugin0.15.3 passes the collapse, reduced-motion, focus and cancel/failure checks.GET /better-display/skill-statusandPOST /better-display/revealreturn 200. Glass mode, dark mode, reduced motion, Tab order, stop, fork and copy all pass.lib/client.jsdepend on the absolute checkout path (tools/client-build.js), so a fresh build in another directory differs from the committedlib/only in class-name hashes.Context
Fixes #62
Fixes #63
Fixes #65
Fixes #66
Fixes #73
Fixes #74
Supersedes #64 and #68: their commits are included here, rebased onto current
mainwith authorship preserved. Those PRs will be closed by hand after this merges. Merge with a merge commit (not squash) to keep the per-item merge history.Harness: 0.2.0-rc.2 (compat check baseline). The reporter environment for #74 was DSH Desktop 0.2.1-rc.3 on Windows, which was not tested.
🤖 Generated with Claude Code