From fe80be6c0567583ef7af127ed13e283ec0310661 Mon Sep 17 00:00:00 2001 From: enne2 Date: Sat, 23 May 2026 20:06:01 +0200 Subject: [PATCH] Bundle pre-generated alert sounds --- README.md | 15 +++---- assets/block.wav | Bin 0 -> 45204 bytes assets/confirm.wav | Bin 0 -> 33122 bytes assets/refine.wav | Bin 0 -> 30828 bytes index.ts | 87 +++---------------------------------- package-lock.json | 4 +- package.json | 8 ++-- scripts/generate_sounds.py | 80 ++++++++++++++++++++++++++++++++++ 8 files changed, 98 insertions(+), 96 deletions(-) create mode 100644 assets/block.wav create mode 100644 assets/confirm.wav create mode 100644 assets/refine.wav create mode 100644 scripts/generate_sounds.py diff --git a/README.md b/README.md index 6d82371..655e031 100644 --- a/README.md +++ b/README.md @@ -66,17 +66,13 @@ Then load it from local `node_modules` or publish it to your npm registry later. ## Sound alerts -The extension generates three small WAV files programmatically on first use: +The package ships with three pre-generated WAV files and the extension only plays them at runtime: - `confirm.wav` — soft ascending alert for human confirmation - `block.wav` — lower, harsher alert for denied actions - `refine.wav` — distinct mid-tone alert for “blocked, but reformulate safely” cases -By default it writes them under: - -```text -~/.pi/agent/policy-gate-sounds/ -``` +By default it plays the bundled files from the package `assets/` directory, so it does **not** write audio files into your agent home at startup. It automatically uses the first available local player among: @@ -147,7 +143,7 @@ Example: "soundBlockEnabled": true, "soundRefineEnabled": true, "soundPlayer": "auto", - "soundDirectory": "~/.pi/agent/policy-gate-sounds", + "soundDirectory": "/absolute/path/to/custom/policy-gate-sounds", "sensitivePathGlobs": ["~/.ssh/**", "**/.env"], "overrides": [ { @@ -168,7 +164,7 @@ Example: - `soundPlayer: "auto"` picks the first available local player. - Set `soundEnabled: false` to disable all alert sounds. - `soundConfirmEnabled`, `soundBlockEnabled`, and `soundRefineEnabled` let you mute just one class of event. -- `soundDirectory` can be absolute, `~`-based, or relative to the project cwd. +- `soundDirectory` is optional: by default the extension uses the package's bundled `assets/` directory. If you set it, it should point to an existing directory containing `confirm.wav`, `block.wav`, and `refine.wav`. - `workspaceRoots` can be absolute paths, `~` paths, or paths relative to the current project cwd. @@ -212,10 +208,11 @@ Inside pi: ## Development -Install deps and verify the package tarball: +Install deps, regenerate the packaged WAV assets if needed, and verify the tarball: ```bash npm install +npm run generate:sounds npm run pack:check ``` diff --git a/assets/block.wav b/assets/block.wav new file mode 100644 index 0000000000000000000000000000000000000000..c97c002b5027200ff49ecf4d8f4034a1419d71fa GIT binary patch literal 45204 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 literal 0 HcmV?d00001 diff --git a/assets/confirm.wav b/assets/confirm.wav new file mode 100644 index 0000000000000000000000000000000000000000..e6e2f00474d304faa0a074c73986620ec080213c GIT binary patch literal 33122 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 literal 0 HcmV?d00001 diff --git a/assets/refine.wav b/assets/refine.wav new file mode 100644 index 0000000000000000000000000000000000000000..34f842974f112452dc0a8ea86fb994e4663784f8 GIT binary patch literal 30828 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 sum + Math.round((segment.durationMs / 1000) * sampleRate), 0); - const pcm = Buffer.alloc(sampleCount * 2); - let sampleOffset = 0; - - for (const segment of segments) { - const segmentSamples = Math.round((segment.durationMs / 1000) * sampleRate); - for (let i = 0; i < segmentSamples; i += 1) { - const globalIndex = sampleOffset + i; - let sample = 0; - if (segment.freqs.length > 0) { - const t = i / sampleRate; - const attack = Math.min(1, i / Math.max(1, segmentSamples * 0.1)); - const release = Math.min(1, (segmentSamples - i) / Math.max(1, segmentSamples * 0.12)); - const envelope = Math.min(attack, release); - for (const freq of segment.freqs) { - sample += Math.sin(2 * Math.PI * freq * t); - } - sample = (sample / segment.freqs.length) * amplitude * envelope; - } - pcm.writeInt16LE(Math.max(-1, Math.min(1, sample)) * 32767, globalIndex * 2); - } - sampleOffset += segmentSamples; - } - - const header = Buffer.alloc(44); - header.write("RIFF", 0); - header.writeUInt32LE(36 + pcm.length, 4); - header.write("WAVE", 8); - header.write("fmt ", 12); - header.writeUInt32LE(16, 16); - header.writeUInt16LE(1, 20); - header.writeUInt16LE(1, 22); - header.writeUInt32LE(sampleRate, 24); - header.writeUInt32LE(sampleRate * 2, 28); - header.writeUInt16LE(2, 32); - header.writeUInt16LE(16, 34); - header.write("data", 36); - header.writeUInt32LE(pcm.length, 40); - return Buffer.concat([header, pcm]); -} - -function ensureSoundAssets(config: ResolvedConfig) { - if (!config.soundEnabled) return; - mkdirSync(config.soundDirectory, { recursive: true }); - for (const kind of ["confirm", "block", "refine"] as const) { - const target = soundPath(kind, config); - writeFileSync(target, createAlertWav(kind)); - } -} - function playAlert(kind: AlertSoundKind, config: ResolvedConfig) { if (!config.soundEnabled) return; if (kind === "confirm" && !config.soundConfirmEnabled) return; @@ -498,8 +422,8 @@ function playAlert(kind: AlertSoundKind, config: ResolvedConfig) { const player = resolveAudioPlayer(config.soundPlayer); if (!player) return; try { - ensureSoundAssets(config); const file = soundPath(kind, config); + if (!existsSync(file)) return; const args = player === "ffplay" ? ["-nodisp", "-autoexit", "-loglevel", "quiet", file] @@ -944,7 +868,6 @@ export default function policyGate(pi: ExtensionAPI) { pi.on("session_start", async (_event, ctx) => { const extraConfig = pi.getFlag("policy-gate-config") as string | undefined; activeConfig = loadConfig(ctx.cwd, extraConfig ? resolveConfigPath(extraConfig, ctx.cwd) : undefined); - ensureSoundAssets(activeConfig); if (ctx.hasUI) { ctx.ui.setStatus("policy-gate", ctx.ui.theme.fg("accent", "policy-gate active")); } diff --git a/package-lock.json b/package-lock.json index 4e1c2e5..b9233ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@enne2/pi-policy-gate", - "version": "0.4.0", + "version": "0.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@enne2/pi-policy-gate", - "version": "0.4.0", + "version": "0.5.0", "license": "MIT", "dependencies": { "minimatch": "^10.1.1" diff --git a/package.json b/package.json index 56461bb..e9da0ca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@enne2/pi-policy-gate", - "version": "0.4.0", + "version": "0.5.0", "description": "Policy gate extension for pi that classifies risky tool calls into allow, confirm, deny, or require-refinement.", "type": "module", "keywords": [ @@ -13,7 +13,8 @@ "files": [ "index.ts", "README.md", - "policy-gate.example.json" + "policy-gate.example.json", + "assets/*.wav" ], "pi": { "extensions": [ @@ -22,7 +23,8 @@ }, "scripts": { "check": "npm pack --dry-run >/dev/null", - "pack:check": "npm pack --dry-run" + "pack:check": "npm pack --dry-run", + "generate:sounds": "python3 scripts/generate_sounds.py" }, "dependencies": { "minimatch": "^10.1.1" diff --git a/scripts/generate_sounds.py b/scripts/generate_sounds.py new file mode 100644 index 0000000..463ced7 --- /dev/null +++ b/scripts/generate_sounds.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import math +import wave +from pathlib import Path + +SAMPLE_RATE = 44100 + +PROFILES = { + "confirm": { + "amplitude": 0.28, + "segments": [ + (80, [660, 990]), + (35, []), + (95, [880, 1320]), + (35, []), + (130, [1174, 1568]), + ], + }, + "block": { + "amplitude": 0.42, + "segments": [ + (120, [392, 587]), + (36, []), + (130, [294, 440]), + (36, []), + (190, [196, 294]), + ], + }, + "refine": { + "amplitude": 0.30, + "segments": [ + (95, [587, 784]), + (32, []), + (95, [659, 880]), + (32, []), + (95, [587, 784]), + ], + }, +} + + +def synth_segment(duration_ms: int, freqs: list[int], amplitude: float) -> list[int]: + samples = round((duration_ms / 1000) * SAMPLE_RATE) + data: list[int] = [] + for i in range(samples): + sample = 0.0 + if freqs: + t = i / SAMPLE_RATE + attack = min(1.0, i / max(1, int(samples * 0.1))) + release = min(1.0, (samples - i) / max(1, int(samples * 0.12))) + envelope = min(attack, release) + sample = sum(math.sin(2 * math.pi * freq * t) for freq in freqs) / len(freqs) + sample *= amplitude * envelope + data.append(int(max(-1.0, min(1.0, sample)) * 32767)) + return data + + +def write_wave(path: Path, profile: dict[str, object]) -> None: + amplitude = float(profile["amplitude"]) + segments = profile["segments"] + pcm: list[int] = [] + for duration_ms, freqs in segments: # type: ignore[misc] + pcm.extend(synth_segment(duration_ms, list(freqs), amplitude)) + + path.parent.mkdir(parents=True, exist_ok=True) + with wave.open(str(path), "wb") as wav: + wav.setnchannels(1) + wav.setsampwidth(2) + wav.setframerate(SAMPLE_RATE) + wav.writeframes(b"".join(sample.to_bytes(2, "little", signed=True) for sample in pcm)) + + +if __name__ == "__main__": + root = Path(__file__).resolve().parent.parent + assets = root / "assets" + for name, profile in PROFILES.items(): + write_wave(assets / f"{name}.wav", profile) + print(f"wrote {assets / f'{name}.wav'}")