vocalize-cli 0.7.0__tar.gz → 0.7.1__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.7.0 → vocalize_cli-0.7.1}/CHANGELOG.md +9 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/PKG-INFO +5 -1
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/README.md +4 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/install_quick_action.py +5 -1
- vocalize_cli-0.7.1/hooks/quick_actions/Speak Latest Plan.workflow/Contents/Info.plist +26 -0
- vocalize_cli-0.7.1/hooks/quick_actions/Speak Latest Plan.workflow/Contents/Resources/document.wflow +209 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_install_quick_action.py +13 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/__init__.py +1 -1
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/.env.example +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/.github/workflows/ci.yml +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/.gitignore +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/LICENSE +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/claude_stop_hook.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/install_hook.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/quick_actions/Speak with Vocalize.workflow/Contents/Info.plist +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/quick_actions/Speak with Vocalize.workflow/Contents/Resources/document.wflow +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/quick_actions/Stop Vocalize.workflow/Contents/Info.plist +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/quick_actions/Stop Vocalize.workflow/Contents/Resources/document.wflow +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/speak_url_gate.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/pyproject.toml +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/conftest.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_audio.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_auth.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_claude_stop_hook.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_cli.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_clipboard.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_config.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_install_hook.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_preprocess.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_speak_url_gate.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_tts.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_wizard.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/__main__.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/audio.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/auth.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/cli.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/clipboard.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/config.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/exceptions.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/preprocess.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/tts.py +0 -0
- {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/wizard.py +0 -0
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
All notable changes to this project are documented here. Format follows
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
5
|
|
|
6
|
+
## 0.7.1 - 2026-08-31
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- "Speak Latest Plan" Quick Action — a no-input Service that speaks the
|
|
11
|
+
newest plan under `~/.claude/plans/` on demand (dialog-asks when over
|
|
12
|
+
the cap). For hearing a Claude Code plan proposal before accepting it;
|
|
13
|
+
installed by the same `hooks/install_quick_action.py`.
|
|
14
|
+
|
|
6
15
|
## 0.7.0 - 2026-08-31
|
|
7
16
|
|
|
8
17
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vocalize-cli
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: A CLI that turns text, markdown, or piped stdin into speech via the ElevenLabs API, with markdown-table-aware preprocessing.
|
|
5
5
|
Project-URL: Homepage, https://github.com/matthager12-collab/vocalize
|
|
6
6
|
Project-URL: Repository, https://github.com/matthager12-collab/vocalize
|
|
@@ -263,6 +263,10 @@ Two Services let you use vocalize from any app without a terminal:
|
|
|
263
263
|
Cancel (that's the `--ask-dialog` flag at work).
|
|
264
264
|
- **Stop Vocalize** — appears in every app's application menu → Services;
|
|
265
265
|
silences playback from anywhere.
|
|
266
|
+
- **Speak Latest Plan** — reads the newest Claude Code plan file
|
|
267
|
+
(`~/.claude/plans/`) aloud on demand. Made for the plan-approval moment:
|
|
268
|
+
the proposal card is up, you press your shortcut, hear the plan, then
|
|
269
|
+
accept or reject. Nothing reads unless you trigger it.
|
|
266
270
|
|
|
267
271
|
Install both:
|
|
268
272
|
|
|
@@ -229,6 +229,10 @@ Two Services let you use vocalize from any app without a terminal:
|
|
|
229
229
|
Cancel (that's the `--ask-dialog` flag at work).
|
|
230
230
|
- **Stop Vocalize** — appears in every app's application menu → Services;
|
|
231
231
|
silences playback from anywhere.
|
|
232
|
+
- **Speak Latest Plan** — reads the newest Claude Code plan file
|
|
233
|
+
(`~/.claude/plans/`) aloud on demand. Made for the plan-approval moment:
|
|
234
|
+
the proposal card is up, you press your shortcut, hear the plan, then
|
|
235
|
+
accept or reject. Nothing reads unless you trigger it.
|
|
232
236
|
|
|
233
237
|
Install both:
|
|
234
238
|
|
|
@@ -17,7 +17,11 @@ from xml.sax.saxutils import escape as xml_escape
|
|
|
17
17
|
|
|
18
18
|
TEMPLATES_DIR = Path(__file__).resolve().parent / "quick_actions"
|
|
19
19
|
SERVICES_DIR = Path.home() / "Library" / "Services"
|
|
20
|
-
BUNDLE_NAMES = (
|
|
20
|
+
BUNDLE_NAMES = (
|
|
21
|
+
"Speak with Vocalize.workflow",
|
|
22
|
+
"Stop Vocalize.workflow",
|
|
23
|
+
"Speak Latest Plan.workflow",
|
|
24
|
+
)
|
|
21
25
|
PLACEHOLDER = "__VOCALIZE_BIN__"
|
|
22
26
|
PBS = "/System/Library/CoreServices/pbs"
|
|
23
27
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>NSServices</key>
|
|
6
|
+
<array>
|
|
7
|
+
<dict>
|
|
8
|
+
<key>NSMenuItem</key>
|
|
9
|
+
<dict>
|
|
10
|
+
<key>default</key>
|
|
11
|
+
<string>Speak Latest Plan</string>
|
|
12
|
+
</dict>
|
|
13
|
+
<key>NSMessage</key>
|
|
14
|
+
<string>runWorkflowAsService</string>
|
|
15
|
+
</dict>
|
|
16
|
+
</array>
|
|
17
|
+
<key>CFBundleDevelopmentRegion</key>
|
|
18
|
+
<string>en_US</string>
|
|
19
|
+
<key>CFBundleIdentifier</key>
|
|
20
|
+
<string>cards.arda.vocalize.speakplan</string>
|
|
21
|
+
<key>CFBundleName</key>
|
|
22
|
+
<string>Speak Latest Plan</string>
|
|
23
|
+
<key>CFBundleShortVersionString</key>
|
|
24
|
+
<string>1.0</string>
|
|
25
|
+
</dict>
|
|
26
|
+
</plist>
|
vocalize_cli-0.7.1/hooks/quick_actions/Speak Latest Plan.workflow/Contents/Resources/document.wflow
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>AMApplicationBuild</key>
|
|
6
|
+
<string>346</string>
|
|
7
|
+
<key>AMApplicationVersion</key>
|
|
8
|
+
<string>2.3</string>
|
|
9
|
+
<key>AMDocumentVersion</key>
|
|
10
|
+
<string>2</string>
|
|
11
|
+
<key>actions</key>
|
|
12
|
+
<array>
|
|
13
|
+
<dict>
|
|
14
|
+
<key>action</key>
|
|
15
|
+
<dict>
|
|
16
|
+
<key>AMAccepts</key>
|
|
17
|
+
<dict>
|
|
18
|
+
<key>Container</key>
|
|
19
|
+
<string>List</string>
|
|
20
|
+
<key>Optional</key>
|
|
21
|
+
<true/>
|
|
22
|
+
<key>Types</key>
|
|
23
|
+
<array>
|
|
24
|
+
<string>com.apple.cocoa.string</string>
|
|
25
|
+
</array>
|
|
26
|
+
</dict>
|
|
27
|
+
<key>AMActionVersion</key>
|
|
28
|
+
<string>2.0.3</string>
|
|
29
|
+
<key>AMApplication</key>
|
|
30
|
+
<array>
|
|
31
|
+
<string>Automator</string>
|
|
32
|
+
</array>
|
|
33
|
+
<key>AMParameterProperties</key>
|
|
34
|
+
<dict>
|
|
35
|
+
<key>COMMAND_STRING</key>
|
|
36
|
+
<dict/>
|
|
37
|
+
<key>CheckedForUserDefaultShell</key>
|
|
38
|
+
<dict/>
|
|
39
|
+
<key>inputMethod</key>
|
|
40
|
+
<dict/>
|
|
41
|
+
<key>shell</key>
|
|
42
|
+
<dict/>
|
|
43
|
+
<key>source</key>
|
|
44
|
+
<dict/>
|
|
45
|
+
</dict>
|
|
46
|
+
<key>AMProvides</key>
|
|
47
|
+
<dict>
|
|
48
|
+
<key>Container</key>
|
|
49
|
+
<string>List</string>
|
|
50
|
+
<key>Types</key>
|
|
51
|
+
<array>
|
|
52
|
+
<string>com.apple.cocoa.string</string>
|
|
53
|
+
</array>
|
|
54
|
+
</dict>
|
|
55
|
+
<key>ActionBundlePath</key>
|
|
56
|
+
<string>/System/Library/Automator/Run Shell Script.action</string>
|
|
57
|
+
<key>ActionName</key>
|
|
58
|
+
<string>Run Shell Script</string>
|
|
59
|
+
<key>ActionParameters</key>
|
|
60
|
+
<dict>
|
|
61
|
+
<key>COMMAND_STRING</key>
|
|
62
|
+
<string># No input: speak the newest Claude Code plan file on demand.
|
|
63
|
+
BIN="__VOCALIZE_BIN__"
|
|
64
|
+
if [[ ! -x "$BIN" ]]; then
|
|
65
|
+
/usr/bin/osascript -e 'display notification "vocalize not found — re-run hooks/install_quick_action.py" with title "Vocalize"'
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
PLAN=$(ls -t "$HOME/.claude/plans"/*.md 2>/dev/null | head -1)
|
|
69
|
+
if [[ -z "$PLAN" ]]; then
|
|
70
|
+
/usr/bin/osascript -e 'display notification "No plan files found in ~/.claude/plans." with title "Vocalize"'
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
"$BIN" stop >/dev/null 2>&1
|
|
74
|
+
exec "$BIN" speak-file "$PLAN" --play --ask-dialog</string>
|
|
75
|
+
<key>CheckedForUserDefaultShell</key>
|
|
76
|
+
<false/>
|
|
77
|
+
<key>inputMethod</key>
|
|
78
|
+
<integer>1</integer>
|
|
79
|
+
<key>shell</key>
|
|
80
|
+
<string>/bin/zsh</string>
|
|
81
|
+
<key>source</key>
|
|
82
|
+
<string></string>
|
|
83
|
+
</dict>
|
|
84
|
+
<key>BundleIdentifier</key>
|
|
85
|
+
<string>com.apple.RunShellScript</string>
|
|
86
|
+
<key>CFBundleVersion</key>
|
|
87
|
+
<string>2.0.3</string>
|
|
88
|
+
<key>CanShowSelectedItemsWhenRun</key>
|
|
89
|
+
<false/>
|
|
90
|
+
<key>CanShowWhenRun</key>
|
|
91
|
+
<true/>
|
|
92
|
+
<key>Category</key>
|
|
93
|
+
<array>
|
|
94
|
+
<string>AMCategoryUtilities</string>
|
|
95
|
+
</array>
|
|
96
|
+
<key>Class Name</key>
|
|
97
|
+
<string>RunShellScriptAction</string>
|
|
98
|
+
<key>InputUUID</key>
|
|
99
|
+
<string>2C7F9E10-55D2-4B31-9A6E-8E0D4C71F301</string>
|
|
100
|
+
<key>Keywords</key>
|
|
101
|
+
<array>
|
|
102
|
+
<string>Shell</string>
|
|
103
|
+
<string>Script</string>
|
|
104
|
+
<string>Command</string>
|
|
105
|
+
<string>Run</string>
|
|
106
|
+
<string>Unix</string>
|
|
107
|
+
</array>
|
|
108
|
+
<key>OutputUUID</key>
|
|
109
|
+
<string>2C7F9E10-55D2-4B31-9A6E-8E0D4C71F302</string>
|
|
110
|
+
<key>UUID</key>
|
|
111
|
+
<string>2C7F9E10-55D2-4B31-9A6E-8E0D4C71F303</string>
|
|
112
|
+
<key>UnlocalizedApplications</key>
|
|
113
|
+
<array>
|
|
114
|
+
<string>Automator</string>
|
|
115
|
+
</array>
|
|
116
|
+
<key>arguments</key>
|
|
117
|
+
<dict>
|
|
118
|
+
<key>0</key>
|
|
119
|
+
<dict>
|
|
120
|
+
<key>default value</key>
|
|
121
|
+
<integer>0</integer>
|
|
122
|
+
<key>name</key>
|
|
123
|
+
<string>inputMethod</string>
|
|
124
|
+
<key>required</key>
|
|
125
|
+
<string>0</string>
|
|
126
|
+
<key>type</key>
|
|
127
|
+
<string>0</string>
|
|
128
|
+
<key>uuid</key>
|
|
129
|
+
<string>0</string>
|
|
130
|
+
</dict>
|
|
131
|
+
<key>1</key>
|
|
132
|
+
<dict>
|
|
133
|
+
<key>default value</key>
|
|
134
|
+
<string></string>
|
|
135
|
+
<key>name</key>
|
|
136
|
+
<string>source</string>
|
|
137
|
+
<key>required</key>
|
|
138
|
+
<string>0</string>
|
|
139
|
+
<key>type</key>
|
|
140
|
+
<string>0</string>
|
|
141
|
+
<key>uuid</key>
|
|
142
|
+
<string>1</string>
|
|
143
|
+
</dict>
|
|
144
|
+
<key>2</key>
|
|
145
|
+
<dict>
|
|
146
|
+
<key>default value</key>
|
|
147
|
+
<false/>
|
|
148
|
+
<key>name</key>
|
|
149
|
+
<string>CheckedForUserDefaultShell</string>
|
|
150
|
+
<key>required</key>
|
|
151
|
+
<string>0</string>
|
|
152
|
+
<key>type</key>
|
|
153
|
+
<string>0</string>
|
|
154
|
+
<key>uuid</key>
|
|
155
|
+
<string>2</string>
|
|
156
|
+
</dict>
|
|
157
|
+
<key>3</key>
|
|
158
|
+
<dict>
|
|
159
|
+
<key>default value</key>
|
|
160
|
+
<string></string>
|
|
161
|
+
<key>name</key>
|
|
162
|
+
<string>COMMAND_STRING</string>
|
|
163
|
+
<key>required</key>
|
|
164
|
+
<string>0</string>
|
|
165
|
+
<key>type</key>
|
|
166
|
+
<string>0</string>
|
|
167
|
+
<key>uuid</key>
|
|
168
|
+
<string>3</string>
|
|
169
|
+
</dict>
|
|
170
|
+
<key>4</key>
|
|
171
|
+
<dict>
|
|
172
|
+
<key>default value</key>
|
|
173
|
+
<string>/bin/sh</string>
|
|
174
|
+
<key>name</key>
|
|
175
|
+
<string>shell</string>
|
|
176
|
+
<key>required</key>
|
|
177
|
+
<string>0</string>
|
|
178
|
+
<key>type</key>
|
|
179
|
+
<string>0</string>
|
|
180
|
+
<key>uuid</key>
|
|
181
|
+
<string>4</string>
|
|
182
|
+
</dict>
|
|
183
|
+
</dict>
|
|
184
|
+
<key>isViewVisible</key>
|
|
185
|
+
<true/>
|
|
186
|
+
</dict>
|
|
187
|
+
<key>isViewVisible</key>
|
|
188
|
+
<true/>
|
|
189
|
+
</dict>
|
|
190
|
+
</array>
|
|
191
|
+
<key>connectors</key>
|
|
192
|
+
<dict/>
|
|
193
|
+
<key>workflowMetaData</key>
|
|
194
|
+
<dict>
|
|
195
|
+
<key>serviceApplicationBundleID</key>
|
|
196
|
+
<string></string>
|
|
197
|
+
<key>serviceApplicationPath</key>
|
|
198
|
+
<string></string>
|
|
199
|
+
<key>serviceInputTypeIdentifier</key>
|
|
200
|
+
<string>com.apple.Automator.nothing</string>
|
|
201
|
+
<key>serviceOutputTypeIdentifier</key>
|
|
202
|
+
<string>com.apple.Automator.nothing</string>
|
|
203
|
+
<key>serviceProcessesInput</key>
|
|
204
|
+
<integer>0</integer>
|
|
205
|
+
<key>workflowTypeIdentifier</key>
|
|
206
|
+
<string>com.apple.Automator.servicesMenu</string>
|
|
207
|
+
</dict>
|
|
208
|
+
</dict>
|
|
209
|
+
</plist>
|
|
@@ -156,3 +156,16 @@ def test_checked_in_stop_bundle_takes_no_stdin():
|
|
|
156
156
|
# inputMethod 1 = as-arguments: a no-input service must not wait on stdin.
|
|
157
157
|
assert params["inputMethod"] == 1
|
|
158
158
|
assert " stop" in params["COMMAND_STRING"]
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def test_checked_in_plan_bundle_speaks_newest_plan_on_demand():
|
|
162
|
+
doc = _real_wflow("Speak Latest Plan.workflow")
|
|
163
|
+
params = doc["actions"][0]["action"]["ActionParameters"]
|
|
164
|
+
script = params["COMMAND_STRING"]
|
|
165
|
+
# No-input service (inputMethod 1), reads the newest plan file, asks
|
|
166
|
+
# via dialog when over the cap, and quotes the resolved path.
|
|
167
|
+
assert params["inputMethod"] == 1
|
|
168
|
+
assert '.claude/plans"/*.md' in script
|
|
169
|
+
assert "--ask-dialog" in script
|
|
170
|
+
assert 'speak-file "$PLAN"' in script
|
|
171
|
+
assert install_quick_action.PLACEHOLDER in script
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|