Skip to content

Instantly share code, notes, and snippets.

@ericchansen
Last active April 15, 2026 17:34
Show Gist options
  • Select an option

  • Save ericchansen/51326eddfd8e123769cf7eccca993f64 to your computer and use it in GitHub Desktop.

Select an option

Save ericchansen/51326eddfd8e123769cf7eccca993f64 to your computer and use it in GitHub Desktop.
One-command setup: Warcraft Peon sounds for Windows Terminal (Stable, Preview, Canary) with volume control
<#
.SYNOPSIS
Replace the Windows Terminal bell with Warcraft Peon sounds.
.DESCRIPTION
Downloads Peon WAV files and configures Windows Terminal's native bellSound
setting to randomly play one on each bell event. That's it - no hooks,
no runtimes, no extra dependencies. Just WAVs + a settings.json change.
Supports all Windows Terminal variants: Stable, Preview, and Canary.
Sounds are volume-reduced by default (13%) so they're a subtle nudge,
not a jump-scare. Adjust with -Volume or $env:PEON_BELL_VOLUME.
.PARAMETER Volume
Bell volume as a percentage of original (1-100). Default: 13.
For the irm | iex one-liner, set $env:PEON_BELL_VOLUME instead.
.EXAMPLE
irm https://gist.githubusercontent.com/ericchansen/51326eddfd8e123769cf7eccca993f64/raw/setup-peon-copilot.ps1 | iex
.EXAMPLE
$env:PEON_BELL_VOLUME = 25; irm https://gist.githubusercontent.com/ericchansen/51326eddfd8e123769cf7eccca993f64/raw/setup-peon-copilot.ps1 | iex
.EXAMPLE
.\setup-peon-copilot.ps1 -Volume 30
#>
param(
[ValidateRange(1,100)]
[int]$Volume = 0
)
$ErrorActionPreference = "Stop"
# ── Resolve volume: param > env var > marker file > default ──────────────
$SoundsDir = Join-Path $env:USERPROFILE ".terminal-sounds\peon"
$BellDir = Join-Path $env:USERPROFILE ".terminal-sounds\peon-bell"
$MarkerFile = Join-Path $env:USERPROFILE ".terminal-sounds\.bell-volume"
if ($Volume -eq 0) {
if ($env:PEON_BELL_VOLUME) {
$Volume = [int]$env:PEON_BELL_VOLUME
} elseif (Test-Path $MarkerFile) {
$Volume = [int](Get-Content $MarkerFile -Raw).Trim()
} else {
$Volume = 13
}
}
$Volume = [Math]::Clamp($Volume, 1, 100)
$Factor = $Volume / 100.0
Write-Host ""
Write-Host "=== Peon Bell for Windows Terminal ===" -ForegroundColor Yellow
Write-Host " Volume: $Volume%" -ForegroundColor DarkYellow
Write-Host ""
# ── Paths ────────────────────────────────────────────────────────────────
$PackBase = "https://raw.githubusercontent.com/PeonPing/og-packs/v1.0.0/peon"
# All known Windows Terminal settings.json locations
$WtCandidates = @(
@{ Name = "Stable"; Path = Join-Path $env:LOCALAPPDATA "Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json" }
@{ Name = "Preview"; Path = Join-Path $env:LOCALAPPDATA "Packages\Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe\LocalState\settings.json" }
@{ Name = "Canary"; Path = Join-Path $env:LOCALAPPDATA "Packages\Microsoft.WindowsTerminalCanary_8wekyb3d8bbwe\LocalState\settings.json" }
@{ Name = "Unpackaged"; Path = Join-Path $env:LOCALAPPDATA "Microsoft\Windows Terminal\settings.json" }
)
# ── Step 1: Download Peon WAV files ──────────────────────────────────────
Write-Host "[1/3] Downloading Peon sounds..." -ForegroundColor Cyan
New-Item -ItemType Directory -Path $SoundsDir -Force | Out-Null
# Fetch the manifest to get the file list
$manifest = (Invoke-WebRequest "$PackBase/openpeon.json" -UseBasicParsing).Content | ConvertFrom-Json
# Collect unique sound files from all categories
$soundFiles = @{}
foreach ($cat in $manifest.categories.PSObject.Properties) {
foreach ($sound in $cat.Value.sounds) {
$file = $sound.file -replace '^sounds/', ''
if (-not $soundFiles.ContainsKey($file)) {
$soundFiles[$file] = $sound.label
}
}
}
$downloaded = 0
$skipped = 0
foreach ($file in $soundFiles.Keys | Sort-Object) {
$outPath = Join-Path $SoundsDir $file
if (Test-Path $outPath) {
$skipped++
} else {
Invoke-WebRequest "$PackBase/sounds/$file" -OutFile $outPath -UseBasicParsing
$downloaded++
}
}
Write-Host " $($soundFiles.Count) sounds ($downloaded downloaded, $skipped cached)" -ForegroundColor Green
# ── Step 2: Create volume-reduced copies ─────────────────────────────────
Write-Host "[2/3] Adjusting volume to $Volume%..." -ForegroundColor Cyan
New-Item -ItemType Directory -Path $BellDir -Force | Out-Null
# Curate: exclude angry/death/warcry (those sound like errors, not "done")
$sourceFiles = Get-ChildItem $SoundsDir -Filter "*.wav" | Where-Object {
$_.Name -notmatch "(Angry|Death|Warcry)"
}
if ($sourceFiles.Count -eq 0) {
$sourceFiles = Get-ChildItem $SoundsDir -Filter "*.wav"
}
$useFfmpeg = $null -ne (Get-Command ffmpeg -ErrorAction SilentlyContinue)
if ($Volume -eq 100) {
# No reduction needed - just copy
foreach ($src in $sourceFiles) {
Copy-Item $src.FullName (Join-Path $BellDir $src.Name) -Force
}
$method = "copy (100%)"
} elseif ($useFfmpeg) {
foreach ($src in $sourceFiles) {
$dst = Join-Path $BellDir $src.Name
ffmpeg -y -loglevel error -i $src.FullName -filter:a "volume=$Factor" $dst 2>&1 | Out-Null
}
$method = "ffmpeg"
} else {
# Pure PowerShell: scale 16-bit PCM samples directly
foreach ($src in $sourceFiles) {
$dst = Join-Path $BellDir $src.Name
$bytes = [System.IO.File]::ReadAllBytes($src.FullName)
# Find the "data" chunk - scan for ASCII "data" after the fmt chunk
$dataOffset = -1
for ($i = 12; $i -lt ($bytes.Length - 8); $i++) {
if ($bytes[$i] -eq 0x64 -and $bytes[$i+1] -eq 0x61 -and
$bytes[$i+2] -eq 0x74 -and $bytes[$i+3] -eq 0x61) {
$dataOffset = $i + 8 # skip "data" + 4-byte size
break
}
}
if ($dataOffset -lt 0) {
# Can't parse - copy as-is
Copy-Item $src.FullName $dst -Force
continue
}
# Scale each 16-bit sample
for ($i = $dataOffset; $i -lt ($bytes.Length - 1); $i += 2) {
$sample = [BitConverter]::ToInt16($bytes, $i)
$scaled = [Math]::Round($sample * $Factor)
$scaled = [Math]::Clamp($scaled, -32768, 32767)
$le = [BitConverter]::GetBytes([Int16]$scaled)
$bytes[$i] = $le[0]
$bytes[$i+1] = $le[1]
}
[System.IO.File]::WriteAllBytes($dst, $bytes)
}
$method = "PowerShell PCM"
}
# Save volume marker for future re-runs
New-Item -ItemType Directory -Path (Split-Path $MarkerFile) -Force | Out-Null
Set-Content $MarkerFile "$Volume" -NoNewline
$bellSounds = Get-ChildItem $BellDir -Filter "*.wav" | ForEach-Object { $_.FullName }
Write-Host " $($bellSounds.Count) bell sounds at $Volume% via $method" -ForegroundColor Green
# ── Step 3: Configure Windows Terminal bellSound ─────────────────────────
Write-Host "[3/3] Configuring Windows Terminal..." -ForegroundColor Cyan
# Find all installed WT variants
$wtFound = $WtCandidates | Where-Object { Test-Path $_.Path }
if ($wtFound.Count -eq 0) {
Write-Host " No Windows Terminal settings.json found - skipping" -ForegroundColor Yellow
Write-Host " Checked:" -ForegroundColor DarkGray
foreach ($c in $WtCandidates) { Write-Host " $($c.Name): $($c.Path)" -ForegroundColor DarkGray }
Write-Host ""
Write-Host "You can manually add this to your terminal's profiles.defaults:" -ForegroundColor Yellow
Write-Host ' "bellStyle": "audible",' -ForegroundColor White
Write-Host ' "bellSound": [<paths to WAV files>]' -ForegroundColor White
exit 0
}
# Apply bellSound to every installed WT variant
foreach ($wt in $wtFound) {
$wtRaw = Get-Content $wt.Path -Raw
$wtClean = $wtRaw -replace '(?m)^\s*//.*$', '' -replace ',(\s*[}\]])', '$1'
$wtObj = $wtClean | ConvertFrom-Json
# Ensure profiles.defaults exists
if (-not $wtObj.profiles) {
$wtObj | Add-Member -NotePropertyName "profiles" -NotePropertyValue ([PSCustomObject]@{
defaults = [PSCustomObject]@{}
list = @()
})
}
if (-not $wtObj.profiles.defaults) {
$wtObj.profiles | Add-Member -NotePropertyName "defaults" -NotePropertyValue ([PSCustomObject]@{})
}
$defaults = $wtObj.profiles.defaults
if ($defaults.PSObject.Properties["bellStyle"]) { $defaults.bellStyle = "audible" }
else { $defaults | Add-Member -NotePropertyName "bellStyle" -NotePropertyValue "audible" }
if ($defaults.PSObject.Properties["bellSound"]) { $defaults.bellSound = @($bellSounds) }
else { $defaults | Add-Member -NotePropertyName "bellSound" -NotePropertyValue @($bellSounds) }
$wtObj | ConvertTo-Json -Depth 20 | Set-Content $wt.Path -Encoding utf8NoBOM
Write-Host " $($wt.Name): bellSound set ($($bellSounds.Count) sounds)" -ForegroundColor Green
}
Write-Host ""
Write-Host "Done! Your Peon is ready at $Volume% volume." -ForegroundColor Green
Write-Host ""
Write-Host "How it works:" -ForegroundColor DarkCyan
Write-Host " Windows Terminal plays a random Peon WAV every time the bell fires." -ForegroundColor DarkCyan
Write-Host " Any app that sends a bell character (`a) will trigger a random sound." -ForegroundColor DarkCyan
Write-Host " No hooks, no runtimes, no extra dependencies - just a settings.json change." -ForegroundColor DarkCyan
Write-Host ""
Write-Host "Adjust volume:" -ForegroundColor DarkCyan
Write-Host " Re-run with: `$env:PEON_BELL_VOLUME = 25; irm <url> | iex" -ForegroundColor DarkCyan
Write-Host " Or directly: .\setup-peon-copilot.ps1 -Volume 25" -ForegroundColor DarkCyan
Write-Host ""
Write-Host "Sounds: $SoundsDir (originals)" -ForegroundColor DarkGray
Write-Host "Bell: $BellDir ($Volume%)" -ForegroundColor DarkGray
Write-Host ""
@ericchansen
Copy link
Copy Markdown
Author

I don't even think you have to restart Windows Terminal. Just works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment