ultraworkers / ultraworkers/claw-code

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

Open Beginner friendly
#3,258 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
195k
Forks
108k
PR merge metrics
No merged PRs in 30d

Description

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 {

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in rust/crates/rusty-claude-cli/src/main.rs, inside LiveCli::run_turn, and inspect how streamed text, final_assistant_text, and spinner.finish interact in non-compact text mode. Run claw in that mode with a response, then verify the assistant text appears only once, the final line is preserved, and the Done status still appears.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.