From 818a8a41f965b8fef822592c9a75cde3e76bf79e Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Thu, 25 Dec 2025 02:07:23 -0800 Subject: [PATCH] Clear tmux scrollback on handoff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds ClearHistory method to tmux package and calls it before respawn-pane during handoff. This resets copy-mode display from [0/N] to [0/0] for a clean session start. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/cmd/handoff.go | 14 ++++++++++++++ internal/tmux/tmux.go | 8 ++++++++ 2 files changed, 22 insertions(+) diff --git a/internal/cmd/handoff.go b/internal/cmd/handoff.go index 8808e5e9..690f04aa 100644 --- a/internal/cmd/handoff.go +++ b/internal/cmd/handoff.go @@ -137,10 +137,17 @@ func runHandoff(cmd *cobra.Command, args []string) error { // Dry run mode - show what would happen if handoffDryRun { + fmt.Printf("Would execute: tmux clear-history -t %s\n", pane) fmt.Printf("Would execute: tmux respawn-pane -k -t %s %s\n", pane, restartCmd) return nil } + // Clear scrollback history before respawn (resets copy-mode from [0/N] to [0/0]) + if err := t.ClearHistory(pane); err != nil { + // Non-fatal - continue with respawn even if clear fails + fmt.Printf("%s Warning: could not clear history: %v\n", style.Dim.Render("⚠"), err) + } + // Use exec to respawn the pane - this kills us and restarts return t.RespawnPane(pane, restartCmd) } @@ -395,6 +402,7 @@ func handoffRemoteSession(t *tmux.Tmux, targetSession, restartCmd string) error // Dry run mode if handoffDryRun { + fmt.Printf("Would execute: tmux clear-history -t %s\n", targetPane) fmt.Printf("Would execute: tmux respawn-pane -k -t %s %s\n", targetPane, restartCmd) if handoffWatch { fmt.Printf("Would execute: tmux switch-client -t %s\n", targetSession) @@ -402,6 +410,12 @@ func handoffRemoteSession(t *tmux.Tmux, targetSession, restartCmd string) error return nil } + // Clear scrollback history before respawn (resets copy-mode from [0/N] to [0/0]) + if err := t.ClearHistory(targetPane); err != nil { + // Non-fatal - continue with respawn even if clear fails + fmt.Printf("%s Warning: could not clear history: %v\n", style.Dim.Render("⚠"), err) + } + // Respawn the remote session's pane if err := t.RespawnPane(targetPane, restartCmd); err != nil { return fmt.Errorf("respawning pane: %w", err) diff --git a/internal/tmux/tmux.go b/internal/tmux/tmux.go index 6955435f..d7163848 100644 --- a/internal/tmux/tmux.go +++ b/internal/tmux/tmux.go @@ -582,6 +582,14 @@ func (t *Tmux) RespawnPane(pane, command string) error { return err } +// ClearHistory clears the scrollback history buffer for a pane. +// This resets copy-mode display from [0/N] to [0/0]. +// The pane parameter should be a pane ID (e.g., "%0") or session:window.pane format. +func (t *Tmux) ClearHistory(pane string) error { + _, err := t.run("clear-history", "-t", pane) + return err +} + // SwitchClient switches the current tmux client to a different session. // Used after remote recycle to move the user's view to the recycled session. func (t *Tmux) SwitchClient(targetSession string) error {