Skip to content

fix: auto-remove stale lock files to prevent TTS blocking#84

Open
benmoumen wants to merge 421 commits intopaulpreibisch:masterfrom
benmoumen:fix/stale-lock-cleanup
Open

fix: auto-remove stale lock files to prevent TTS blocking#84
benmoumen wants to merge 421 commits intopaulpreibisch:masterfrom
benmoumen:fix/stale-lock-cleanup

Conversation

@benmoumen
Copy link
Copy Markdown

Summary

  • Fixes TTS permanently blocking with "Skipping TTS (previous audio still playing)" error
  • Adds automatic cleanup of stale lock files older than 30 seconds
  • Uses cross-platform stat command syntax (macOS -f %m, Linux -c %Y)

Problem

The lock file mechanism (/tmp/agentvibes-audio.lock) prevents overlapping audio during learning mode. However, if the background cleanup process at line 411 is killed (e.g., when Claude Code session is interrupted), the lock file remains indefinitely. This causes all future TTS attempts to be skipped.

Solution

Before checking if the lock file exists, we now check if it's stale (older than 30 seconds - well beyond any normal TTS duration) and remove it automatically. This ensures that even if the background cleanup fails, TTS will resume working after 30 seconds.

Test plan

  • Verify TTS works normally on fresh install
  • Create stale lock: touch /tmp/agentvibes-audio.lock then wait 30s
  • Verify TTS resumes after stale lock cleanup
  • Test on both macOS and Linux/WSL

Paul Preibisch and others added 30 commits November 24, 2025 16:17
Output styles code was removed in commit df7520f but the summary line
was left behind, causing 'outputStyleFiles is not defined' error during updates.

Fixes update failure when installing personalities.
- Added CRITICAL RULE: Every response must be in rhyming couplets
- Rewrote all examples with strict AABB rhyme scheme
- Line 1 rhymes with Line 2, Line 3 rhymes with Line 4
- Added 2 new example responses (10 total)
- Clarified techniques: multisyllabic end rhymes, slant rhymes
- Better rhythm guidance: 8-12 syllables per line

Examples now use tight rhyme pairs like:
- tight/right, blessed/best
- lie/apply, grace/race
- flow/show, fame/game
- bars/stars, status/baddest
…soning

- CRITICAL RULE now explicitly covers reasoning steps
- Added 'Example Reasoning' section with rhyming 💭🤔✓ examples
- Reasoning, observations, questions - everything must rhyme
- No exceptions to the AABB rhyme scheme rule

Examples:
- '💭 Let me search through this code with care, Looking for the function hiding somewhere'
- '✓ Found the issue, it's crystal clear, A missing import right up here'
The processBmadTtsInjections function was using process.cwd() for
security validation, but when called from BMAD's installer via npx,
the cwd differs from the actual installation directory. This caused
false "Security: Invalid BMAD path detected" errors.

Changes:
- Modified processBmadTtsInjections to accept targetDir parameter
- Updated isPathSafe to handle path prefix edge cases (/projectX vs /project)
- Added comprehensive test suite for path security validation
- Added Node.js test runner support to package.json

Fixes BMAD-METHOD PR #934 integration issue.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The tts-queue-worker.sh was hardcoding QUEUE_DIR="/tmp/agentvibes-tts-queue"
while tts-queue.sh dynamically determines the directory based on XDG_RUNTIME_DIR.
This caused the worker to look in the wrong directory on systems where
XDG_RUNTIME_DIR is set (most Linux systems), resulting in queued TTS
messages never being played.

Now both scripts use the same logic:
- If XDG_RUNTIME_DIR is set: use $XDG_RUNTIME_DIR/agentvibes-tts-queue
- Otherwise: use /tmp/agentvibes-tts-queue-$USER

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Addresses potential Sonar security hotspots:
- Added directory existence check before processing
- Added ownership verification to prevent symlink attacks
- Fixed unquoted variable in trap command (single quotes)
- Uses stat with fallback for cross-platform compatibility (Linux/macOS)

Defense-in-depth: Worker now validates it owns the queue directory
before processing any files, preventing potential TOCTOU attacks.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Establishes coding standards for AgentVibes development including:
- Security hotspot prevention guidelines
- Shell script security patterns (bash strict mode, secure temp dirs)
- JavaScript/Node.js security patterns (path validation, credential masking)
- Python security patterns (resource cleanup, error handling)
- Pre-release checklist for quality gates

All contributors must follow these standards to pass Sonar quality gates.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Update default BMAD voice assignments with intro messages for party mode
- Swap bmad-master (lessac) and pm/John (ryan) voices for better fit
- Add CLAUDE.md rule requiring user approval before PR pushes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Fix rapper personality to use Antoni voice (Drew was undefined)
- Update README to v2.13.7 with current release notes
- Update installer showReleaseInfo to v2.13.7

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
ElevenLabs deprecated eleven_monolingual_v1 for free tier users as of
November 2025. Switched to eleven_turbo_v2_5 which is fast, high quality,
and free tier compatible.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Replace execSync with execFileSync using array args to prevent command injection
  - mcp-server/install-deps.js
  - src/commands/bmad-voices.js
  - src/commands/install-mcp.js
  - src/installer.js (refactored execScript function)
