Skip to content

feat: add hook execution progress display with spinners#217

Merged
avihut merged 14 commits intomasterfrom
daft-203/hook-prints
Feb 17, 2026
Merged

feat: add hook execution progress display with spinners#217
avihut merged 14 commits intomasterfrom
daft-203/hook-prints

Conversation

@avihut
Copy link
Owner

@avihut avihut commented Feb 17, 2026

Summary

  • Add rich hook execution output with indicatif spinners, rolling output windows, framed headers, and per-job summaries with duration tracking
  • Support both TTY (spinners) and non-TTY (plain text) rendering with configurable daft.hooks.output.* settings
  • Force colors through shell wrapper via CLICOLOR_FORCE=1, suppress hook output in tests, and print result messages to stderr when running through the wrapper for correct ordering
  • Show "No output" in dark grey italicized text for jobs that produce no output
  • Add "Removed worktree" result messages to prune, flow-eject, and branch-delete commands

Fixes #203

Test plan

  • Run mise run test to verify all unit and integration tests pass
  • Manually test gwtcbm <branch> and verify "Created worktree" appears before hook output
  • Manually test gprune and verify "Removed worktree" appears before post-remove hooks
  • Verify colors work through shell wrapper (gwtcbm, gwtco, gwtfetch)
  • Verify hook output is suppressed in test runs (no ANSI junk in test output)
  • Test non-TTY rendering by piping: git worktree-checkout-branch test 2>&1 | cat

🤖 Generated with Claude Code

avihut and others added 14 commits February 16, 2026 22:29
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire the HookProgressRenderer into execute_parallel(),
execute_dag_parallel(), and execute_dag_sequential() so all hook
execution paths now display real-time progress spinners and rolling
output.

For parallel execution, each job thread spawns a reader thread that
drains the mpsc channel and updates the renderer via Arc<Mutex<>>
(or &Mutex<> for scoped threads in the DAG executor). The renderer
is shared safely across threads with proper locking.

Also removes the now-unused run_shell_command() wrapper since all
call sites use run_shell_command_with_callback() directly, and
includes the executor.rs change to pass output_config through to
the YAML executor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When stderr is not a terminal (CI, pipes, redirected output), the
indicatif spinners and ANSI cursor manipulation produce garbled
output. This adds a PlainHookRenderer that prints simple text lines
to stderr, and a HookRenderer enum that auto-detects the environment
using std::io::IsTerminal to dispatch to the appropriate renderer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace raw output.step()/output.raw() calls in execute_legacy() with
HookRenderer, giving legacy script hooks the same spinner and progress
display as YAML hooks. The old execute_hook_file() is replaced by
execute_hook_file_with_renderer() which reads stdout/stderr in separate
threads and feeds captured lines to the renderer after the process exits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace dark-grey background header with a dark-grey framed box using
  box-drawing characters, with bold+white hook name emphasis
- Add summary section after hook execution with per-job results, check/cross
  markers, and durations formatted to scale (ms/s/min)
- Fix shell wrapper capturing stderr (2>&1) which disabled colors for
  wrapped commands; now only stdout is captured for __DAFT_CD__ markers
- Extract format_header_lines() and format_summary_lines() as shared
  helpers to eliminate duplication across renderer variants
- Add extra blank line before summary separator for visual spacing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…pper

- Add DAFT_TESTING env var check to suppress hook header/summary output
  during integration tests (set in xtask test runner)
- Add cfg!(test) check to suppress output during unit tests
- Respect CLICOLOR_FORCE env var in colors_enabled() / colors_enabled_stderr()
  following the standard CLICOLOR convention
- Set CLICOLOR_FORCE=1 in both bash/zsh and fish shell wrappers so all
  commands produce colored output even though stdout is captured by $()
- Add missing chevron (❯) to finished job line in HookProgressRenderer
- Change chevron color from grey to orange

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use insert_after to place the "No output" bar after the finished
spinner instead of mp.println which always inserts above the drawing
area.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move "Created worktree" and "Prepared worktree" result messages before
post-create hooks so they appear in the correct chronological order.
Print result() to stderr when running through the shell wrapper so it
appears in real-time instead of after the command finishes.

Add "Removed worktree" result messages to prune, flow-eject, and
branch-delete commands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@avihut avihut added this to the v1.1.0 milestone Feb 17, 2026
@avihut avihut added the feat New feature label Feb 17, 2026
@avihut avihut self-assigned this Feb 17, 2026
@avihut avihut merged commit 2809ff1 into master Feb 17, 2026
4 checks passed
@avihut avihut deleted the daft-203/hook-prints branch February 17, 2026 05:37
This was referenced Feb 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hook prints

1 participant