fix(hook_runner): v5.1.2 — wait for real clip length on Windows (#14)#15
Merged
Merged
Conversation
…t truncated (#14) Every PowerShell playback snippet in play_audio_windows (three fallback methods) and play_audio_wsl used a fixed Start-Sleep -Seconds 3 before calling $player.Stop(); $player.Close(). The default audio/default/permission-request.mp3 is ~3.4s (70,989 bytes, 128 kbps after a 16 kB ID3v2 tag), so PowerShell tore the player down ~0.4s early and the tail of the clip was always cut off on Windows. The default elicitation.mp3 (~3.1s) was also clipped; subagent-start.mp3 and notification-urgent.mp3 were on the edge. Fix: poll the media player for the real clip length, then sleep for duration + 500ms tail buffer before Stop()/Close(). - PresentationCore MediaPlayer (Methods 1 & 2 and the WSL path): MediaPlayer.Open() is async, so we poll $player.NaturalDuration.HasTimeSpan with a 1.5s ceiling, then Start-Sleep -Milliseconds ([int]($player.NaturalDuration.TimeSpan.TotalMilliseconds + 500)). - WMPlayer.OCX (Method 3): same pattern on $w.currentMedia.duration. - Fallback when the player never reports a duration (corrupt file, etc.): Start-Sleep -Seconds 10 — generous enough to cover any plausible default clip, still bounded so the PowerShell host process does not leak. The Python subprocess layer was already fire-and-forget (subprocess.Popen); the fix closes the gap that was inside the PowerShell command string itself. macOS afplay and Linux mpg123/ffplay/paplay/aplay are unaffected: those players block until playback completes by default. Version bump to 5.1.2 across the usual version-holding files: - hooks/hook_runner.py (HOOK_RUNNER_VERSION) - bin/audio-hooks.py (PROJECT_VERSION) - .claude-plugin/marketplace.json (metadata + plugin entry) - plugins/audio-hooks/.claude-plugin/plugin.json - config/default_preferences.json (_comment + _version + version) - CLAUDE.md header + Version history row - README.md version badge + sequence diagram + status line example - docs/ARCHITECTURE.md status line example - plugins/audio-hooks/skills/audio-hooks/SKILL.md status line example CHANGELOG.md gets a 5.1.2 entry. Plugin copies synced via scripts/build-plugin.sh; scripts/build-plugin.sh --check reports in_sync:true. Fixes #14 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Fixes Windows/WSL audio clips being truncated by replacing fixed PowerShell Start-Sleep delays with duration-aware waits, and bumps the project/plugin version to 5.1.2 across canonical + synced plugin copies.
Changes:
- Update Windows/WSL PowerShell playback snippets to poll for real media duration and sleep for
duration + 500ms(with bounded fallback). - Bump version strings to
5.1.2across CLI, hook runner, plugin manifests, and default config templates. - Refresh documentation/examples (README/ARCHITECTURE/CLAUDE/CHANGELOG/SKILL) to reflect
v5.1.2.
Reviewed changes
Copilot reviewed 11 out of 13 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| plugins/audio-hooks/skills/audio-hooks/SKILL.md | Updates status line example version to v5.1.2. |
| plugins/audio-hooks/hooks/hook_runner.py | Windows/WSL playback now waits for actual clip length (synced plugin copy). |
| plugins/audio-hooks/config/default_preferences.json | Bumps default config template version fields to 5.1.2. |
| plugins/audio-hooks/bin/audio-hooks.py | Bumps CLI PROJECT_VERSION to 5.1.2 (synced plugin copy). |
| plugins/audio-hooks/.claude-plugin/plugin.json | Bumps plugin manifest version to 5.1.2. |
| hooks/hook_runner.py | Windows/WSL playback now waits for actual clip length (canonical source). |
| docs/ARCHITECTURE.md | Updates status line example version to v5.1.2. |
| config/default_preferences.json | Bumps default config template version fields to 5.1.2 (canonical). |
| bin/audio-hooks.py | Bumps CLI PROJECT_VERSION to 5.1.2 (canonical). |
| README.md | Updates badge + examples to v5.1.2. |
| CLAUDE.md | Updates header/version history with the Windows truncation fix entry. |
| CHANGELOG.md | Adds 5.1.2 release notes describing the Windows/WSL playback fix. |
| .claude-plugin/marketplace.json | Bumps marketplace/plugin listing versions to 5.1.2. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
permission-request.mp3(~3.4 s) andelicitation.mp3(~3.1 s) were always truncated on Windows because every PowerShell playback snippet hard-codedStart-Sleep -Seconds 3before$player.Stop(); $player.Close().hooks/hook_runner.py(three fallback methods inplay_audio_windows+ the WSL path inplay_audio_wsl) now poll the media player for the actual clip length and sleep forduration + 500 mstail buffer. PresentationCoreMediaPlayeruses$player.NaturalDuration.HasTimeSpanwith a 1.5 s poll ceiling (Open()is async); WMPlayer.OCX uses$w.currentMedia.duration. FallbackStart-Sleep -Seconds 10if the player never reports a duration — generous but bounded so the PowerShell host doesn't leak.afplay) and Linux (mpg123/ffplay/paplay/aplay) are unaffected: those players block until playback completes by default.scripts/build-plugin.sh;CHANGELOG.md+CLAUDE.mdVersion-history row updated.Why not the reporter's other options
MediaPlayeris hosted inside the PowerShell process; if PowerShell exits before playback completes, the player is disposed mid-clip. The Pythonsubprocess.Popenlayer was already fire-and-forget; this PR closes the gap that was inside the PowerShell command string.Test plan
bash scripts/build-plugin.sh --check→{"ok":true,"in_sync":true,"checked":60}import hook_runnerfrom bothhooks/andplugins/audio-hooks/hooks/→ both print5.1.2python bin/audio-hooks.py version | status | diagnose→ valid JSON,"version":"5.1.2",errors:[],warnings:[]python bin/audio-hooks.py test all→{"ok":true,"passed":26,"failed":[],"total":26}python bin/audio-hooks.py test permission_request→ dispatches cleanly;logs tail --level errorstays empty after playbacksmokeworkflow (Ubuntu / Windows / macOS × Python 3.9 / 3.12 / 3.13) — should stay greenaudio-hooks test permission_request— confirm the ~0.4 s tail that used to be cut off is now audible; same foraudio-hooks test elicitation🤖 Generated with Claude Code