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.
Files changed (42) hide show
  1. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/CHANGELOG.md +9 -0
  2. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/PKG-INFO +5 -1
  3. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/README.md +4 -0
  4. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/install_quick_action.py +5 -1
  5. vocalize_cli-0.7.1/hooks/quick_actions/Speak Latest Plan.workflow/Contents/Info.plist +26 -0
  6. vocalize_cli-0.7.1/hooks/quick_actions/Speak Latest Plan.workflow/Contents/Resources/document.wflow +209 -0
  7. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_install_quick_action.py +13 -0
  8. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/__init__.py +1 -1
  9. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/.env.example +0 -0
  10. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/.github/workflows/ci.yml +0 -0
  11. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/.gitignore +0 -0
  12. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/LICENSE +0 -0
  13. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/claude_stop_hook.py +0 -0
  14. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/install_hook.py +0 -0
  15. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/quick_actions/Speak with Vocalize.workflow/Contents/Info.plist +0 -0
  16. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/quick_actions/Speak with Vocalize.workflow/Contents/Resources/document.wflow +0 -0
  17. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/quick_actions/Stop Vocalize.workflow/Contents/Info.plist +0 -0
  18. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/quick_actions/Stop Vocalize.workflow/Contents/Resources/document.wflow +0 -0
  19. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/hooks/speak_url_gate.py +0 -0
  20. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/pyproject.toml +0 -0
  21. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/conftest.py +0 -0
  22. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_audio.py +0 -0
  23. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_auth.py +0 -0
  24. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_claude_stop_hook.py +0 -0
  25. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_cli.py +0 -0
  26. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_clipboard.py +0 -0
  27. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_config.py +0 -0
  28. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_install_hook.py +0 -0
  29. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_preprocess.py +0 -0
  30. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_speak_url_gate.py +0 -0
  31. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_tts.py +0 -0
  32. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/tests/test_wizard.py +0 -0
  33. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/__main__.py +0 -0
  34. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/audio.py +0 -0
  35. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/auth.py +0 -0
  36. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/cli.py +0 -0
  37. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/clipboard.py +0 -0
  38. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/config.py +0 -0
  39. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/exceptions.py +0 -0
  40. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/preprocess.py +0 -0
  41. {vocalize_cli-0.7.0 → vocalize_cli-0.7.1}/vocalize/tts.py +0 -0
  42. {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.0
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 = ("Speak with Vocalize.workflow", "Stop Vocalize.workflow")
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>
@@ -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&gt;/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 &gt;/dev/null 2&gt;&amp;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
@@ -7,4 +7,4 @@ formatting into something that actually sounds good spoken aloud
7
7
  which is close to useless).
8
8
  """
9
9
 
10
- __version__ = "0.7.0"
10
+ __version__ = "0.7.1"
File without changes
File without changes
File without changes