Key changes:
- π Sound-out / voice-out β prompts can be read aloud, with an on-device neural voice (Supertonic)
- βοΈ In-app settings window β configure voice, behavior, and defaults from the tray
- π± Cross-device routing β an iOS / watchOS companion surfaces prompts on your phone and Watch
- π§©
dismiss_pendingMCP tool β for agent-driven voice loops - π Launch fix β 0.3.0 wouldn't open on some Macs; 0.3.1 fixes it and hardens the release pipeline so it can't recur
Fixed (0.3.1)
- 0.3.0 would not launch ("The application "cenno" can't be opened"). The
0.3.0 build added restricted iCloud/CloudKit entitlements for the relay, but a
Developer-ID (non-App-Store) bundle ships noembedded.provisionprofileto
authorize them, so macOS AMFI killed the app at spawn (exit 137). The iCloud
entitlements are removed; the relay is already gated to run without them, so no
functionality is lost on the Mac build. The release pipeline now launch-tests
the built app and rejects restricted entitlements lacking a provisioning
profile, so this class of brick cannot ship again.
What landed in 0.3.0
Added
- Sound-out (voice-out): cenno can read a prompt aloud when it appears.
Opt-in, urgency-gated, with an optional shortsaysummary. Two engines β
the fast macOS system voice and Supertonic, a fully on-device neural
voice (10 styles, F1βF5 / M1βM5) that downloads and runs locally. - In-app settings window (tray β "cenno settingsβ¦"): a tabbed
Settings / Integration / About window styled after the website. Configure
voice (engine, voice, urgency, audio output device, model download /
delete), behavior (launch at login, hide from Dock), and defaults β written
to~/.cennoand applied without a restart. dismiss_pendingMCP tool: unparks pending prompts and hides the panel
immediately, for agent-driven voice loops that capture the answer via an
external speech-to-text.- Cross-device prompt routing (second screens) and an iOS / watchOS
companion app that surfaces prompts on the phone and Watch.
Fixed
- CloudKit relay no longer crashes the app on builds without the iCloud
entitlement: the relay is gated on the entitlement being present instead of
trapping inside CloudKit (uncatchable from Swift).