feat(cli): show the change, the reasoning, and the whole error - #218
Merged
Conversation
The REPL printed a tool call as one line, its result truncated at 200 characters, no colour anywhere, and threw away every reasoning token the model produced. Approving an Edit meant answering y/n to a tool name with no way to see what it would do. Finding A in docs/THREE_WAY_REVIEW.md. Diffs. Edit and Write now render a hunked, capped unified diff — at the approval prompt, and again when the call runs, so acceptEdits mode (no prompt) still shows the change. Write is diffed against the file on disk when one exists, so an overwrite doesn't read as a creation. Bash prints its command in full, every line, rather than the first 80 characters. Reasoning. thinking_delta went to `return`. It now streams into a dim gutter that closes before anything else prints. DeepSeek's reasoner is the premise of this product and its reasoning was the one thing the CLI dropped. `--no-thinking` opts out. Output. Tool results elide the middle rather than cutting at 200 bytes — the tail of a failing command is usually the part that matters. Single pathological lines (minified JSON, base64) are clipped so they can't flood the terminal. Colour. Resolved once at startup from --no-color, NO_COLOR, FORCE_COLOR, TERM=dumb and whether stdout is a TTY, then threaded through as a palette, so piped output is byte-identical minus the escapes. The line differ moves from apps/desktop/src/lib/diff.ts into core, where the CLI can reach it; the desktop module re-exports it, so the file panel and the terminal now show the same diffs from the same code. Two bugs caught by rendering real output rather than trusting the tests: reasoning was painted per character (kilobytes of escape soup for a paragraph), and a failing command's elision marker was painted twice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
oratis
pushed a commit
that referenced
this pull request
Aug 3, 2026
The protocol carried reasoningTokens and nothing else, so DeepSeek's reasoner produced its most distinctive output and every client dropped it. The CLI got this in #218; the desktop could not, because there was nothing on the wire to render. Adds a `reasoning.delta` transient event behind a `reasoningDeltas` capability. Separate from `item.delta` rather than a flag on it: reasoning is not the answer, it is never persisted as a completed item, and a client that doesn't understand the type has to be able to drop it rather than accidentally render it as assistant text. The app-server forwards the agent loop's thinking_delta events; the desktop projects them onto the assistant turn as a distinct `reasoning` field — kept out of `text` precisely so it can be rendered as its own channel — and shows a collapsed `▸ thinking · N lines` block above the answer. Collapsed because reasoner output is long and is not the response; the line count is there because while a turn streams it is often the only thing to look at. VS Code and the LSP bridge forward protocol events unchanged, so they receive the new event without changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
oratis
added a commit
that referenced
this pull request
Aug 3, 2026
* feat(protocol): carry reasoning, and show it in the desktop The protocol carried reasoningTokens and nothing else, so DeepSeek's reasoner produced its most distinctive output and every client dropped it. The CLI got this in #218; the desktop could not, because there was nothing on the wire to render. Adds a `reasoning.delta` transient event behind a `reasoningDeltas` capability. Separate from `item.delta` rather than a flag on it: reasoning is not the answer, it is never persisted as a completed item, and a client that doesn't understand the type has to be able to drop it rather than accidentally render it as assistant text. The app-server forwards the agent loop's thinking_delta events; the desktop projects them onto the assistant turn as a distinct `reasoning` field — kept out of `text` precisely so it can be rendered as its own channel — and shows a collapsed `▸ thinking · N lines` block above the answer. Collapsed because reasoner output is long and is not the response; the line count is there because while a turn streams it is often the only thing to look at. VS Code and the LSP bridge forward protocol events unchanged, so they receive the new event without changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(test): restore the describe block the rebase truncated The conflict boundary fell inside a describe(), so the file lost its closing braces and esbuild refused it. Same shape as the CSS seam in #220 — resolving a conflict by keeping both sides needs a structural check, not just "no markers left". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: t <t@t> Co-authored-by: Claude Opus 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.
Finding A from
docs/THREE_WAY_REVIEW.md— the CLI presentation layer. The REPL printed a tool call as one line, its result cut at 200 characters, no colour anywhere, and dropped every reasoning token the model produced. Approving anEditmeant answering y/n to a tool name.What changes
Diffs.
EditandWriterender a hunked, capped unified diff — at the approval prompt, and again when the call runs, soacceptEdits(which has no prompt) still shows the change.Writeis diffed against the file on disk when one exists, so an overwrite doesn't read as a creation.Bashprints its command in full, every line.Long files collapse: a two-line change in a 900-line file prints as ~6 rows with
⋯markers, and a whole-file rewrite caps with⋯ N more changed lines.Reasoning.
thinking_deltawent straight toreturn. It now streams into a dim gutter that closes before anything else prints. DeepSeek's reasoner is the premise of this product and its reasoning was the one thing the terminal threw away.--no-thinkingopts out.Output. Tool results elide the middle instead of cutting at 200 bytes — the tail of a failing command is usually the part that matters. Single pathological lines (minified JSON, base64) are clipped so they can't flood the terminal.
Colour. Resolved once at startup from
--no-color,NO_COLOR,FORCE_COLOR,TERM=dumb, and whether stdout is a TTY, then threaded through as a palette — piped output is byte-identical minus the escapes.Shared differ
apps/desktop/src/lib/diff.tsmoves intopackages/core/src/util/diff.ts; the desktop module re-exports it. The file panel and the terminal now render diffs from one implementation instead of two.Review notes
Two bugs came out of rendering real output rather than trusting green tests, both now covered:
ESC[2mT ESC[0m ESC[2mh ESC[0m …, kilobytes of escape soup for one paragraphESC[31m ESC[2m … ESC[0m ESC[0m)render.tsis pure string → string, so all of it is tested without a TTY: 29 new cases covering colour precedence, diff hunking/capping, elision, approval previews per tool, and the reasoning stream's line-state machine.Verification
pnpm typecheck·lint·format:checkclean. core 718/16 skipped · cli 204 · desktop 54 · server 41 · protocol 24 · vscode 12 · lsp 13 · scripts 21. Rendered sample output through the built module and read the raw bytes withcat -v— that is how both colour bugs surfaced.🤖 Generated with Claude Code