diff --git a/rebase-upstream.sh b/rebase-upstream.sh new file mode 100755 index 00000000..86706964 --- /dev/null +++ b/rebase-upstream.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +# Rebase claw-code feat-tui onto latest upstream/main (ultracode) +# Run from repo root: ./rebase-upstream.sh +# +# Prereq: remotes configured +# upstream → ultracode/claw (or whatever the upstream org/repo is) +# origin → your fork + +set -euo pipefail + +BRANCH="feat-tui" +REMOTE_UPSTREAM="upstream" +REMOTE_ORIGIN="origin" + +cd "$(git rev-parse --show-toplevel)" + +echo "🔄 Rebasing $BRANCH onto $REMOTE_UPSTREAM/main" + +# Make sure we're on the right branch +current=$(git branch --show-current) +if [ "$current" != "$BRANCH" ]; then + echo "❌ Not on $BRANCH (on $current). Switch first." + exit 1 +fi + +# Stash any uncommitted work +if ! git diff --quiet || ! git diff --cached --quiet; then + echo "📦 Stashing uncommitted changes..." + git stash push -m "auto-stash before rebase $(date +%Y%m%d-%H%M%S)" + STASHED=true +else + STASHED=false +fi + +# Fetch upstream +echo "⬇️ Fetching $REMOTE_UPSTREAM..." +git fetch "$REMOTE_UPSTREAM" + +# Check if upstream/main moved +OLD_BASE=$(git merge-base "$BRANCH" "$REMOTE_UPSTREAM/main") +NEW_HEAD=$(git rev-parse "$REMOTE_UPSTREAM/main") + +if [ "$OLD_BASE" = "$NEW_HEAD" ]; then + echo "✅ Already up to date with $REMOTE_UPSTREAM/main ($NEW_HEAD)" +else + echo "📋 Rebasing... ($OLD_BASE → $NEW_HEAD)" + echo " $(git log --oneline $OLD_BASE..$NEW_HEAD | wc -l) new upstream commits" + if ! git rebase "$REMOTE_UPSTREAM/main"; then + echo "" + echo "⚠️ CONFLICTS! Resolve them, then:" + echo " git add " + echo " git rebase --continue" + echo "" + echo " To abort: git rebase --abort" + exit 1 + fi + echo "✅ Rebase complete" +fi + +# Force push to origin (safe — only your fork) +echo "⬆️ Force-pushing to $REMOTE_ORIGIN/$BRANCH..." +git push --force-with-lease "$REMOTE_ORIGIN" "$BRANCH" + +# Restore stashed work +if [ "$STASHED" = true ]; then + echo "📦 Restoring stashed changes..." + git stash pop +fi + +echo "" +echo "🎉 Done! $BRANCH is now rebased on $REMOTE_UPSTREAM/main" +echo " HEAD: $(git log --oneline -1)" +echo " $(git log --oneline "$REMOTE_UPSTREAM/main".."$BRANCH" | wc -l) commits ahead of upstream" diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index 0e1e4515..4fdc4935 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -7301,18 +7301,20 @@ fn run_tui_repl(mut cli: LiveCli) -> Result<(), Box> { let mut buf: Vec = Vec::new(); let result = cli.run_turn_to(&trimmed, &mut buf, false); - // Feed the captured output into the conversation pane. - // The buffer may contain ANSI codes from TerminalRenderer — - // strip them before pushing. - let captured = String::from_utf8_lossy(&buf); - let plain = tui_update::strip_ansi(&captured); - if !plain.is_empty() { - app.push_output(&plain, false); + // Wipe the alternate screen in case any runtime internals + // wrote to the real stdout fd despite emit_output=false + // (e.g. child process stderr, tokio tracing, etc.) + { + use crossterm::terminal::ClearType; + let _ = crossterm::execute!( + std::io::stdout(), + crossterm::terminal::Clear(ClearType::All), + crossterm::cursor::MoveTo(0, 0), + ); } - // Also read the last assistant message from the session for - // the conversation pane (richer content than the spinner/status - // lines in the buffer). + // Read the last assistant message from the session for + // the conversation pane. { let messages = &cli.runtime.session().messages; if let Some(msg) = messages.last() { @@ -7336,6 +7338,9 @@ fn run_tui_repl(mut cli: LiveCli) -> Result<(), Box> { } } update_dashboard(&dashboard_state, &cli); + // Force a full clear+redraw to ensure the conversation pane + // is correctly bounded after each turn + let _ = app.redraw_after_turn(); } tui::TuiReadOutcome::Cancel => { // Clear input, stay in TUI