-
Notifications
You must be signed in to change notification settings - Fork 1
Fix hooks: PowerShell quoting, stopTeammate helper, output docs #177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -103,13 +103,15 @@ export function playSound(soundFile: string): void { | |||||||||||
| // For named system sounds (no extension) fall back to rundll32. | ||||||||||||
| const isWav = soundFile.toLowerCase().endsWith('.wav'); | ||||||||||||
| if (isWav) { | ||||||||||||
| // Use double-quoted string which handles spaces and most special chars | ||||||||||||
| const escaped = soundFile.replace(/"/g, '\\"'); | ||||||||||||
| spawnSync( | ||||||||||||
| 'powershell', | ||||||||||||
| [ | ||||||||||||
| '-NoProfile', | ||||||||||||
| '-NonInteractive', | ||||||||||||
| '-Command', | ||||||||||||
| `$p='${soundFile.replace(/'/g, "''")}'; (New-Object System.Media.SoundPlayer $p).PlaySync()`, | ||||||||||||
| `$p="${escaped}"; (New-Object System.Media.SoundPlayer $p).PlaySync()`, | ||||||||||||
| ], | ||||||||||||
| { stdio: 'ignore' }, | ||||||||||||
|
Comment on lines
+106
to
116
|
||||||||||||
| ); | ||||||||||||
|
|
@@ -135,3 +137,17 @@ export function playSound(soundFile: string): void { | |||||||||||
| // Never crash on sound failure | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| /** | ||||||||||||
| * Send a JSON stop signal to terminate a teammate. | ||||||||||||
| * Outputs the stop payload to stdout and exits cleanly. | ||||||||||||
| * Use this when a teammate should be permanently stopped (not just blocked). | ||||||||||||
| * | ||||||||||||
| * For blocking (retry behavior), use: process.stderr.write(msg); process.exit(2); | ||||||||||||
| * For stopping (permanent), use: stopTeammate(reason); | ||||||||||||
| */ | ||||||||||||
| export function stopTeammate(reason: string): never { | ||||||||||||
| const payload = JSON.stringify({ continue: false, stopReason: reason }); | ||||||||||||
| process.stdout.write(`${payload}\n`); | ||||||||||||
| process.exit(0); | ||||||||||||
|
Comment on lines
+151
to
+152
|
||||||||||||
| process.stdout.write(`${payload}\n`); | |
| process.exit(0); | |
| process.stdout.write(`${payload}\n`, () => { | |
| process.exit(0); | |
| }); |
Copilot
AI
Mar 25, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stopTeammate() introduces new hook-control behavior but isn’t covered by the existing hooks/shared.ts unit tests. Adding a small test that spies on process.stdout.write and process.exit would prevent regressions in the JSON payload format and exit semantics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PowerShell
-Commandstring now uses a double-quoted literal ($p="..."). In PowerShell, double-quoted strings perform variable/subexpression expansion (e.g.$,$(), and backtick escapes), so valid Windows path characters like$or`can be misinterpreted and break playback (and it also makes the “handles special chars” comment inaccurate). Consider avoiding interpolation entirely by passing the path as a separate argument and reading it via$args[0](or revert to a single-quoted literal with proper escaping).