SpeakEasy
Voice for Codex

say("Speak to the task you’re already in. Hear its real answer come back.",
{ mode: 'speak', task: 'locked' })
Hear the TTS side:
speakeasy "Welcome to SpeakEasy! This unified text-to-speech service makes it easy to add voice to your applications" --provider openai --voice nova --rate 180
npm install @arach/speakeasy
Two-way voice · available now

Speak to the task you’re already in.Hear its real answer come back.

SpeakEasy now joins local speech recognition and controllable narration around one exact Codex Desktop conversation.

Speak
One explicit utterance
Transcribe
Locally on your Mac
Route
To the exact Codex task
Answer
Inside the real thread
Hear
Through the native player
Available now

Listen · ASR

Press once to record and again to send. Vox transcribes locally before SpeakEasy routes the final text to the task you chose.

Available now

Speak · TTS

The task’s response returns through the menu-bar player with autoplay, queueing, speed, volume, and a live transcript HUD.

Exact-task mapping

Nine persistent lanes. No focus guessing.

⌘⌥1…9
1
Website narrative
Exact Codex Desktop task
Locked
2
Native player release
Exact Codex Desktop task
Ready
3
Claude adapter
Exact Codex Desktop task
Next
  • Task ID is routing authority
  • Every activation revalidates the lock
See the Codex mapping
Dual-mode release · 0.2.19

Download the completeCodex voice companion.

No repository, Bun, Xcode, or server setup. Give Codex one bounded installation task; it verifies and opens the notarized app, then tells you exactly which human permissions remain. The paired browser/iPad Deck is included.

Apple siliconmacOS 14 or newerCodex Desktop
Codex-assisted setup
Automation with explicit trust checks
  1. 1
    Give Codex the prompt

    It downloads and inspects the pinned release installer—never a floating latest build.

  2. 2
    Let it verify everything

    Checksum, Gatekeeper, Developer ID, version, and safe app replacement are checked in order.

  3. 3
    Approve the human steps

    You grant microphone and local-network access; Settings verifies Codex and the live bridge.

Release notes SHA-256 Signed + notarized

Start Speaking in Seconds

No complex setup, no boilerplate. Choose your style and start building.

import { say } from '@arach/speakeasy';

// Quick start - one line!
await say('Hello world!');

// With provider
await say('Hello from OpenAI!', 'openai');
await say('Hello from ElevenLabs!', 'elevenlabs');
import { speak, SpeakEasy } from '@arach/speakeasy';

// Full featured with options
await speak('Priority message', {
  provider: 'openai',
  volume: 0.8,
  priority: 'high'
});

// Custom instance
const speech = new SpeakEasy({
  provider: 'elevenlabs',
  volume: 0.6,
  rate: 200
});

await speech.speak('Custom configuration');
# Install globally
npm install -g @arach/speakeasy

# Quick setup - save your API key
speakeasy --set-key elevenlabs YOUR_API_KEY

# Set as default provider
speakeasy --set-default elevenlabs

# Start speaking!
speakeasy "Hello world"

# Or use system voice (no API key needed)
speakeasy "Hello world" --provider system
// ~/.config/speakeasy/settings.json
{
  "providers": {
    "openai": {
      "voice": "nova",
      "apiKey": "sk-..."
    },
    "elevenlabs": {
      "voiceId": "EXAVITQu4vr4xnSDxMaL",
      "apiKey": "sk-..."
    }
  },
  "defaults": {
    "provider": "openai",
    "volume": 0.7,
    "rate": 180
  }
}

Get Started in 3 Steps

npm install -g @arach/speakeasy
+ @arach/speakeasy@0.2.19 Added 1 package in 2.3s
speakeasy --set-key elevenlabs sk_abc123...
✅ ElevenLabs API key saved to config 🎉 You can now use: speakeasy "Hello world" --provider elevenlabs
speakeasy "Hello world!" --provider elevenlabs
🎙️ Speaking with elevenlabs...
No API key? Use --provider system for built-in macOS voices

Have Claude speak to you

Never miss important notifications. Transform Claude Code's silent alerts into intelligent spoken updates.

Tool Permission Request

Trigger: "Claude needs your permission"
What Claude shows:
Claude needs your permission
Audio Result
Loading waveform...
0:00 / 0:00
Visual Context
speakeasy --setup-hooks
Configure Claude Code notifications
⏺ Update(.claude/hooks/notif.ts)
⎿ Updated .claude/hooks/notif.ts with 10 additions
// ~/.claude/hooks/notification.ts
import { SpeakEasy } from '@arach/speakeasy';

const speakEasy = new SpeakEasy({
  provider: 'groq',
  cache: { enabled: true, ttl: '7d' },
  fallbackOrder: ['groq', 'openai', 'system']
});

// Read notification from Claude Code
const notificationType = process.argv[2];
const payload = JSON.parse(await readStdin());

// Extract project context
const projectMatch = payload.transcript_path?.match(/\/([^\/]+)$/);
const projectName = projectMatch?.[1] || 'your project';

// Transform into natural speech
let spokenMessage = payload.message;
if (projectName !== 'your project') {
  spokenMessage = `In ${projectName}, ${payload.message}`;
}

// Speak the notification
await speakEasy.speak(spokenMessage);

// Also copy to clipboard and log
await copyToClipboard(JSON.stringify(payload, null, 2));
logger.info('Notification processed', { type: notificationType, message: spokenMessage });
@arach/hooked

Ready-to-deploy handlers

ClaudeClaude Hooks

Official documentation