Black Mesa-style voice notifications for Codex on macOS. The project builds short announcements from the Half-Life 1 VOX catalog and connects them to Codex lifecycle hooks. An optional chill mode replaces every enabled phrase with the same short GTA Vice City pop-up notification sound.
Every spoken announcement begins with the original Half-Life vox/buzwarn.wav Black Mesa signal.
See the complete installation and usage guide for configuration, testing, troubleshooting, updating, and uninstalling.
| Setting | Phrase | When it plays |
|---|---|---|
task_started |
“Processing.” | A task or queued prompt starts |
permission_required |
“Attention. Security clearance required. Please acknowledge.” | Codex requests permission |
response_required |
“Attention. Communication required. Please acknowledge.” | Codex stops with a direct question or request |
queue_item_complete |
“Secondary objective secured.” | One item completes while another task remains active |
task_complete |
“Final objective reached.” | One task finishes and no queued prompt follows |
queue_complete |
“Final objective secured. All systems nominal.” | A sequence of two or more queued tasks finishes |
blocked |
“Warning. Objective failed. User acknowledge.” | Codex reports that it cannot continue |
Internal SubagentStop events are intentionally silent and are not installed as hooks.
Edit config.json. Changes apply on the next hook event; rebuilding and reinstalling are not required.
{
"mode": "normal",
"announcements": {
"task_started": false,
"permission_required": true,
"response_required": true,
"queue_item_complete": true,
"task_complete": true,
"queue_complete": true,
"blocked": true
},
"alokium_enabled": true,
"queue_idle_seconds": 4
}Set an announcement to false to mute only that announcement. Missing announcement keys default to true. Invalid JSON fails silent and is recorded in ~/.codex/codex-intercom/intercom.log so it cannot interrupt Codex.
The shipped configuration keeps task_started muted to avoid a sound on every submitted prompt. Set it to true if you want the “Processing” announcement.
Set mode to normal for the current Half-Life phrases or chill to use the shared GTA Vice City pop-up notification for every enabled announcement. Mode changes apply on the next hook and do not require a restart.
Use the safe command instead of editing JSON:
/usr/bin/python3 scripts/set_config.py mode normal
/usr/bin/python3 scripts/set_config.py mode chill
/usr/bin/python3 scripts/set_config.py alokium on
/usr/bin/python3 scripts/set_config.py alokium offThe repository can also be controlled through four Apple Shortcuts named Intercom - normal, Intercom - chill, Intercom - LEDs on, and Intercom - LEDs off. Matching application launchers can be placed on the Desktop for double-click access. Audio mode and LED forwarding are independent.
When the separate codex_alokium_intercom project is installed beside this checkout, the Black Mesa runtime sends it only finalized semantic announcements. Raw Stop and SubagentStop events are never forwarded. This keeps Alokium credentials, device filtering, and RGB restoration outside this repository while guaranteeing the sound and LED react to the same decision.
Expected sibling layout:
projects/
├── codex-intercom/
├── codex_alokium_intercom/
└── alokium_notifications/
Set CODEX_ALOKIUM_ADAPTER to an explicit intercom.py path when the projects are not siblings. Set alokium_enabled to false in config.json to disable LED forwarding without disabling audio.
Requirements:
- macOS with
/usr/bin/afplay /usr/bin/python33.9 or later
Clone the repository and merge the hooks into ~/.codex/hooks.json:
git clone https://github.com/viniciusczanini/codex-hl1-intercom-system.git
cd codex-hl1-intercom-system
/usr/bin/python3 scripts/install.pyThe seven final Half-Life WAV announcements and the shared chill WAV are included in assets/, so normal installation does not require ffmpeg, audio downloads, or a separate build step.
The installer preserves unrelated hooks and does not modify ~/.codex/config.toml or its existing notify command. It is idempotent, so rerunning it does not create duplicate handlers.
After installation, open /hooks in Codex and trust the four entries labelled Black Mesa intercom. Codex hashes hook definitions; changed definitions must be reviewed again.
If the ChatGPT desktop app was already running when the hooks were installed, quit and reopen it once. Its embedded codex app-server loads hook definitions when the process starts. Announcement booleans in config.json are read on every event and do not require another restart.
Codex hooks do not expose a desktop-wide queue length. Stop ends one turn, not necessarily every task in the app. Intercom therefore aggregates activity across all observed session_id values and holds global completion for four seconds:
- If another prompt starts in that window, the previous task is announced as a queue item.
- If another session is still active, the completed task gets
queue_item_complete; the final queue announcement waits for the last active session. - Before deciding, Intercom reads the bounded tail of Codex's own transcript and removes sessions whose persisted turn reached
task_completeor whose transcript was moved to Codex'sarchived_sessionsdirectory. - There is no task timeout: a transcript ending in
task_startedremains active regardless of how long the task runs. - If nothing follows, a one-item batch gets
task_complete. - A sequential or concurrent batch announces each non-final item and gets exactly one
queue_completeannouncement at the end. - Questions and blocked states close the batch immediately and never produce a false queue-complete sound.
Adjust queue_idle_seconds in config.json if queued prompts on your machine take longer to start.
cd codex-hl1-intercom-system
PYTHONPATH=src /usr/bin/python3 -m unittest discover -s tests -vThe committed sounds/manifest.json records each source fragment and phrase sequence. Maintainers can rebuild the bundled assets with /usr/bin/python3 scripts/install.py --rebuild-assets; that optional path requires ffmpeg, ffprobe, and access to HL1SFX.
Play all generated phrases:
for wav in assets/*.wav; do
echo "PLAYING $wav"
/usr/bin/afplay "$wav"
done
/usr/bin/afplay assets/chill/notification.wavcd codex-hl1-intercom-system
/usr/bin/python3 scripts/uninstall.pyUninstall removes only handlers owned by this project. It preserves unrelated Codex hooks, config.toml, downloaded source clips, and generated phrases.
Hook execution is recorded as metadata-only JSON Lines in /tmp/codex-intercom-hooks.log. Follow it live with:
tail -f /tmp/codex-intercom-hooks.logThe trace contains event, session, classification, scheduling, transcript lifecycle classification, playback, and semantic Alokium dispatch status. session_reconciled records show whether another session was active, complete, missing, or unreadable. It does not store transcript paths, prompts, or assistant-message content, and macOS may remove it after a reboot.
Final phrase assets are included for easy installation. Original fragments and normalized intermediate files remain local and are excluded from Git.
Original sound fragments, including vox/buzwarn.wav, were sourced through HL1SFX. Half-Life and its original audio assets were created by and belong to Valve Corporation. This unofficial integration and its phrase arrangements were created by viniciusczanini. The project is not affiliated with or endorsed by Valve Corporation or HL1SFX.
The chill notification is an audio effect from Grand Theft Auto: Vice City. Grand Theft Auto, Vice City, and their original audio assets were created by Rockstar Games and are owned by Rockstar Games/Take-Two Interactive. This project is not affiliated with, endorsed by, or sponsored by Rockstar Games or Take-Two Interactive.