Community code plugin. Review compatibility and verification before install.
Latest release: v0.1.2Download zip
Capabilities
Compatibility
Security Scan
OpenClaw
Suspicious
high confidencePurpose & Capability
Name, README, code, and openclaw.plugin.json consistently describe a macOS-only plugin that wraps the voicecli CLI for transcription and TTS — this matches the requested capability. However the registry metadata reported earlier lists 'Required binaries: none' while the package/README and openclaw.plugin.json clearly require the voicecli CLI and macOS; the registry metadata is inconsistent with the code and docs.
Instruction Scope
Runtime behavior uses child_process.exec to call voicecli (transcribe, speak, voices). Inputs from callers (audioPath and text) are interpolated into shell commands; escapeShellArg only escapes double quotes and does not neutralize $(), backticks, or other expansions. Passing untrusted paths or text through this code can allow shell injection. The plugin also writes temporary audio files under a tempDir and modifies incoming message objects (attaching transcription/text) — those behaviors are expected for this plugin but worth noting.
Install Mechanism
No external download/install spec is present; the package is a normal npm package with source and compiled dist files. It expects the user to install voicecli (Homebrew) per README/openclaw.plugin.json. There are no fetched archives or unusual install URLs.
Credentials
The skill does not request environment variables or credentials. It requires only the voicecli CLI and macOS platform, which are proportional to its stated purpose.
Persistence & Privilege
The skill is not always-enabled and is user-invocable. It registers an event hook (message_received) and modifies message objects by attaching transcriptions — this is expected for a speech provider but it does mean the plugin can alter messages globally when registered.
What to consider before installing
This plugin appears to implement what it claims (macOS on-device TTS/STT via the voicecli CLI), but exercise caution before installing/running it: 1) It runs voicecli via shell commands and interpolates caller-provided paths/text into those commands. The escaping only replaces double quotes and does not prevent expansions like $(...), `...`, or $VAR, so a malicious or malformed audioPath/text could lead to shell injection. 2) Ensure you run this only on macOS hosts where you trust inputs (or run in a sandbox/container with limited privileges). 3) Prefer fixes before use: ask the maintainer to replace exec with a safer execFile/spawn variant (passing args as an array) or to robustly escape/validate inputs (disallow $/`/\n in user-supplied arguments, validate file paths exist under expected directories). 4) Verify voicecli is the official project you expect and install it from a trusted source. 5) Note the registry metadata mismatch: the package requires voicecli and macOS but the registry entry lists no required binaries — ask the publisher to correct metadata. If you cannot accept the injection risk, do not install or use this plugin until the input-handling is hardened.Verification
Tags
openclaw-macvoice
OpenClaw plugin for voice message support using native macOS speech APIs via voicecli.
⚠️ macOS only — This plugin requires macOS 13.0+ and uses native Apple frameworks (
SFSpeechRecognizer,AVSpeechSynthesizer).
Features
- 🎙️ Transcribe voice messages to text
- 🔊 Respond with voice — convert text responses to audio
- 🏠 Native macOS — uses
SFSpeechRecognizerandAVSpeechSynthesizer - ⚡ Fast — no cloud API calls, all on-device
Prerequisites
- macOS 13.0+ (required)
- voicecli installed:
brew tap acwilan/voicecli brew install voicecli
Installation
# From OpenClaw skill directory
npm install openclaw-macvoice
Usage
Basic
import macvoice from 'openclaw-macvoice';
// Initialize
const plugin = await macvoice.init(ctx, {
voice: 'com.apple.voice.compact.en-US.Samantha',
rate: 0.5,
});
// Transcribe a voice message
const transcription = await plugin.transcribe('/path/to/audio.m4a');
console.log('User said:', transcription);
// Respond with voice
const audioPath = await plugin.speak('Hello, how can I help you?');
// Send audioPath as voice message
With Telegram Channel
// In your Telegram OpenClaw handler
import macvoice from 'openclaw-macvoice';
export default {
async onVoiceMessage(message, ctx) {
// Initialize if not already
if (!ctx.macvoice) {
await macvoice.init(ctx, { rate: 0.5 });
}
// Transcribe
const text = await ctx.macvoice.transcribe(message.audioPath);
// Get AI response (your existing logic)
const response = await ctx.llm.chat(text);
// Convert to voice
const responseAudio = await ctx.macvoice.speak(response);
// Send voice response
await ctx.telegram.sendVoice({
chat_id: message.chat_id,
voice: responseAudio,
});
},
};
Configuration
| Option | Type | Default | Description |
|---|---|---|---|
voice | string | — | Voice identifier (see voicecli voices) |
rate | number | 0.5 | Speech rate 0.0-1.0 |
tempDir | string | os.tmpdir() | Directory for temporary audio files |
API
MacVoicePlugin
transcribe(audioPath: string): Promise<string>
Transcribe audio file to text.
speak(text: string, options?): Promise<string>
Convert text to speech. Returns path to generated audio file.
processVoiceMessage(audioPath, options)
Combined method: transcribe + optionally respond with voice.
Platform Support
| Platform | Status |
|---|---|
| macOS 13.0+ | ✅ Supported |
| Linux | ❌ Not supported |
| Windows | ❌ Not supported |
License
MIT
