Skip to content

fix: keep outer spinner alive across hook boundary#367

Merged
avihut merged 1 commit intomasterfrom
fix/worktree-deletion-indication
Apr 17, 2026
Merged

fix: keep outer spinner alive across hook boundary#367
avihut merged 1 commit intomasterfrom
fix/worktree-deletion-indication

Conversation

@avihut
Copy link
Copy Markdown
Owner

@avihut avihut commented Apr 17, 2026

Summary

  • daft remove (and any command running a lifecycle hook while an outer spinner is active) fell silent during the filesystem-delete phase after the pre-remove hook finished, leaving an unexplained pause between the hook summary and the Deleted <branch> line.
  • Root cause: the hook's own indicatif::MultiProgress shared stderr with the command-level ProgressBar, so the outer spinner's steady ticks no longer redrew once the hook renderer relinquished the terminal. Step-label updates like Removing worktree at <path> were being written to a spinner that had effectively stopped painting.
  • Fix: CommandBridge::run_hook now brackets HookExecutor::execute with pause_spinner / resume_spinner. CliOutput stashes the active message on pause, clears the spinner cleanly, and rebuilds a fresh ProgressBar on resume with the preserved label.
  • Secondary bug (caught during iteration): the hook executor defensively calls output.finish_spinner() before drawing its own UI. The initial patch cleared paused_spinner_message inside finish_spinner, silently defusing the subsequent resume_spinner. finish_spinner no longer touches the paused-message field; ownership of that field belongs exclusively to the pause/resume pair.

Test plan

  • cargo test -p daft --lib -- core::progress::tests::run_hook_brackets_executor_with_spinner_pause_resume — asserts pause/resume brackets executor.execute
  • cargo test -p daft --lib -- output::cli::tests::finish_spinner_preserves_paused_message_across_hook_call — regression against the defensive finish_spinner clobbering saved state
  • Both regression tests bisected: fail on pre-fix, pass on fix
  • mise run clippy — clean
  • mise run fmt:check — clean
  • Manual TTY verification: daft remove <branch> in a sandbox with a worktree-pre-remove hook — expect a ticking spinner labeled Removing worktree at <path>... during the previously silent pause
  • Follow-up (not in this PR): non-TTY / --quiet paths still have no activity line for the fs-delete phase

Notes

  • Scope kept to interactive-TTY rendering. Non-TTY and --quiet were deliberately left out; they're a separate UX decision worth its own PR.
  • Default no-op trait methods on Output keep BufferingOutput (TUI path) unchanged.

🤖 Generated with Claude Code

@avihut avihut added this to the Public Launch milestone Apr 17, 2026
@avihut avihut added the fix Bug fix label Apr 17, 2026
@avihut avihut self-assigned this Apr 17, 2026
Add pause_spinner/resume_spinner to the Output trait so CommandBridge
can suspend the command-level spinner around HookExecutor::execute().
Without this, the hook's own indicatif MultiProgress fights the outer
ProgressBar for stderr, and subsequent step-label updates (e.g.
"Removing worktree at <path>") stay invisible during the
filesystem-delete phase — leaving the user with an unexplained pause.

CliOutput remembers the active spinner's message on pause and
recreates a fresh spinner on resume with that message. finish_spinner
deliberately does not touch paused_spinner_message: HookExecutor calls
finish_spinner defensively before rendering, and clearing the saved
state there would turn resume_spinner into a silent no-op.

Regression coverage:
- core::progress::tests — asserts run_hook brackets the executor with
  pause/resume entries in order
- output::cli::tests — asserts the saved message survives the
  executor's defensive finish_spinner call

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@avihut avihut force-pushed the fix/worktree-deletion-indication branch from 46367d5 to d25126b Compare April 17, 2026 21:29
@avihut avihut merged commit 9455fbe into master Apr 17, 2026
8 checks passed
@avihut avihut deleted the fix/worktree-deletion-indication branch April 17, 2026 21:38
This was referenced Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant