Skip to content

fix(cli): resolve duplicate assistant text printing after 'Done' in non-compact text mode #3258

Description

@ibmany-spec

Description

When running claw in non-compact text mode, the entire assistant response is printed twice.

  1. First, the text chunks are streamed and printed in real-time during the API call.
  2. Second, after ✔ ✨ Done is printed, the full assistant text (final_text) is printed again.

This causes a large amount of redundant output in the console, especially for long responses.

Cause

In LiveCli::run_turn (inside main.rs), spinner.finish("✨ Done") is called right after the conversation stream finishes.
Because spinner.finish moves the cursor to column 0 and clears the current line, it would erase the last line of the streamed text if we do not print a newline first.
To prevent this, the previous commit introduced a secondary full-text reprint:

let final_text = final_assistant_text(&summary);
if !final_text.is_empty() {
    let renderer = TerminalRenderer::new();
    println!("{}", renderer.markdown_to_ansi(&final_text));
}

However, this reprints the entire assistant message instead of just protecting the last line, causing the duplicate response.

Solution

  1. Print a newline before spinner.finish if the final_text is not empty. This moves the cursor to a new line, ensuring the line-clearing operation in spinner.finish only clears the empty line and does not corrupt the last line of the streamed text.
  2. Remove the redundant final_text reprint logic in run_turn.

Here is the proposed diff in rust/crates/rusty-claude-cli/src/main.rs:

@@ -7763,15 +7763,15 @@
         match result {
             Ok(summary) => {
                 self.replace_runtime(runtime)?;
-                spinner.finish(
-                    "✨ Done",
-                    TerminalRenderer::new().color_theme(),
-                    &mut stdout,
-                )?;
                 let final_text = final_assistant_text(&summary);
                 if !final_text.is_empty() {
-                    let renderer = TerminalRenderer::new();
-                    println!("{}", renderer.markdown_to_ansi(&final_text));
-                }
+                    println!();
+                }
+                spinner.finish(
+                    "✨ Done",
+                    TerminalRenderer::new().color_theme(),
+                    &mut stdout,
+                )?;
                 println!();
                 if let Some(event) = summary.auto_compaction {

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions