Repository navigation
feat(tui): print session transcript to scrollback on exit - #134
Merged
Merged
Conversation
Quitting the TUI restored the alternate screen and threw the conversation away. The exit epilogue can now be a lazy thunk, materialized in the renderer destroy listener while the reactive tree is still alive; the session route's thunk prepends a compact Claude-Code-style transcript (user "> " prompts, assistant text, dim one-line tool calls) to the logo/session epilogue. Also fixes a teardown race where the route onCleanup cleared the epilogue during Solid dispose before it printed, and repairs the epilogue lifecycle test: its session id "dummy" collided with the fork's placeholder route id, so the session route never mounted and the test could never pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The exit transcript takes optional theme colors (text, textMuted, error) and emits truecolor ANSI: user/assistant text in the theme text color, tool one-liners muted, error-status tools in the error color. The session route passes the active theme; without colors the formatter keeps the plain dim fallback. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Assistant text printed at quit was raw markdown in a single color. Approximate the session's <markdown> renderable line by line using the theme's markdown* colors: headings bold in markdownHeading, bold/italic spans in markdownStrong/markdownEmph, inline code and fenced blocks in markdownCode, list bullets in markdownListItem, blockquotes in markdownBlockQuote, links underlined in markdownLink with the URL muted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop the codev wordmark banner and the "Session <title>" line from sessionEpilogue; the exit transcript already shows the conversation, so only the "Continue codev -s <id>" resume hint remains. Removes the now unused title input. Co-Authored-By: Claude Fable 5 <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.
What
Quitting the TUI restored the alternate screen and threw the conversation away, leaving only the logo + Session/Continue epilogue. Now the exit path prints a compact, Claude Code-style transcript of the session to the normal terminal scrollback first: user prompts prefixed with
>, assistant replies as plain text, and tool calls as dim one-line summaries like⏺ Bash(bun test)(no thinking, no tool output), followed by the usual epilogue. The transcript is painted with the session's active theme colors — text, muted, and error (failed tool calls) — as truecolor ANSI, and assistant replies get a line-based markdown approximation of the session's renderer: headings, bold, italic, inline code, code fences, list bullets, and links styled with the theme's markdown colors. Empty sessions keep the current epilogue-only behavior.How
string | (() => string)). The session route sets a thunk that builds transcript + epilogue;app.tsxmaterializes it in itsrenderer.once("destroy")listener, which fires before@opentui/solid's dispose listener — so the sync store is still alive, and message updates during the session never rebuild the transcript.packages/tui/src/util/exit-transcript.tsmaps each tool to its primary argument (bash → command, read/edit/write → relative path via the path formatter, glob/grep → pattern, …) with a first-string-input fallback.Bug fixes along the way
onCleanup(() => setEpilogue())ran during Solid dispose and clobbered the epilogue beforerun()printed it. The provider setter now ignores writes oncerenderer.isDestroyed.dummycollides with the fork's pre-navigation placeholder route id, so the Session route never mounted and the test could never pass. Renamed toses_demo, stubbed the session-scoped endpoints + a paid model (keeps the first-run configure dialog closed), and the test now asserts the transcript end-to-end after a deterministic wait for the session view.Bookkeeping
DIVERGENCES.md: combined row for the four edited upstream files (app.tsx,context/epilogue.tsx,routes/session/index.tsx,test/app-lifecycle.test.tsx); the formatter + its test are fork-only.CHANGELOG.md: Unreleased → TUI entry.Verification
bun typecheckclean (full turbo run via pre-push hook).packages/tuisuite green (241 pass, 0 fail).packages/opencode: a real turn with bash + read tools, then Ctrl+D — scrollback shows the>prompt line,⏺ Bash(cat README.md), the assistant reply, then the wordmark epilogue; an empty session prints only the epilogue.🤖 Generated with Claude Code