@settinghead/pi-voxlert 0.1.0 → 0.2.0
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.
- package/README.md +9 -5
- package/extensions/voxlert.ts +86 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,14 +9,17 @@ Voice notifications for [pi](https://github.com/badlogic/pi) powered by [Voxlert
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
# 1. Install the Voxlert CLI (one-time)
|
|
13
|
-
npm install -g @settinghead/voxlert
|
|
14
|
-
voxlert setup
|
|
15
|
-
|
|
16
|
-
# 2. Install the pi package
|
|
17
12
|
pi install npm:@settinghead/pi-voxlert
|
|
18
13
|
```
|
|
19
14
|
|
|
15
|
+
That's it. On first session, the extension detects that the Voxlert CLI is missing and offers to install + configure it automatically:
|
|
16
|
+
|
|
17
|
+
- Installs `@settinghead/voxlert` globally
|
|
18
|
+
- Downloads default voice packs (SHODAN, Adjutant, Kerrigan, etc.)
|
|
19
|
+
- Auto-detects your TTS backend (Qwen3-TTS on Apple Silicon, Chatterbox on CUDA)
|
|
20
|
+
|
|
21
|
+
You can also trigger setup manually anytime with `/voxlert setup`, or run `voxlert setup` in a terminal for full interactive configuration.
|
|
22
|
+
|
|
20
23
|
## What it does
|
|
21
24
|
|
|
22
25
|
| pi event | Voxlert action |
|
|
@@ -30,6 +33,7 @@ Phrases are generated per-event by an LLM, so you hear things like *"Pathetic au
|
|
|
30
33
|
|
|
31
34
|
| Command | Description |
|
|
32
35
|
|---------|-------------|
|
|
36
|
+
| `/voxlert setup` | Install CLI + configure with defaults |
|
|
33
37
|
| `/voxlert test` | Fire a test voice notification |
|
|
34
38
|
| `/voxlert status` | Check if Voxlert CLI is available |
|
|
35
39
|
| `/voxlert` | Show help |
|
package/extensions/voxlert.ts
CHANGED
|
@@ -95,15 +95,80 @@ export default function (pi: ExtensionAPI) {
|
|
|
95
95
|
let available = isVoxlertAvailable();
|
|
96
96
|
|
|
97
97
|
// ------------------------------------------------------------------
|
|
98
|
-
//
|
|
98
|
+
// Guided setup: install CLI + run setup --yes
|
|
99
|
+
// ------------------------------------------------------------------
|
|
100
|
+
async function runGuidedSetup(ctx: any): Promise<boolean> {
|
|
101
|
+
// Step 1: Install the CLI
|
|
102
|
+
ctx.ui.notify("Installing @settinghead/voxlert...", "info");
|
|
103
|
+
const install = await pi.exec("npm", ["install", "-g", "@settinghead/voxlert"], {
|
|
104
|
+
timeout: 120_000,
|
|
105
|
+
});
|
|
106
|
+
if (install.code !== 0) {
|
|
107
|
+
ctx.ui.notify(
|
|
108
|
+
`Install failed (exit ${install.code}):\n${install.stderr.slice(0, 300)}`,
|
|
109
|
+
"error",
|
|
110
|
+
);
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Step 2: Run non-interactive setup (downloads voice packs, detects TTS)
|
|
115
|
+
ctx.ui.notify("Running voxlert setup (downloading voice packs, detecting TTS)...", "info");
|
|
116
|
+
const setup = await pi.exec("voxlert", ["setup", "--yes"], { timeout: 120_000 });
|
|
117
|
+
if (setup.code !== 0) {
|
|
118
|
+
ctx.ui.notify(
|
|
119
|
+
`Setup failed (exit ${setup.code}):\n${setup.stderr.slice(0, 300)}`,
|
|
120
|
+
"error",
|
|
121
|
+
);
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Verify it worked
|
|
126
|
+
available = isVoxlertAvailable();
|
|
127
|
+
if (available) {
|
|
128
|
+
ctx.ui.notify(
|
|
129
|
+
"Voxlert installed and configured!\n\n" +
|
|
130
|
+
"Voice notifications will now play when the agent finishes a task.\n" +
|
|
131
|
+
"Run /voxlert test to hear it, or 'voxlert setup' in a terminal for full interactive config.",
|
|
132
|
+
"info",
|
|
133
|
+
);
|
|
134
|
+
ctx.ui.setStatus("voxlert", "🔊 Voxlert");
|
|
135
|
+
return true;
|
|
136
|
+
} else {
|
|
137
|
+
ctx.ui.notify("Install succeeded but voxlert binary not found in PATH.", "error");
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ------------------------------------------------------------------
|
|
143
|
+
// Session start: verify Voxlert is installed, offer setup if not
|
|
99
144
|
// ------------------------------------------------------------------
|
|
100
145
|
pi.on("session_start", async (_event, ctx) => {
|
|
101
146
|
available = isVoxlertAvailable();
|
|
102
147
|
if (!available) {
|
|
103
|
-
ctx.
|
|
104
|
-
|
|
105
|
-
|
|
148
|
+
if (!ctx.hasUI) {
|
|
149
|
+
// Non-interactive mode (print mode, JSON mode) — just warn
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const install = await ctx.ui.confirm(
|
|
154
|
+
"Voxlert Setup",
|
|
155
|
+
"Voxlert CLI not found. Install it now?\n\n" +
|
|
156
|
+
"This will:\n" +
|
|
157
|
+
" • npm install -g @settinghead/voxlert\n" +
|
|
158
|
+
" • Download default voice packs (SHODAN, Adjutant, etc.)\n" +
|
|
159
|
+
" • Auto-detect your TTS backend\n\n" +
|
|
160
|
+
"You can run full interactive setup later with: voxlert setup",
|
|
106
161
|
);
|
|
162
|
+
|
|
163
|
+
if (install) {
|
|
164
|
+
await runGuidedSetup(ctx);
|
|
165
|
+
} else {
|
|
166
|
+
ctx.ui.notify(
|
|
167
|
+
"Skipped. Run /voxlert setup anytime, or manually:\n" +
|
|
168
|
+
" npm install -g @settinghead/voxlert && voxlert setup",
|
|
169
|
+
"info",
|
|
170
|
+
);
|
|
171
|
+
}
|
|
107
172
|
} else {
|
|
108
173
|
ctx.ui.setStatus("voxlert", "🔊 Voxlert");
|
|
109
174
|
}
|
|
@@ -168,9 +233,21 @@ export default function (pi: ExtensionAPI) {
|
|
|
168
233
|
handler: async (args, ctx) => {
|
|
169
234
|
const sub = (args || "").trim().split(/\s+/)[0];
|
|
170
235
|
|
|
236
|
+
if (sub === "setup") {
|
|
237
|
+
if (available) {
|
|
238
|
+
const redo = await ctx.ui.confirm(
|
|
239
|
+
"Voxlert Setup",
|
|
240
|
+
"Voxlert is already installed. Re-run setup with defaults?",
|
|
241
|
+
);
|
|
242
|
+
if (!redo) return;
|
|
243
|
+
}
|
|
244
|
+
await runGuidedSetup(ctx);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
171
248
|
if (sub === "test") {
|
|
172
249
|
if (!available) {
|
|
173
|
-
ctx.ui.notify("Voxlert CLI not installed.", "error");
|
|
250
|
+
ctx.ui.notify("Voxlert CLI not installed. Run /voxlert setup first.", "error");
|
|
174
251
|
return;
|
|
175
252
|
}
|
|
176
253
|
fireVoxlert("Stop", ctx.cwd);
|
|
@@ -182,7 +259,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
182
259
|
ctx.ui.notify(
|
|
183
260
|
available
|
|
184
261
|
? "Voxlert is active. Voice notifications will play on agent_end, tool errors, compaction, and session end."
|
|
185
|
-
: "Voxlert CLI not found. Run
|
|
262
|
+
: "Voxlert CLI not found. Run /voxlert setup to install.",
|
|
186
263
|
available ? "info" : "warning",
|
|
187
264
|
);
|
|
188
265
|
return;
|
|
@@ -190,10 +267,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
190
267
|
|
|
191
268
|
// Default: show help
|
|
192
269
|
ctx.ui.notify(
|
|
193
|
-
"Usage: /voxlert [test|status]\n" +
|
|
270
|
+
"Usage: /voxlert [setup|test|status]\n" +
|
|
271
|
+
" setup — install Voxlert CLI and configure with defaults\n" +
|
|
194
272
|
" test — fire a test voice notification\n" +
|
|
195
273
|
" status — check if Voxlert CLI is available\n" +
|
|
196
|
-
"\
|
|
274
|
+
"\nFor full interactive config, run in terminal: voxlert setup",
|
|
197
275
|
"info",
|
|
198
276
|
);
|
|
199
277
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@settinghead/pi-voxlert",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "SHODAN, the StarCraft Adjutant, and GLaDOS narrate your pi coding sessions. LLM-generated voice notifications spoken by game characters — know which agent needs you, by ear.",
|
|
5
5
|
"keywords": ["pi-package", "voxlert", "voice-notifications", "tts", "coding-agent", "notifications", "audio"],
|
|
6
6
|
"repository": {
|