@acpfx/cli
v0.5.2
Published
Observable audio pipeline framework — pluggable voice agent pipelines via YAML config
Readme
@acpfx/cli
The acpfx orchestrator — spawns pipeline nodes as child processes, routes NDJSON events between them, runs first-time setup (model downloads), and displays a real-time terminal dashboard.
Install
npx @acpfx/cli@latest onboardThe onboarding wizard walks you through choosing a pipeline template, configuring API keys, and running your first pipeline. A prebuilt binary is downloaded for your platform.
Usage
# Run a pipeline by name (resolved from .acpfx/pipelines/ or ~/.acpfx/pipelines/)
acpfx run deepgram
acpfx run local-gpu
# Run with explicit config path
acpfx run --config path/to/pipeline.yaml
# Run headless (no TUI, logs to stderr)
acpfx run deepgram --headless
# Interactive onboarding
acpfx onboard
# Manage configuration
acpfx config set env.DEEPGRAM_API_KEY sk-...
acpfx config get defaultPipeline
acpfx config set defaultPipeline deepgram --global
# List and create pipelines
acpfx pipelines
acpfx pipelines createPipeline Resolution
When you run acpfx run <name>, the pipeline is resolved in this order:
- Direct path — if
<name>contains/or ends with.yaml, load as file path - Project-local —
.acpfx/pipelines/<name>.yaml - Global —
~/.acpfx/pipelines/<name>.yaml - Bundled —
examples/pipeline/<name>.yaml(dev builds only)
If no pipeline is specified and no default is configured, the onboarding wizard runs automatically.
CLI Flags (acpfx run)
| Flag | Default | Description |
|------|---------|-------------|
| <pipeline> | | Pipeline name or path (positional) |
| --config | | Explicit path to YAML config (overrides positional) |
| --dist | dist | Path to built node artifacts (dev only) |
| --ready-timeout | 10000 | ms to wait for each node's lifecycle.ready |
| --headless | off | Disable TUI, log events to stderr |
| --setup-timeout | 600000 | ms for node setup phase (model downloads) |
| --skip-setup | off | Skip the --acpfx-setup-check phase |
Node Resolution
When the orchestrator encounters use: "@acpfx/<name>" in pipeline YAML, it resolves the node binary:
- Local JS bundle —
dist/nodes/<name>.js→ run vianode - Local native binary —
dist/nodes/<name>→ spawn directly - npx fallback —
npx -y @acpfx/<name>@latest→ download and run latest published version
Setup Phase
Before spawning nodes, the orchestrator runs a setup check:
- For each node, runs
<binary> --acpfx-setup-check(5s timeout) - If any node reports
{"needed": true}, runs<binary> --acpfx-setupto download models - Progress is displayed to stderr; auth errors show clear instructions (e.g.,
huggingface-cli login) - Skip with
--skip-setup
Available Nodes
| Package | Type | Description | |---------|------|-------------| | @acpfx/mic-speaker | Rust | Native mic capture with AEC | | @acpfx/mic-file | TS | WAV file playback as mic input | | @acpfx/stt-deepgram | TS | Deepgram streaming STT | | @acpfx/stt-elevenlabs | TS | ElevenLabs streaming STT | | @acpfx/stt-kyutai | Python | Local STT via Kyutai moshi (MLX on Mac, PyTorch+CUDA on Linux) | | @acpfx/bridge-acpx | TS | Agent bridge (Claude via acpx) | | @acpfx/tts-deepgram | TS | Deepgram streaming TTS | | @acpfx/tts-elevenlabs | TS | ElevenLabs streaming TTS | | @acpfx/tts-kyutai | Python | Local TTS via Kyutai moshi (MLX on Mac, PyTorch+CUDA on Linux) | | @acpfx/tts-pocket | Rust | Local lightweight TTS via Pocket TTS | | @acpfx/audio-player | TS | Audio mixer with SFX | | @acpfx/recorder | TS | Records events + audio to files | | @acpfx/play-file | TS | Writes audio chunks to WAV | | @acpfx/echo | TS | Echoes events back (testing) |
Pipeline Templates
Built-in templates available via acpfx onboard:
| Name | STT | TTS | Requires |
|------|-----|-----|----------|
| deepgram | Deepgram | Deepgram | DEEPGRAM_API_KEY |
| elevenlabs | ElevenLabs | ElevenLabs | ELEVENLABS_API_KEY |
| local | Kyutai (on-device) | Pocket TTS (CPU) | No API key |
| local-gpu | Kyutai (on-device) | Kyutai TTS (GPU) | No API key |
Building from Source
cargo build --release -p acpfx-orchestratorLicense
ISC