- Fix regex DoS by using bounded quantifiers in git hash matching
- Replace random.choice with secrets.choice for cryptographic security
- Pin GitHub Action to full SHA for supply chain security

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Update bmad.md documentation table to show both ElevenLabs and Piper columns
- Add migrate_voice_to_provider() function for automatic voice migration when switching providers
- Preserve internal spaces in voice names when reading from config files
- Update tests to verify voice migration and preservation behavior

Fixes paulpreibisch#49

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fixes SonarCloud reliability bug (javascript:S3854) by adding an
initial value to the reduce() call in findVoiceMatch(). This prevents
potential TypeError if the matches array were empty, improving code
reliability and satisfying the Quality Gate requirement.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Paul Preibisch and others added 26 commits December 14, 2025 13:30
Removes the extra console.log blank line in showPaginatedContent that
was creating excessive vertical spacing between page content and the
navigation menu.

🎨 Visual fix:
- Removed blank line between content display and navigation menu building
- Navigation now appears immediately after boxen content
- Tighter, more professional page layout
- Applies to all paginated installer pages

This combined with the bottom margin removal creates the optimal
spacing between content and navigation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed inquirer message from ' ' to '' in configuration navigation
to eliminate extra vertical spacing between content and navigation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Merged cosmetic and UX improvements from better-installer branch:
- Added page navigation with preview icons
- Implemented two-column layouts for summaries
- Fixed auto-advance flow after selections
- Improved welcome message placement
- Eliminated excessive vertical spacing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
removed old elevenlabs docs
The bmad-tts-injector was failing to inject TTS into BMAD v6 agents
because it searched for step 4 with "greet" regex, but the BMAD
compiler puts the greeting in step 5, not step 4.

Changes:
- Simplified pattern from `/<step n="4">.*[Gg]reet/` to `/<step n="4">/`
- Updated error message to match new pattern
- Added comment explaining injection happens after step 4, before step 5

This allows agent voice assignments to work correctly in party mode:
- Mary (analyst) → en_US-kristin-medium
- John (pm) → en_US-ryan-high
- Winston (architect) → en_GB-alan-medium
- etc.

Testing:
- Tested in ~/claude/tests/test27
- All 9 agents now have unique voices
- TTS injection status shows 9/9 enabled

Related: Works with BMAD-METHOD PR 987 (compiler TTS preservation)
Enhance the AgentVibes installer to automatically detect BMAD and prompt
users to enable TTS injection for multi-agent voice support.

Changes:
- Add interactive prompt explaining TTS injection benefits
- Show list of agents that will get unique voices (Mary, John, Winston, etc.)
- Explain what the injection does and how to disable it later
- Auto-enable with --yes flag for non-interactive installs
- Run bmad-tts-injector.sh enable if user agrees
- Handle errors gracefully with manual retry instructions

User Experience:
- Interactive mode: Shows detailed explanation + yes/no prompt (default: yes)
- Non-interactive (--yes): Automatically enables TTS injection
- Clear instructions for disabling later if needed

This completes the automated workflow:
1. User installs BMAD (with PR 987 compiler that preserves TTS data)
2. User installs AgentVibes
3. Installer detects BMAD and prompts for TTS injection
4. If accepted, all agents get unique voices automatically

Testing:
- Syntax validated with node -c
- Ready for fresh install testing

Related: Requires bmad-tts-injector.sh fix (commit 63dd18b)
The bmad-tts-injector.sh was injecting .claude/hooks/play-tts.sh
paths into agent files, which Claude Code resolves as ~/.claude/hooks/
(global) instead of project-local .claude/hooks/.

Changes:
- Updated play-tts.sh references in TTS injection code (4 instances)
- Changed from: .claude/hooks/play-tts.sh
- Changed to: bash .claude/hooks/play-tts.sh

This matches the BMAD party mode fix (BMAD-METHOD commit f91d6833).

Testing: Fixes applied to test28, ready for party mode testing
…aulpreibisch#80 Phase 1)

Reduce token count from ~500 to ~250 by streamlining TTS protocol instructions while maintaining all core functionality. Add strict mode for improved reliability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…rectory bug

Root cause: bmad-voice-manager.sh uses relative paths (.bmad/_cfg/agent-voice-map.csv)
that depend on current working directory. When party mode runs from a different directory,
it reads the wrong CSV file, causing all agents to use the same voice instead of their
unique assigned voices.

