vocalize-cli 0.12.0__tar.gz → 0.13.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/CHANGELOG.md +70 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/PKG-INFO +69 -14
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/README.md +68 -13
- vocalize_cli-0.13.0/docs/app.md +205 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/dictation.md +38 -2
- vocalize_cli-0.13.0/docs/installation.md +211 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/decisions.md +6 -6
- vocalize_cli-0.13.0/docs/plans/2026-09-app-roadmap/review-0.13.0.md +252 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-10-release-0-13-0/validate-exit.sh +2 -2
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-12-release-0-13-1/validate-exit.sh +2 -2
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-16-release-0-14-0/validate-exit.sh +2 -2
- vocalize_cli-0.13.0/docs/plans/2026-09-app-roadmap/run-6-release-0-12-0/report.md +31 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-6-release-0-12-0/validate-exit.sh +2 -2
- vocalize_cli-0.13.0/docs/plans/2026-09-app-roadmap/run-7-hotkey-spike-and-builder/report.md +17 -0
- vocalize_cli-0.13.0/docs/plans/2026-09-app-roadmap/run-7-hotkey-spike-and-builder/task-report.md +31 -0
- vocalize_cli-0.13.0/docs/plans/2026-09-app-roadmap/run-8a-app-swift/report.md +19 -0
- vocalize_cli-0.13.0/docs/plans/2026-09-app-roadmap/run-8a-app-swift/task-report.md +30 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-8a-app-swift/validate-exit.sh +12 -3
- vocalize_cli-0.13.0/docs/plans/2026-09-app-roadmap/run-8b-app-python/report.md +20 -0
- vocalize_cli-0.13.0/docs/plans/2026-09-app-roadmap/run-8b-app-python/task-report.md +36 -0
- vocalize_cli-0.13.0/docs/plans/2026-09-app-roadmap/run-9-doctor-integrate-setup/report.md +21 -0
- vocalize_cli-0.13.0/docs/plans/2026-09-app-roadmap/run-9-doctor-integrate-setup/task-report.md +29 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/spike-notes.md +9 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/verification.md +2 -2
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/roadmap.md +1 -1
- vocalize_cli-0.13.0/hooks/install_quick_action.py +13 -0
- vocalize_cli-0.13.0/hooks/speak_options.py +13 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/conftest.py +71 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/portal_page_harness.js +120 -1
- vocalize_cli-0.13.0/tests/test_app_build.py +242 -0
- vocalize_cli-0.13.0/tests/test_app_cli.py +777 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_cli.py +296 -1
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_config.py +116 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_dictate.py +131 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_install_quick_action.py +70 -30
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_local_install.py +27 -7
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_portal.py +153 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_portal_assets.py +14 -2
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_readiness.py +391 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_recorder_build.py +1 -37
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_speak_options.py +2 -1
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_wizard.py +20 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/__init__.py +1 -1
- vocalize_cli-0.13.0/vocalize/app.py +406 -0
- vocalize_cli-0.13.0/vocalize/assets/claude/speak/SKILL.md +168 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/assets/portal.html +9 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/assets/portal.js +143 -16
- {vocalize_cli-0.12.0/hooks → vocalize_cli-0.13.0/vocalize/assets}/quick_actions/Speak Latest Plan.workflow/Contents/Resources/document.wflow +1 -1
- {vocalize_cli-0.12.0/hooks → vocalize_cli-0.13.0/vocalize/assets}/quick_actions/Speak with Vocalize.workflow/Contents/Resources/document.wflow +2 -2
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/cli.py +282 -9
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/config.py +129 -1
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/dictate.py +42 -2
- vocalize_cli-0.13.0/vocalize/integrate.py +264 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/local/install.py +172 -52
- vocalize_cli-0.13.0/vocalize/menubar/Info.plist.in +47 -0
- vocalize_cli-0.13.0/vocalize/menubar/VocalizeApp.swift +1560 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/portal.py +40 -3
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/readiness.py +231 -2
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/wizard.py +3 -1
- vocalize_cli-0.12.0/docs/installation.md +0 -483
- vocalize_cli-0.12.0/hooks/install_quick_action.py +0 -136
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/.env.example +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/.github/workflows/ci.yml +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/.gitignore +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/LICENSE +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/next-features-analysis.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/choreography.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/design.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/review-0.12.0.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/review-plan-2026-09-06.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-1-local-first-defaults/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-1-local-first-defaults/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-1-local-first-defaults/task-report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-1-local-first-defaults/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-10-release-0-13-0/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-11-cue-hold-paste/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-11-cue-hold-paste/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-11b-playback-pause/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-11b-playback-pause/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-12-release-0-13-1/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-13-spikes/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-13-spikes/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-14-local-llm/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-14-local-llm/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-15-notes/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-15-notes/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-15b-recording-pause/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-15b-recording-pause/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-16-release-0-14-0/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-17-optional-spikes/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-17-optional-spikes/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-2-stt-decoding/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-2-stt-decoding/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-2-stt-decoding/task-report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-2-stt-decoding/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-3-llm-and-enums/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-3-llm-and-enums/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-3-llm-and-enums/task-report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-3-llm-and-enums/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-4-keychain/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-4-keychain/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-4-keychain/task-report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-4-keychain/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-5-keys-tab/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-5-keys-tab/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-5-keys-tab/task-report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-5-keys-tab/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-6-release-0-12-0/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-7-hotkey-spike-and-builder/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-7-hotkey-spike-and-builder/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-8a-app-swift/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-8b-app-python/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-8b-app-python/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-9-doctor-integrate-setup/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/run-9-doctor-integrate-setup/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-app-roadmap/split-assessment.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/choreography.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/decisions.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/design.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/review-0.10.0.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/review-0.11.0.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-1-status/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-1-status/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-1-status/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-10-release-0-11-0/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-10-release-0-11-0/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-10-release-0-11-0/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-2-stt-runtime/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-2-stt-runtime/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-2-stt-runtime/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-3-recorder/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-3-recorder/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-3-recorder/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-4-dictation/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-4-dictation/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-4-dictation/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-5-resume/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-5-resume/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-5-resume/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-6-release-0-10-0/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-6-release-0-10-0/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-6-release-0-10-0/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-7-portal-read/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-7-portal-read/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-7-portal-read/review-findings.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-7-portal-read/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-8-portal-write/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-8-portal-write/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-8-portal-write/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-9-portal-page/project-plan.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-9-portal-page/report.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-9-portal-page/review-findings.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/run-9-portal-page/validate-exit.sh +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/spike-2026-09-01.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/split-assessment.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/plans/2026-09-next-features/verification.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/provider-credentials.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/research/2026-09-01-config-portal-design.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/research/2026-09-01-dictation-design.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/research/2026-09-01-voicebox-findings.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/docs/research/2026-09-04-app-roadmap-analysis.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/hooks/claude_stop_hook.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/hooks/install_hook.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/hooks/speak_url_gate.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/pyproject.toml +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_audio.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_auth.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_cache.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_chain.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_claude_stop_hook.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_clipboard.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_cue_assets.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_elevenlabs_provider.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_exceptions.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_google_provider.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_http.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_install_hook.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_kokoro_manifest.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_kokoro_provider.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_kokoro_worker.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_ledger.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_listen_check.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_llm.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_openai_provider.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_polly_provider.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_preprocess.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_providers_registry.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_say_provider.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_speak_url_gate.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_tts.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_uv_path.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_whisper_manifest.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/tests/test_whisper_worker.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/uv.lock +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/__main__.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/assets/cues/README.md +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/assets/cues/ready.wav +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/assets/cues/start.wav +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/assets/cues/stopped.wav +0 -0
- {vocalize_cli-0.12.0/hooks → vocalize_cli-0.13.0/vocalize/assets}/quick_actions/Dictate with Vocalize.workflow/Contents/Info.plist +0 -0
- {vocalize_cli-0.12.0/hooks → vocalize_cli-0.13.0/vocalize/assets}/quick_actions/Dictate with Vocalize.workflow/Contents/Resources/document.wflow +0 -0
- {vocalize_cli-0.12.0/hooks → vocalize_cli-0.13.0/vocalize/assets}/quick_actions/Speak Latest Plan.workflow/Contents/Info.plist +0 -0
- {vocalize_cli-0.12.0/hooks → vocalize_cli-0.13.0/vocalize/assets}/quick_actions/Speak with Vocalize.workflow/Contents/Info.plist +0 -0
- {vocalize_cli-0.12.0/hooks → vocalize_cli-0.13.0/vocalize/assets}/quick_actions/Stop Vocalize.workflow/Contents/Info.plist +0 -0
- {vocalize_cli-0.12.0/hooks → vocalize_cli-0.13.0/vocalize/assets}/quick_actions/Stop Vocalize.workflow/Contents/Resources/document.wflow +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/audio.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/auth.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/cache.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/chain.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/clipboard.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/exceptions.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/interrupted.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/ledger.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/llm.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/local/__init__.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/local/kokoro_manifest.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/local/kokoro_worker.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/local/whisper_manifest.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/local/whisper_worker.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/preprocess.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/providers/__init__.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/providers/_http.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/providers/elevenlabs.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/providers/google.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/providers/kokoro.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/providers/openai.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/providers/polly.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/providers/say.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/recorder/Info.plist.in +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/recorder/Recorder.entitlements +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/recorder/VocalizeRecorder.swift +0 -0
- {vocalize_cli-0.12.0/hooks → vocalize_cli-0.13.0/vocalize}/speak_options.py +0 -0
- {vocalize_cli-0.12.0 → vocalize_cli-0.13.0}/vocalize/tts.py +0 -0
|
@@ -7,6 +7,76 @@ All notable changes to this project are documented here. Format follows
|
|
|
7
7
|
|
|
8
8
|
Nothing yet.
|
|
9
9
|
|
|
10
|
+
## 0.13.0 - 2026-09-08
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **The `[app]` config table** for the menu-bar app that arrives in 0.13.0:
|
|
15
|
+
`dictate`, `speak` and `stop` chords (`ctrl+alt+cmd+d`, `+s`, `+x` by
|
|
16
|
+
default; tokens joined by `+`, modifiers ctrl/alt/cmd/shift with their
|
|
17
|
+
long-form aliases, a key of a–z, 0–9 or f1–f12, ctrl or cmd required,
|
|
18
|
+
`""` disables) and `dictate_mode` (`toggle`; `hold` parses and resolves
|
|
19
|
+
to toggle with one warning until 0.13.1). The wizard renders it and
|
|
20
|
+
`vocalize settings` prints `app.<key>=…` in one canonical spelling.
|
|
21
|
+
- **`vocalize app install / uninstall / status [--json] / restart`** —
|
|
22
|
+
a menu-bar app (`Vocalize.app`) that owns the dictation, speak and stop
|
|
23
|
+
hotkeys system-wide, as a LaunchAgent, so a hotkey works from any app
|
|
24
|
+
with no Services menu and no per-app shortcut assignment. `install`
|
|
25
|
+
builds the bundle, warns about a running Hammerspoon or a Services
|
|
26
|
+
shortcut assigned to the "Dictate with Vocalize" Quick Action, resets
|
|
27
|
+
the Accessibility grant
|
|
28
|
+
only on a rebuild, and loads the LaunchAgent; `status` reports what's
|
|
29
|
+
built, whether the agent is loaded, and the app's own hotkey and
|
|
30
|
+
Accessibility state; `restart` kicks the running app without touching
|
|
31
|
+
the LaunchAgent; `uninstall` removes everything `install` put down
|
|
32
|
+
and leaves the Accessibility entry in System Settings alone. See
|
|
33
|
+
[docs/app.md](docs/app.md).
|
|
34
|
+
- **`dictate.session` gains a `state` and a per-dictation `nonce`.**
|
|
35
|
+
`state` moves through `starting` → `recording` → `transcribing` as a
|
|
36
|
+
dictation runs, so anything reading the session file (the app included)
|
|
37
|
+
knows which stage it's watching, not just that one is in progress.
|
|
38
|
+
`nonce` ties one dictation's session to its eventual `dictate.copied`
|
|
39
|
+
write. Unknown keys in the file are still ignored.
|
|
40
|
+
- **`vocalize doctor [--json]`** — every readiness row plus the toolchain
|
|
41
|
+
and environment checks `status` doesn't cover: `cli path`, `uv`,
|
|
42
|
+
`swiftc`, `claude` on PATH, the running console script's shebang
|
|
43
|
+
(brew rot), a Hammerspoon or old Quick Action conflict, `vocalize
|
|
44
|
+
--version` cold-start time, app bundle state with its repair command,
|
|
45
|
+
and the notes folder's size on disk. Exits 1 only on a failing row;
|
|
46
|
+
warn rows print but don't fail a script.
|
|
47
|
+
- **`vocalize integrate claude [--yes]`** — one command in place of the
|
|
48
|
+
hand-rolled `/speak` skill and the standalone Quick Action installer.
|
|
49
|
+
Checks `vocalize`, `claude`, `node`, and `python3` on PATH, installs
|
|
50
|
+
`~/.claude/skills/speak/SKILL.md` from the package (kept unless
|
|
51
|
+
`--yes`), installs the four Quick Actions into `~/Library/Services`,
|
|
52
|
+
and prints the GUI-only hotkey and Accessibility steps. The Quick
|
|
53
|
+
Action installer and its `.workflow` bundles moved into the package
|
|
54
|
+
(`vocalize/assets/quick_actions/`); `hooks/install_quick_action.py` is
|
|
55
|
+
now a thin wrapper around it. The baked `claude` path is the stable
|
|
56
|
+
symlink, not `.resolve()`'s version-pinned Caskroom target, so a
|
|
57
|
+
`brew upgrade claude-code` no longer silently breaks the summary
|
|
58
|
+
picker.
|
|
59
|
+
- **The Setup tab** in `vocalize portal` — a nine-step checklist
|
|
60
|
+
(toolchain, both bundles, login item, chords, model download,
|
|
61
|
+
microphone, `/speak` and Quick Actions, Accessibility, self-test)
|
|
62
|
+
built from the readiness rows the sidebar shows; its first step points at
|
|
63
|
+
`vocalize doctor`. Its install
|
|
64
|
+
buttons drive the existing `/api/local/install` routes, now including
|
|
65
|
+
target `app`. See [docs/app.md](docs/app.md#the-setup-tab).
|
|
66
|
+
|
|
67
|
+
### Changed
|
|
68
|
+
|
|
69
|
+
- **The recorder is built by a general bundle builder.** `build_bundle(BundleSpec)`
|
|
70
|
+
replaces the recorder-only code path; `build_recorder` is the recorder's
|
|
71
|
+
door onto it and its build is unchanged byte for byte (a golden test pins
|
|
72
|
+
the `swiftc` and `codesign` argv, because any drift is a new ad-hoc
|
|
73
|
+
signature and a microphone re-grant). `vocalize local uninstall --stt`
|
|
74
|
+
now removes only the recorder bundle and its stamp, never the whole
|
|
75
|
+
`~/.cache/vocalize/bin`.
|
|
76
|
+
- **`vocalize clip` exits 3, not 1, when it refuses a credential-shaped
|
|
77
|
+
clipboard.** A script that already treats exit 1 as "something went
|
|
78
|
+
wrong, try again" can now tell that refusal apart from a real failure.
|
|
79
|
+
|
|
10
80
|
## 0.12.0 - 2026-09-07
|
|
11
81
|
|
|
12
82
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vocalize-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.0
|
|
4
4
|
Summary: A local-first CLI that turns text, markdown, or piped stdin into speech: the on-device Kokoro voice by default, cloud voices optional, with markdown-table-aware preprocessing and Claude Code hooks.
|
|
5
5
|
Project-URL: Homepage, https://github.com/matthager12-collab/vocalize
|
|
6
6
|
Project-URL: Repository, https://github.com/matthager12-collab/vocalize
|
|
@@ -513,13 +513,24 @@ more accurate) or `--model base.en` (~141 MB, fastest, least accurate).
|
|
|
513
513
|
### The hotkey
|
|
514
514
|
|
|
515
515
|
```bash
|
|
516
|
-
|
|
516
|
+
vocalize app install
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
installs and starts **Vocalize.app**, a menu-bar app that owns the
|
|
520
|
+
dictation hotkey (and speak/stop) system-wide, no Services menu or
|
|
521
|
+
per-app shortcut assignment needed — see [docs/app.md](docs/app.md) for
|
|
522
|
+
install, uninstall, status and restart. `vocalize dictate` is the same
|
|
523
|
+
command from a terminal, if you'd rather trigger it that way.
|
|
524
|
+
|
|
525
|
+
Prefer a Quick Action instead? That still works:
|
|
526
|
+
|
|
527
|
+
```bash
|
|
528
|
+
vocalize integrate claude
|
|
517
529
|
```
|
|
518
530
|
|
|
519
531
|
then assign a shortcut under **System Settings › Keyboard › Keyboard
|
|
520
532
|
Shortcuts › Services › Text › "Dictate with Vocalize"** — ⌃⌥⌘D is free by
|
|
521
|
-
default and a sensible pick.
|
|
522
|
-
terminal, if you'd rather trigger it that way.
|
|
533
|
+
default and a sensible pick.
|
|
523
534
|
|
|
524
535
|
### How a dictation works
|
|
525
536
|
|
|
@@ -609,6 +620,37 @@ set it:
|
|
|
609
620
|
input_device = "MacBook Pro Microphone"
|
|
610
621
|
```
|
|
611
622
|
|
|
623
|
+
### Configuration: the `[app]` table
|
|
624
|
+
|
|
625
|
+
The chords the menu-bar app owns, system-wide. A change needs
|
|
626
|
+
`vocalize app restart` before the app picks it up.
|
|
627
|
+
|
|
628
|
+
```toml
|
|
629
|
+
[app]
|
|
630
|
+
dictate = "ctrl+alt+cmd+d" # start/stop dictation
|
|
631
|
+
dictate_mode = "toggle" # toggle | hold ("hold" arrives in 0.13.1)
|
|
632
|
+
speak = "ctrl+alt+cmd+s" # speak the selection
|
|
633
|
+
stop = "ctrl+alt+cmd+x" # stop whatever is playing
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
| Key | Allowed values | Default |
|
|
637
|
+
|---|---|---|
|
|
638
|
+
| `dictate` | a chord, or `""` to disable | `ctrl+alt+cmd+d` |
|
|
639
|
+
| `dictate_mode` | `toggle`, `hold` | `toggle` |
|
|
640
|
+
| `speak` | a chord, or `""` to disable | `ctrl+alt+cmd+s` |
|
|
641
|
+
| `stop` | a chord, or `""` to disable | `ctrl+alt+cmd+x` |
|
|
642
|
+
|
|
643
|
+
**Chord grammar:** tokens joined by `+`. Modifiers are `ctrl`, `alt`,
|
|
644
|
+
`cmd`, `shift` (long spellings `control`, `option`, `command` also work);
|
|
645
|
+
the key is one of `a`-`z`, `0`-`9`, `f1`-`f12`. A chord must include
|
|
646
|
+
`ctrl` or `cmd` — macOS refuses to register the rest. The three chords
|
|
647
|
+
must differ from each other, and `""` disables one.
|
|
648
|
+
|
|
649
|
+
A bad chord is a `ConfigError` naming the key, the value and the legal
|
|
650
|
+
keys — and, like any bad config value, it stops the command you ran, so
|
|
651
|
+
fix it before anything else works. `vocalize settings` prints the four
|
|
652
|
+
`app.*` values in their canonical spelling.
|
|
653
|
+
|
|
612
654
|
### `vocalize status`
|
|
613
655
|
|
|
614
656
|
```bash
|
|
@@ -631,6 +673,17 @@ get four permanent red rows for a feature nobody asked for):
|
|
|
631
673
|
providers and dictation both — is `ok`, 1 otherwise, so it composes with
|
|
632
674
|
`&&` in a script.
|
|
633
675
|
|
|
676
|
+
### `vocalize doctor`
|
|
677
|
+
|
|
678
|
+
Everything `status` checks plus the machine itself: the CLI's own path and
|
|
679
|
+
start-up time, `uv`, `swiftc`, `claude`, the console script's interpreter,
|
|
680
|
+
Hammerspoon, the app bundle and the notes folder. Every row regardless of the
|
|
681
|
+
chain, exit 1 when any row fails. `--json` for scripts.
|
|
682
|
+
|
|
683
|
+
```bash
|
|
684
|
+
vocalize doctor
|
|
685
|
+
```
|
|
686
|
+
|
|
634
687
|
### Continuing an interrupted read
|
|
635
688
|
|
|
636
689
|
Starting a dictation stops any read in progress, but doesn't throw the rest
|
|
@@ -704,15 +757,16 @@ Four Services let you use vocalize from any app without a terminal:
|
|
|
704
757
|
Install all four:
|
|
705
758
|
|
|
706
759
|
```bash
|
|
707
|
-
|
|
760
|
+
vocalize integrate claude
|
|
708
761
|
```
|
|
709
762
|
|
|
710
|
-
This
|
|
711
|
-
`~/Library/Services
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
763
|
+
This installs the `/speak` skill plus the four Quick Action bundles into
|
|
764
|
+
`~/Library/Services/`, with this machine's `vocalize`, `claude`, and
|
|
765
|
+
helper paths baked in (the stable symlinks, not their resolved targets —
|
|
766
|
+
survives a `brew upgrade claude-code`), then refreshes the Services
|
|
767
|
+
registry. Run it from a normal terminal — its PATH is what gets captured.
|
|
768
|
+
To trigger the actions from the keyboard, assign shortcuts under System
|
|
769
|
+
Settings → Keyboard → Keyboard Shortcuts → Services (Stop Vocalize is worth a
|
|
716
770
|
shortcut of its own so you can silence a read from anywhere).
|
|
717
771
|
|
|
718
772
|
Some Electron apps (Claude Code desktop among them) don't expose the
|
|
@@ -924,9 +978,10 @@ model.
|
|
|
924
978
|
there. Use `--no-play` and open the saved file with whatever's on hand.
|
|
925
979
|
- **The disk cache under `~/.cache/vocalize` grows unbounded.** It's
|
|
926
980
|
content-addressed (keyed by a hash of text, voice, model, format, and
|
|
927
|
-
speed),
|
|
928
|
-
|
|
929
|
-
|
|
981
|
+
speed), so it's always safe to delete — except `bin/`, which holds
|
|
982
|
+
Vocalize Recorder and is tied to your microphone grant; deleting that
|
|
983
|
+
forces a rebuild and a re-grant. Delete anything else and nothing will
|
|
984
|
+
break, you'll just re-pay for a re-synthesized clip.
|
|
930
985
|
- **`--api-key` on the command line is visible to other local processes**
|
|
931
986
|
(anything that can run `ps`). Prefer `vocalize auth login`, the
|
|
932
987
|
`ELEVENLABS_API_KEY` environment variable, or a `.env` file instead.
|
|
@@ -477,13 +477,24 @@ more accurate) or `--model base.en` (~141 MB, fastest, least accurate).
|
|
|
477
477
|
### The hotkey
|
|
478
478
|
|
|
479
479
|
```bash
|
|
480
|
-
|
|
480
|
+
vocalize app install
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
installs and starts **Vocalize.app**, a menu-bar app that owns the
|
|
484
|
+
dictation hotkey (and speak/stop) system-wide, no Services menu or
|
|
485
|
+
per-app shortcut assignment needed — see [docs/app.md](docs/app.md) for
|
|
486
|
+
install, uninstall, status and restart. `vocalize dictate` is the same
|
|
487
|
+
command from a terminal, if you'd rather trigger it that way.
|
|
488
|
+
|
|
489
|
+
Prefer a Quick Action instead? That still works:
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
vocalize integrate claude
|
|
481
493
|
```
|
|
482
494
|
|
|
483
495
|
then assign a shortcut under **System Settings › Keyboard › Keyboard
|
|
484
496
|
Shortcuts › Services › Text › "Dictate with Vocalize"** — ⌃⌥⌘D is free by
|
|
485
|
-
default and a sensible pick.
|
|
486
|
-
terminal, if you'd rather trigger it that way.
|
|
497
|
+
default and a sensible pick.
|
|
487
498
|
|
|
488
499
|
### How a dictation works
|
|
489
500
|
|
|
@@ -573,6 +584,37 @@ set it:
|
|
|
573
584
|
input_device = "MacBook Pro Microphone"
|
|
574
585
|
```
|
|
575
586
|
|
|
587
|
+
### Configuration: the `[app]` table
|
|
588
|
+
|
|
589
|
+
The chords the menu-bar app owns, system-wide. A change needs
|
|
590
|
+
`vocalize app restart` before the app picks it up.
|
|
591
|
+
|
|
592
|
+
```toml
|
|
593
|
+
[app]
|
|
594
|
+
dictate = "ctrl+alt+cmd+d" # start/stop dictation
|
|
595
|
+
dictate_mode = "toggle" # toggle | hold ("hold" arrives in 0.13.1)
|
|
596
|
+
speak = "ctrl+alt+cmd+s" # speak the selection
|
|
597
|
+
stop = "ctrl+alt+cmd+x" # stop whatever is playing
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
| Key | Allowed values | Default |
|
|
601
|
+
|---|---|---|
|
|
602
|
+
| `dictate` | a chord, or `""` to disable | `ctrl+alt+cmd+d` |
|
|
603
|
+
| `dictate_mode` | `toggle`, `hold` | `toggle` |
|
|
604
|
+
| `speak` | a chord, or `""` to disable | `ctrl+alt+cmd+s` |
|
|
605
|
+
| `stop` | a chord, or `""` to disable | `ctrl+alt+cmd+x` |
|
|
606
|
+
|
|
607
|
+
**Chord grammar:** tokens joined by `+`. Modifiers are `ctrl`, `alt`,
|
|
608
|
+
`cmd`, `shift` (long spellings `control`, `option`, `command` also work);
|
|
609
|
+
the key is one of `a`-`z`, `0`-`9`, `f1`-`f12`. A chord must include
|
|
610
|
+
`ctrl` or `cmd` — macOS refuses to register the rest. The three chords
|
|
611
|
+
must differ from each other, and `""` disables one.
|
|
612
|
+
|
|
613
|
+
A bad chord is a `ConfigError` naming the key, the value and the legal
|
|
614
|
+
keys — and, like any bad config value, it stops the command you ran, so
|
|
615
|
+
fix it before anything else works. `vocalize settings` prints the four
|
|
616
|
+
`app.*` values in their canonical spelling.
|
|
617
|
+
|
|
576
618
|
### `vocalize status`
|
|
577
619
|
|
|
578
620
|
```bash
|
|
@@ -595,6 +637,17 @@ get four permanent red rows for a feature nobody asked for):
|
|
|
595
637
|
providers and dictation both — is `ok`, 1 otherwise, so it composes with
|
|
596
638
|
`&&` in a script.
|
|
597
639
|
|
|
640
|
+
### `vocalize doctor`
|
|
641
|
+
|
|
642
|
+
Everything `status` checks plus the machine itself: the CLI's own path and
|
|
643
|
+
start-up time, `uv`, `swiftc`, `claude`, the console script's interpreter,
|
|
644
|
+
Hammerspoon, the app bundle and the notes folder. Every row regardless of the
|
|
645
|
+
chain, exit 1 when any row fails. `--json` for scripts.
|
|
646
|
+
|
|
647
|
+
```bash
|
|
648
|
+
vocalize doctor
|
|
649
|
+
```
|
|
650
|
+
|
|
598
651
|
### Continuing an interrupted read
|
|
599
652
|
|
|
600
653
|
Starting a dictation stops any read in progress, but doesn't throw the rest
|
|
@@ -668,15 +721,16 @@ Four Services let you use vocalize from any app without a terminal:
|
|
|
668
721
|
Install all four:
|
|
669
722
|
|
|
670
723
|
```bash
|
|
671
|
-
|
|
724
|
+
vocalize integrate claude
|
|
672
725
|
```
|
|
673
726
|
|
|
674
|
-
This
|
|
675
|
-
`~/Library/Services
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
727
|
+
This installs the `/speak` skill plus the four Quick Action bundles into
|
|
728
|
+
`~/Library/Services/`, with this machine's `vocalize`, `claude`, and
|
|
729
|
+
helper paths baked in (the stable symlinks, not their resolved targets —
|
|
730
|
+
survives a `brew upgrade claude-code`), then refreshes the Services
|
|
731
|
+
registry. Run it from a normal terminal — its PATH is what gets captured.
|
|
732
|
+
To trigger the actions from the keyboard, assign shortcuts under System
|
|
733
|
+
Settings → Keyboard → Keyboard Shortcuts → Services (Stop Vocalize is worth a
|
|
680
734
|
shortcut of its own so you can silence a read from anywhere).
|
|
681
735
|
|
|
682
736
|
Some Electron apps (Claude Code desktop among them) don't expose the
|
|
@@ -888,9 +942,10 @@ model.
|
|
|
888
942
|
there. Use `--no-play` and open the saved file with whatever's on hand.
|
|
889
943
|
- **The disk cache under `~/.cache/vocalize` grows unbounded.** It's
|
|
890
944
|
content-addressed (keyed by a hash of text, voice, model, format, and
|
|
891
|
-
speed),
|
|
892
|
-
|
|
893
|
-
|
|
945
|
+
speed), so it's always safe to delete — except `bin/`, which holds
|
|
946
|
+
Vocalize Recorder and is tied to your microphone grant; deleting that
|
|
947
|
+
forces a rebuild and a re-grant. Delete anything else and nothing will
|
|
948
|
+
break, you'll just re-pay for a re-synthesized clip.
|
|
894
949
|
- **`--api-key` on the command line is visible to other local processes**
|
|
895
950
|
(anything that can run `ps`). Prefer `vocalize auth login`, the
|
|
896
951
|
`ELEVENLABS_API_KEY` environment variable, or a `.env` file instead.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# The menu-bar app
|
|
2
|
+
|
|
3
|
+
`Vocalize.app` is a small Swift menu-bar app that owns the dictation and
|
|
4
|
+
speak-selection hotkeys system-wide. It replaces both the Hammerspoon
|
|
5
|
+
config and the Quick Action as the way to trigger vocalize from the
|
|
6
|
+
keyboard — it runs all the time, as a LaunchAgent, so a hotkey works from
|
|
7
|
+
any app without a terminal or a Service menu.
|
|
8
|
+
|
|
9
|
+
It does one job: listen for its three chords, then run the matching
|
|
10
|
+
`vocalize` command (`dictate`, `clip`, `stop`) as a subprocess. It never
|
|
11
|
+
touches your microphone or clipboard itself and never reads the audio or
|
|
12
|
+
the transcript — `vocalize` does that work, same as if you'd typed the
|
|
13
|
+
command.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
vocalize app install
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This:
|
|
22
|
+
|
|
23
|
+
1. Checks that the `vocalize` you're running right now is one the app can
|
|
24
|
+
find. The app only looks in `~/.local/bin`, `/opt/homebrew/bin` and
|
|
25
|
+
`/usr/local/bin`; if yours isn't one of those, install prints a
|
|
26
|
+
`defaults write` line (see [Pointing the app at a different
|
|
27
|
+
vocalize](#pointing-the-app-at-a-different-vocalize) below) and stops —
|
|
28
|
+
pass `--yes` to print the same line and continue anyway.
|
|
29
|
+
2. Warns if Hammerspoon is running, or if the "Dictate with Vocalize"
|
|
30
|
+
Quick Action has a keyboard shortcut on one of the app's chords —
|
|
31
|
+
either can steal it (see
|
|
32
|
+
[Conflicts](#conflicts-hammerspoon-and-the-old-quick-action)).
|
|
33
|
+
3. Builds `Vocalize.app` under `~/Library/Application Support/vocalize`
|
|
34
|
+
if it isn't already current — see [The re-grant
|
|
35
|
+
rule](#the-re-grant-rule) for what happens when a build replaces one
|
|
36
|
+
that was already there.
|
|
37
|
+
4. Writes the LaunchAgent plist at
|
|
38
|
+
`~/Library/LaunchAgents/cards.arda.vocalize.app.plist` and loads it,
|
|
39
|
+
so the app starts now and again at every login.
|
|
40
|
+
|
|
41
|
+
It asks to confirm first, listing exactly what it's about to write.
|
|
42
|
+
`--yes` skips that prompt.
|
|
43
|
+
|
|
44
|
+
## Status
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
vocalize app status
|
|
48
|
+
vocalize app status --json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Reports what's built, whether the LaunchAgent is loaded, and what the
|
|
52
|
+
app itself last wrote about its hotkeys and Accessibility grant:
|
|
53
|
+
|
|
54
|
+
| Row | Reports |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `bundle` | `current`, `stale`, or `not built` — read-only, this never triggers a build |
|
|
57
|
+
| `agent` | `loaded`, `not running`, or `unknown` — from `launchctl`; a result it can't parse reads as `unknown`, never `not running` |
|
|
58
|
+
| `accessibility` | `granted`, `not granted`, or `unknown` |
|
|
59
|
+
| `hotkeys` | `ok`, `failed:<name>`, or `unknown` — which chord, if any, failed to register |
|
|
60
|
+
| `hotkey_backend` | `carbon` or `monitor` — which macOS API is handling the keys |
|
|
61
|
+
| `vocalize` | the path the app resolved, or `none` |
|
|
62
|
+
|
|
63
|
+
The last four come from the app's own status file and can be stale
|
|
64
|
+
between runs — the app only rewrites it when something changes.
|
|
65
|
+
|
|
66
|
+
`--json` prints the same six keys as one object. Exit code is 0 when
|
|
67
|
+
`bundle` is `current` and `agent` is `loaded`, 1 otherwise, so it
|
|
68
|
+
composes with `&&` in a script.
|
|
69
|
+
|
|
70
|
+
## Chords
|
|
71
|
+
|
|
72
|
+
Three chords, set under `[app]` in `~/.config/vocalize/config.toml`:
|
|
73
|
+
|
|
74
|
+
| Key | What it does | Default |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `dictate` | start/stop dictation | `ctrl+alt+cmd+d` |
|
|
77
|
+
| `dictate_mode` | `toggle` or `hold` (`hold` arrives in 0.13.1) | `toggle` |
|
|
78
|
+
| `speak` | speak the selection | `ctrl+alt+cmd+s` |
|
|
79
|
+
| `stop` | stop whatever is playing | `ctrl+alt+cmd+x` |
|
|
80
|
+
|
|
81
|
+
```toml
|
|
82
|
+
[app]
|
|
83
|
+
dictate = "ctrl+alt+cmd+d"
|
|
84
|
+
dictate_mode = "toggle"
|
|
85
|
+
speak = "ctrl+alt+cmd+s"
|
|
86
|
+
stop = "ctrl+alt+cmd+x"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Tokens join with `+`. Modifiers are `ctrl`, `alt`, `cmd`, `shift` (or the
|
|
90
|
+
long `control`, `option`, `command`); the key is one of `a`-`z`, `0`-`9`,
|
|
91
|
+
`f1`-`f12`. Every chord needs `ctrl` or `cmd`, because macOS refuses to
|
|
92
|
+
register the rest. The three must differ from each other; `""` disables
|
|
93
|
+
one.
|
|
94
|
+
|
|
95
|
+
A chord the parser rejects is a config error, and config is read by
|
|
96
|
+
almost every command — so a typo here stops `vocalize speak` and
|
|
97
|
+
`vocalize status` too, with a message naming the key and the legal keys.
|
|
98
|
+
`vocalize doctor` still runs, and reports it as a failed `config file`
|
|
99
|
+
row. The running app keeps the chords it already registered until the
|
|
100
|
+
file is valid again and you run `vocalize app restart`.
|
|
101
|
+
|
|
102
|
+
## Restart
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
vocalize app restart
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Stops and starts the running app without touching the LaunchAgent or
|
|
109
|
+
rebuilding anything — the equivalent of quitting it from its own menu
|
|
110
|
+
and having it come back. Use this after a config change (a new chord
|
|
111
|
+
under `[app]`) instead of a full `install`.
|
|
112
|
+
|
|
113
|
+
## Uninstall
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
vocalize app uninstall
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Unloads the app and removes what `install` put on this machine: the
|
|
120
|
+
bundle, the LaunchAgent plist, the app's status and log files, and the
|
|
121
|
+
`VocalizeBinary` override if one was set. It lists exactly what it's
|
|
122
|
+
about to remove and asks first; `--yes` skips the prompt.
|
|
123
|
+
|
|
124
|
+
The Accessibility entry itself stays in System Settings — macOS keeps a
|
|
125
|
+
record of every app that ever asked, uninstalled or not — remove it
|
|
126
|
+
there if you want it gone too. Dictation and the recorder's own
|
|
127
|
+
microphone grant are a separate install (`vocalize local install --stt`)
|
|
128
|
+
and are untouched by this command.
|
|
129
|
+
|
|
130
|
+
## The re-grant rule
|
|
131
|
+
|
|
132
|
+
The app's Accessibility permission is tied to its ad-hoc code signature,
|
|
133
|
+
the same way the recorder's microphone permission is (see
|
|
134
|
+
[docs/dictation.md](dictation.md#rebuilds-and-re-granting-the-microphone)).
|
|
135
|
+
`install` only rebuilds the bundle — and only resets the grant — when one
|
|
136
|
+
of these is true:
|
|
137
|
+
|
|
138
|
+
- the Swift source changed since the bundle was last built, or
|
|
139
|
+
- the bundle or its stamp file is missing (deleted by hand, or by
|
|
140
|
+
`app uninstall`, or by clearing `~/Library/Application Support`
|
|
141
|
+
yourself).
|
|
142
|
+
|
|
143
|
+
Either one produces a new signature, so `install` runs
|
|
144
|
+
`tccutil reset Accessibility cards.arda.vocalize.app` before loading it
|
|
145
|
+
and prints:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
Vocalize.app was rebuilt — its Accessibility grant was reset; re-grant it in
|
|
149
|
+
System Settings › Privacy & Security › Accessibility the next time it asks
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
A plain `install` on an already-current bundle never touches `tccutil` —
|
|
153
|
+
most upgrades don't touch the Swift source, so most re-installs cost you
|
|
154
|
+
nothing.
|
|
155
|
+
|
|
156
|
+
## Pointing the app at a different vocalize
|
|
157
|
+
|
|
158
|
+
The app doesn't search your `PATH` — it only checks three fixed
|
|
159
|
+
locations. If `install` reports your `vocalize` isn't one of them, run
|
|
160
|
+
the line it prints:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
defaults write cards.arda.vocalize.app VocalizeBinary /path/to/vocalize
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Uninstalling removes this override automatically.
|
|
167
|
+
|
|
168
|
+
## The Setup tab
|
|
169
|
+
|
|
170
|
+
`vocalize portal` has a **Setup** tab, after Local. It walks the nine
|
|
171
|
+
setup steps — toolchain, building both bundles, the login item, chords,
|
|
172
|
+
the model download, the microphone, `/speak` and Quick Actions,
|
|
173
|
+
Accessibility, and a self-test — as a checklist built from the readiness
|
|
174
|
+
rows the sidebar shows (step 1 points at `vocalize doctor`), so it's always
|
|
175
|
+
current with what's actually on the machine. Its "Install the app" button drives this same `app install`
|
|
176
|
+
sequence (build, plist, bootout, bootstrap, and the Accessibility reset on
|
|
177
|
+
a rebuild) through the portal instead of the CLI; the GUI-only steps still
|
|
178
|
+
print from `vocalize integrate claude`, not the page.
|
|
179
|
+
|
|
180
|
+
## Quit stays quit
|
|
181
|
+
|
|
182
|
+
The app's own menu has a Quit item, and quitting it stays quit — it does
|
|
183
|
+
not relaunch itself the next time it crashes on purpose or the way a
|
|
184
|
+
typical LaunchAgent does on every exit. It comes back at your next login,
|
|
185
|
+
or the next time you run `vocalize app restart` or `install`.
|
|
186
|
+
|
|
187
|
+
## Conflicts: Hammerspoon and the old Quick Action
|
|
188
|
+
|
|
189
|
+
Two older ways of binding the same keys can steal a chord out from under
|
|
190
|
+
the app, so its hotkey silently does nothing:
|
|
191
|
+
|
|
192
|
+
- **Hammerspoon**, if it's still running and still has the old
|
|
193
|
+
`hs.hotkey.bind` lines for dictate/speak. `install` checks for a
|
|
194
|
+
running Hammerspoon and, if found, tells you to remove the
|
|
195
|
+
`ctrl-alt-cmd-S` and `ctrl-alt-cmd-X` bind lines from
|
|
196
|
+
`~/.hammerspoon/init.lua` and reload Hammerspoon.
|
|
197
|
+
- **A Services keyboard shortcut** on the "Dictate with Vocalize" or
|
|
198
|
+
"Stop Vocalize" Quick Action. `vocalize integrate claude` installs both
|
|
199
|
+
on purpose, and keeping them is fine — they stay reachable from the
|
|
200
|
+
Services menu. What conflicts is *assigning* ctrl-alt-cmd-D or
|
|
201
|
+
ctrl-alt-cmd-X to one in System Settings › Keyboard › Keyboard
|
|
202
|
+
Shortcuts › Services: the assignment wins and the app's hotkey never
|
|
203
|
+
fires. `install` says so when the Quick Action is present.
|
|
204
|
+
|
|
205
|
+
Neither check blocks the install; they're warnings, not a hard stop.
|
|
@@ -90,6 +90,19 @@ recorder did not start."
|
|
|
90
90
|
|
|
91
91
|
## The hotkey
|
|
92
92
|
|
|
93
|
+
```bash
|
|
94
|
+
vocalize app install
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
builds and loads **Vocalize.app**, a menu-bar app that owns the dictation
|
|
98
|
+
hotkey system-wide — no Services menu, no shortcut assignment, no
|
|
99
|
+
per-app Electron gap. It starts at login and stays running; see
|
|
100
|
+
[docs/app.md](app.md) for install, uninstall, status and restart, and
|
|
101
|
+
`vocalize app status` for whether it's currently loaded and which chord
|
|
102
|
+
(if any) failed to register.
|
|
103
|
+
|
|
104
|
+
Prefer the Quick Action instead?
|
|
105
|
+
|
|
93
106
|
```bash
|
|
94
107
|
python3 hooks/install_quick_action.py
|
|
95
108
|
```
|
|
@@ -107,7 +120,7 @@ project was built and tested around, but any unused combination works.
|
|
|
107
120
|
|
|
108
121
|
From a terminal, the identical command is `vocalize dictate` (an alias for
|
|
109
122
|
`vocalize listen --toggle`) — useful for testing the toggle without
|
|
110
|
-
touching System Settings at all.
|
|
123
|
+
touching System Settings at all, whichever way you trigger it.
|
|
111
124
|
|
|
112
125
|
## Using it
|
|
113
126
|
|
|
@@ -514,8 +527,31 @@ unconditionally and is always safe to run.
|
|
|
514
527
|
|
|
515
528
|
### The hotkey does nothing
|
|
516
529
|
|
|
530
|
+
**If you installed the app** (`vocalize app install`), start with:
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
vocalize app status
|
|
534
|
+
```
|
|
535
|
+
|
|
517
536
|
In rough order of likelihood:
|
|
518
537
|
|
|
538
|
+
1. **`agent: not running`.** The LaunchAgent isn't loaded. Run
|
|
539
|
+
`vocalize app install` again, or `vocalize app restart` if it was
|
|
540
|
+
loaded a moment ago.
|
|
541
|
+
2. **`accessibility: not granted`.** Grant it in System Settings ›
|
|
542
|
+
Privacy & Security › Accessibility. A rebuild resets this grant — see
|
|
543
|
+
[docs/app.md](app.md#the-re-grant-rule).
|
|
544
|
+
3. **`hotkeys: failed:<name>`.** That chord is already claimed by
|
|
545
|
+
another app — Hammerspoon and the old Quick Action are the two this
|
|
546
|
+
project itself might have left behind; see
|
|
547
|
+
[docs/app.md](app.md#conflicts-hammerspoon-and-the-old-quick-action).
|
|
548
|
+
4. **`bundle: stale` or `not built`.** Run `vocalize app install`.
|
|
549
|
+
5. **Speech-to-text was never installed.** `vocalize listen --check` will
|
|
550
|
+
say so plainly (exit 1).
|
|
551
|
+
|
|
552
|
+
**If you installed the Quick Action** (`hooks/install_quick_action.py`)
|
|
553
|
+
instead:
|
|
554
|
+
|
|
519
555
|
1. **No shortcut is assigned yet**, or it's assigned to something else.
|
|
520
556
|
Check System Settings › Keyboard › Keyboard Shortcuts › Services ›
|
|
521
557
|
Text › "Dictate with Vocalize" — if it isn't listed at all, re-run
|
|
@@ -533,7 +569,7 @@ In rough order of likelihood:
|
|
|
533
569
|
cause for a no-input Service like this one.
|
|
534
570
|
|
|
535
571
|
`vocalize dictate` from a plain terminal isolates whether the problem is
|
|
536
|
-
the hotkey
|
|
572
|
+
the hotkey layer or dictation itself — if that works, the app or Quick
|
|
537
573
|
Action installation is where to look next.
|
|
538
574
|
|
|
539
575
|
### Rebuilds and re-granting the microphone
|