An unofficial animated Codex pet for macOS with local voice lines, speech bubbles, a small to-do list, and a peek-from-the-edge mode.
简体中文 · Asset notice · Voice source · Privacy
Important
This is a fan-made project. The MIT License covers the code and original documentation only. It does not cover the character name, character design, artwork or animation. The bundled synthesized voice clips are documented separately and remain subject to ACML 1.0. Read ASSET_NOTICE.md and VOICE_SOURCE.md before you redistribute the project.
- Requirements
- Installation
- Quick start
- Features
- How it works
- Configuration
- Custom voice files
- Privacy
- Limitations
- Testing
- Uninstall
- Project structure
- Media rights and license
- macOS with Codex Desktop pet support. The current package was verified on macOS 26.6.2.
- Python 3.10 or newer.
- Xcode Command Line Tools, including
swiftc. - A local Codex session directory at
~/.codex/sessions.
The runtime uses the Python standard library and built-in macOS commands. It does not require a Python package install.
Do not run the installer with sudo. The LaunchAgent and Accessibility grant
must belong to the signed-in macOS user.
git clone https://github.com/violetloveAI/violet-codex-pet.git
cd violet-codex-pet./scripts/install.shThe installer performs these actions:
- Copies the Codex pet to
~/.codex/pets/violet. - Copies the five bundled synthesized voice clips without replacing files you already customized.
- Compiles
VioletPetBridge.swiftas a local macOS app. - Installs the Python watcher under
~/.codex/violet-voice-companion. - Creates and starts the
io.github.codex-violet-voiceLaunchAgent.
If another violet pet exists and differs from this package, the installer
copies it to a timestamped backup under ~/.codex/pets before replacement.
The default clips were synthesized with AivisSpeech. Their source, credit, and license are recorded in VOICE_SOURCE.md.
To generate a separate sample set with the built-in macOS Kyoko voice, use:
./scripts/generate_demo_audio.sh /tmp/violet-kyoko-demo Kyoko 175This command does not change the active installation. Copy only the AIFF files you want into the matching installed event folders. Keeping several files in one event folder makes Violet choose one at random.
Open Settings → Pets, refresh the pet list, and select Violet. Use the Codex pet command if the pet window is not already visible.
When macOS asks, allow Violet Pet Bridge under System Settings → Privacy & Security → Accessibility. This permission is required for opening the matching task and for the edge-hide toggle.
If the permission was added while the helper was running, restart the service:
launchctl kickstart -k "gui/$(id -u)/io.github.codex-violet-voice"python3 "$HOME/.codex/violet-voice-companion/src/violet_voice.py" \
--config "$HOME/.codex/violet-voice-companion/config.json" \
doctorEvery value in checks must be true, including pet_bridge.
Use these pointer interactions on the visible pet:
| Interaction | Result |
|---|---|
| Single-click | Shows one greeting in a small Japanese and Chinese bubble |
| Double-click | Shows one random conversational line |
| Right-click | Opens the to-do, edge-hide, mute, and volume menu |
| Drag to left or right edge | Hides the native pet and shows a tilted peek pose |
| Move the pointer over the peek pose | Returns the native pet |
| Click the task badge | Opens the matching Codex task |
The to-do window stores items locally. You can add, complete, delete, and clear completed items.
- A Codex-compatible 8 × 9 animated pet atlas.
- Pet states for idle, directional movement, waving, waiting, work, review, completion, and failure flows.
- Five bundled AivisSpeech voice clips for task start, waiting, completion, interruption, and greeting. Chat uses the TTS fallback by default.
- Audio-file playback with macOS text-to-speech fallback.
- Small Japanese and Chinese speech bubbles.
- A persistent local to-do list with strikethrough completion.
- Left-edge and right-edge peek poses with pointer-based return.
- Right-click mute and 25%, 50%, 75%, or 100% playback volume.
- Root-task filtering so worker or subagent sessions do not speak by default.
- No network request or analytics code.
The complete animation sheet is available at assets/animation-sheet.png.
Codex Desktop
├── loads pet/pet.json and pet/spritesheet.webp
├── writes local task lifecycle records
│ └── Python watcher routes lifecycle events to local audio or TTS
└── displays the native pet window
└── Swift helper adds bubbles, to-dos, clicks, and edge peeking
The Python process follows new JSONL records under ~/.codex/sessions. It uses
the lifecycle event type and turn ID. It does not use prompt or response text
to select a line.
The Swift helper does not modify or inject code into Codex Desktop. It observes the native pet window and uses ordinary macOS windows for bubbles, to-dos, and peek poses.
Edit the installed configuration:
~/.codex/violet-voice-companion/config.json
Restart the LaunchAgent after a change:
launchctl kickstart -k "gui/$(id -u)/io.github.codex-violet-voice"| Setting | Default | Purpose |
|---|---|---|
sessions_dir |
~/.codex/sessions |
Codex session JSONL directory |
poll_interval_seconds |
1.0 |
Delay between file scans |
waiting_after_seconds |
35.0 |
Delay before one waiting line per task turn |
cooldown_seconds |
4.0 |
Duplicate suppression window per event |
include_subagents |
false |
Includes worker sessions when enabled |
voice.name |
Kyoko |
macOS voice for TTS fallback |
voice.rate |
175 |
TTS speech rate |
voice.volume |
0.75 |
afplay volume for audio files |
voice.use_tts_fallback |
true |
Uses TTS when no audio file exists |
interaction.enabled |
true |
Starts the native interaction helper |
interaction.bubble_duration_seconds |
2.8 |
Bubble display time |
interaction.show_lifecycle_bubbles |
false |
Shows bubbles for automatic task events |
interaction.reveal_on_completed |
false |
Returns a hidden pet when a task completes |
Each item under events supports enabled, audio_glob, phrases, and
Japanese and Chinese entries under lines.
Supported formats are AIFF, AIF, WAV, MP3, M4A, and CAF. The installer copies the five bundled WAV clips only when a file with the same name does not already exist. Put your own files under the installed event folders:
~/.codex/violet-voice-companion/audio/
├── started/
├── waiting/
├── completed/
├── failed/
├── greeting/
└── chat/
If a folder contains more than one supported file, Violet selects one at random. If the folder is empty, Violet uses a configured Japanese phrase with macOS text to speech.
Add only recordings that you created or have permission to use. Do not add anime dialogue or cloned performer voices.
The bundled clips are documented in VOICE_SOURCE.md. They are unofficial synthesized audio and are not recordings from the anime or its performers.
Violet runs locally. The project has no analytics or network client. The watcher still needs read access to Codex session files, which can contain complete prompts and responses.
Read PRIVACY.md for the exact data flow, local files, and macOS permission use.
- This project depends on Codex Desktop window names, session paths, and event names that are not a stable public integration API.
- A Codex Desktop update can require an adapter change.
- The edge-hide feature uses the Codex command interface and requires Accessibility access.
- Audio playback is serial. A long clip delays later voice events.
- The pet package uses the current 8 × 9 atlas contract.
- GitHub Pages is not applicable because this is a native macOS project.
Run the Python tests:
python3 -m unittest discover -s tests -vCheck the shell scripts:
/bin/sh -n scripts/install.sh
/bin/sh -n scripts/uninstall.sh
/bin/sh -n scripts/generate_demo_audio.shCompile-check the Swift helper:
swiftc -warnings-as-errors \
-framework AppKit \
-framework ApplicationServices \
-framework CoreGraphics \
src/VioletPetBridge.swift \
-o /tmp/violet-pet-bridge-checkStop the LaunchAgent but keep local configuration, audio, and the pet:
./scripts/uninstall.shRemove the service, helper app, local configuration, and audio:
./scripts/uninstall.sh --remove-dataRemove the installed Violet pet as well:
./scripts/uninstall.sh --remove-allUse --remove-pet if you want to remove only the installed pet package in
addition to stopping the service.
The uninstall script removes data only from directories that contain this project's install marker. Remove Violet Pet Bridge from the macOS Accessibility list manually if you no longer want to keep the permission.
violet-codex-pet/
├── pet/ # Codex pet manifest and animation atlas
├── src/
│ ├── violet_voice.py # Lifecycle watcher and local voice player
│ └── VioletPetBridge.swift # Native pointer and window interactions
├── scripts/ # Install, uninstall, and demo-audio scripts
├── tests/ # Python unit tests
├── assets/ # Runtime artwork and README previews
├── audio/ # Five bundled synthesized voice clips
├── config.example.json
├── ASSET_NOTICE.md
├── VOICE_SOURCE.md
├── PRIVACY.md
└── LICENSE
This is an unofficial fan project. It is not affiliated with OpenAI, Codex, Kyoto Animation, or the rights holders of Violet Evergarden.
The source code and original documentation are available under the MIT License. The character-related artwork and visual elements are not licensed under MIT. The bundled synthesized voice clips are subject to the source model's ACML 1.0 terms and are also outside MIT. See ASSET_NOTICE.md and VOICE_SOURCE.md.