Solution: Run bmad-voice-manager.sh with PROJECT_ROOT as working directory to ensure
it always reads the correct project's voice configuration.

Affected files:
- .claude/hooks/bmad-speak.sh: Added cd "$PROJECT_ROOT" before voice lookup
- .claude/hooks/bmad-speak-enhanced.sh: Added cd "$PROJECT_ROOT" before voice lookup

Impact: Party mode now correctly uses unique voices for each agent (pm=ryan-high,
analyst=kristin-medium, architect=alan-medium, etc.) instead of all using default voice.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Updated RELEASE_NOTES.md with v2.17.7 entry
- Updated src/installer.js getReleaseInfoBoxen() with v2.17.7 info
- Updated README.md version badge and Latest Release section

This commit prepares documentation for v2.17.7 release. The version
bump commit will follow via npm version patch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed 12 outdated files to improve repository organization:
- 8 old release notes (v2.4.0-v2.16.0)
- 3 legacy setup scripts (VS Code color fixers, Ubuntu RDP audio)
- Old changelog from October
- Docker volumes report
- Duplicate fixcolors script

All current documentation preserved in RELEASE_NOTES.md and docs/releases/.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updated release documentation:
- RELEASE_NOTES.md: Added v2.17.8 release entry
- src/installer.js: Updated release info box
- README.md: Updated version badge and latest release section

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
## Changes

### Documentation Updates
- **docs/voice-library.md**: Replace fake piper.io URLs with actual Piper voice names
- **docs/providers.md**: Remove ElevenLabs section, add macOS Say provider documentation
- **docs/technical-deep-dive.md**: Major rewrite to reflect current architecture
- **README.md**: Update FAQ to remove ElevenLabs from provider list

### Technical Deep Dive Overhaul
- Replace "Output Style System" with "Startup Hook Protocol"
- Update from 4 core systems to 3 (removed output styles)
- Remove all ElevenLabs API code examples
- Add macOS Say provider implementation details
- Update voice references from 150+ to 50+ neural voices
- Fix all code snippets to match current implementation
- Update provider comparison tables
- Remove SSH audio conversion (only needed for API streaming)
- Update BMAD integration references

### Provider Documentation
- Accurate comparison between Piper TTS and macOS Say
- Remove outdated pricing and API key information
- Add correct feature matrices
- Update installation requirements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…fully

## Changes

### mcp-server/install-deps.js
- Detect PEP 668 'externally-managed-environment' errors
- Return 'skipped' status instead of failing when PEP 668 detected
- Provide clear guidance about virtual environment setup
- Prevent workflow failures on macOS systems

### .github/workflows/test-macos.yml
- Add explicit error handling for MCP installation step
- Always exit 0 from MCP test step (it's optional for unit tests)
- Add informative messages about PEP 668 expectations
- Clarify that MCP installation failures are non-critical

## Impact
- ✅ No more ❌ status on macOS workflows
- ✅ Users get helpful messages about virtual environments
- ✅ Tests continue to run successfully
- ✅ MCP still works when installed in venv (as documented)

Fixes macOS test workflow failures caused by Python environment protection.
…st reliability

- Add new 'agentvibes uninstall' command with interactive confirmation
- Support --yes, --global, and --with-piper flags for flexible removal
- Document uninstall process in README with examples and what gets removed
- Increase party-mode TTS test timeout from 10s to 15s for slower CI systems

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The lock file mechanism prevents overlapping audio playback during
learning mode. However, if the background cleanup process is killed
(e.g., when Claude Code session is interrupted), the lock file
remains indefinitely, causing all future TTS to be skipped with
"Skipping TTS (previous audio still playing)" error.

This fix adds automatic cleanup of locks older than 30 seconds,
which is well beyond any normal TTS playback duration. Uses
cross-platform stat command syntax (macOS -f %m, Linux -c %Y).
paulpreibisch pushed a commit that referenced this pull request Mar 17, 2026
… lock fix

- Add Receiver tab to TUI with live message log (date, time, ID, IP, status,
  project, voice, music, text columns)
- Show Tailscale IP and SSH port in receiver tab header and setup instructions
- Fix cross-user audio: use localhost TCP (port 34567) with PulseAudio cookie
  auth instead of Unix sockets (which reject different-uid callers)
- Add setup-receiver-user.sh: creates dedicated agentvibes-receiver user,
  copies voices/tracks, configures PipeWire TCP, shares pulse cookie
- Add add-server-key.sh: safely adds server SSH keys to receiver user
- Add test-receiver.sh: end-to-end diagnostic for receiver setup
- Fix stale lock files blocking TTS permanently (PR #84) in piper, soprano,
  and macos providers — auto-remove locks older than 30 seconds
- Fix SSH receiver temp dir permissions (use own /run/user, not desktop user's)
- Add ssh-remote provider support to play-tts.sh dispatcher
- Log ID field for correlating receiver log entries

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants