pi-smart-voice-notify 0.5.2 → 0.5.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased]
4
+
5
+ ## [0.5.3] - 2026-06-16
6
+
7
+ ### Fixed
8
+ - Filtered blank template entries so whitespace-only overrides no longer produce empty notification messages.
9
+ - Added a final fallback (`"Notification: Please check the terminal."`) when all template expansions and defaults yield empty output.
10
+
3
11
  ## [0.5.2] - 2026-06-01
4
12
 
5
13
  ### Changed
package/package.json CHANGED
@@ -1,74 +1,74 @@
1
- {
2
- "name": "pi-smart-voice-notify",
3
- "version": "0.5.2",
4
- "description": "Windows-optimized smart voice, sound, and desktop notifications for Pi coding agent.",
5
- "type": "module",
6
- "main": "./index.ts",
7
- "exports": {
8
- ".": "./index.ts"
9
- },
10
- "files": [
11
- "index.ts",
12
- "src",
13
- "config/config.example.json",
14
- "assets",
15
- "README.md",
16
- "CHANGELOG.md",
17
- "LICENSE"
18
- ],
19
- "scripts": {
20
- "build": "npx --yes -p typescript@5.7.3 -p @types/node@20.17.57 tsc -p tsconfig.json --noEmit",
21
- "lint": "npm run build",
22
- "test": "node --experimental-strip-types --test test/abortable-command.test.ts test/reminder-playback.test.ts test/permission-forwarding-watcher.test.ts test/sound-theme.test.ts test/webhook.test.ts test/linux.test.ts test/index.test.ts test/tts.test.ts",
23
- "check": "npm run build && npm run test"
24
- },
25
- "keywords": [
26
- "pi-package",
27
- "pi",
28
- "pi-extension",
29
- "pi-coding-agent",
30
- "coding-agent",
31
- "voice-notify",
32
- "desktop-notification",
33
- "notifications",
34
- "voice",
35
- "audio",
36
- "text-to-speech",
37
- "tts",
38
- "windows",
39
- "linux",
40
- "macos"
41
- ],
42
- "author": "MasuRii",
43
- "license": "MIT",
44
- "repository": {
45
- "type": "git",
46
- "url": "git+https://github.com/MasuRii/pi-smart-voice-notify.git"
47
- },
48
- "homepage": "https://github.com/MasuRii/pi-smart-voice-notify#readme",
49
- "bugs": {
50
- "url": "https://github.com/MasuRii/pi-smart-voice-notify/issues"
51
- },
52
- "engines": {
53
- "node": ">=24"
54
- },
55
- "publishConfig": {
56
- "access": "public"
57
- },
58
- "pi": {
59
- "extensions": [
60
- "./index.ts"
61
- ]
62
- },
63
- "peerDependencies": {
64
- "@earendil-works/pi-coding-agent": "^0.74.0 || ^0.75.0 || ^0.77.0 || ^0.78.0",
65
- "@earendil-works/pi-tui": "^0.74.0 || ^0.75.0 || ^0.77.0 || ^0.78.0"
66
- },
67
- "dependencies": {
68
- "node-notifier": "^10.0.1",
69
- "undici": "^8.3.0"
70
- },
71
- "devDependencies": {
72
- "@types/node": "25.9.1"
73
- }
74
- }
1
+ {
2
+ "name": "pi-smart-voice-notify",
3
+ "version": "0.5.3",
4
+ "description": "Windows-optimized smart voice, sound, and desktop notifications for Pi coding agent.",
5
+ "type": "module",
6
+ "main": "./index.ts",
7
+ "exports": {
8
+ ".": "./index.ts"
9
+ },
10
+ "files": [
11
+ "index.ts",
12
+ "src",
13
+ "config/config.example.json",
14
+ "assets",
15
+ "README.md",
16
+ "CHANGELOG.md",
17
+ "LICENSE"
18
+ ],
19
+ "scripts": {
20
+ "build": "npx --yes -p typescript@5.7.3 -p @types/node@20.17.57 tsc -p tsconfig.json --noEmit",
21
+ "lint": "npm run build",
22
+ "test": "node --experimental-strip-types --test test/abortable-command.test.ts test/reminder-playback.test.ts test/permission-forwarding-watcher.test.ts test/sound-theme.test.ts test/webhook.test.ts test/linux.test.ts test/index.test.ts test/tts.test.ts",
23
+ "check": "npm run build && npm run test"
24
+ },
25
+ "keywords": [
26
+ "pi-package",
27
+ "pi",
28
+ "pi-extension",
29
+ "pi-coding-agent",
30
+ "coding-agent",
31
+ "voice-notify",
32
+ "desktop-notification",
33
+ "notifications",
34
+ "voice",
35
+ "audio",
36
+ "text-to-speech",
37
+ "tts",
38
+ "windows",
39
+ "linux",
40
+ "macos"
41
+ ],
42
+ "author": "MasuRii",
43
+ "license": "MIT",
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/MasuRii/pi-smart-voice-notify.git"
47
+ },
48
+ "homepage": "https://github.com/MasuRii/pi-smart-voice-notify#readme",
49
+ "bugs": {
50
+ "url": "https://github.com/MasuRii/pi-smart-voice-notify/issues"
51
+ },
52
+ "engines": {
53
+ "node": ">=24"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ },
58
+ "pi": {
59
+ "extensions": [
60
+ "./index.ts"
61
+ ]
62
+ },
63
+ "peerDependencies": {
64
+ "@earendil-works/pi-coding-agent": "^0.74.0 || ^0.75.0 || ^0.77.0 || ^0.78.0 || ^0.79.0",
65
+ "@earendil-works/pi-tui": "^0.74.0 || ^0.75.0 || ^0.77.0 || ^0.78.0 || ^0.79.0"
66
+ },
67
+ "dependencies": {
68
+ "node-notifier": "^10.0.1",
69
+ "undici": "^8.5.0"
70
+ },
71
+ "devDependencies": {
72
+ "@types/node": "25.9.3"
73
+ }
74
+ }
package/src/agent-dir.ts CHANGED
@@ -1,32 +1,32 @@
1
- import { homedir } from "node:os";
2
- import { join } from "node:path";
3
-
4
- const PI_AGENT_DIR_ENV_VAR = "PI_CODING_AGENT_DIR";
5
-
6
- interface AgentDirEnvironment {
7
- [name: string]: string | undefined;
8
- }
9
-
10
- function expandHomeDirectory(configuredDir: string, homeDirectory: string): string {
11
- if (configuredDir === "~") {
12
- return homeDirectory;
13
- }
14
-
15
- if (configuredDir.startsWith("~/") || configuredDir.startsWith("~\\")) {
16
- return join(homeDirectory, configuredDir.slice(2));
17
- }
18
-
19
- return configuredDir;
20
- }
21
-
22
- export function resolvePiAgentDir(
23
- env: AgentDirEnvironment = process.env,
24
- homeDirectory = homedir(),
25
- ): string {
26
- const configuredDir = env[PI_AGENT_DIR_ENV_VAR];
27
- if (!configuredDir) {
28
- return join(homeDirectory, ".pi", "agent");
29
- }
30
-
31
- return expandHomeDirectory(configuredDir, homeDirectory);
32
- }
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+
4
+ const PI_AGENT_DIR_ENV_VAR = "PI_CODING_AGENT_DIR";
5
+
6
+ interface AgentDirEnvironment {
7
+ [name: string]: string | undefined;
8
+ }
9
+
10
+ function expandHomeDirectory(configuredDir: string, homeDirectory: string): string {
11
+ if (configuredDir === "~") {
12
+ return homeDirectory;
13
+ }
14
+
15
+ if (configuredDir.startsWith("~/") || configuredDir.startsWith("~\\")) {
16
+ return join(homeDirectory, configuredDir.slice(2));
17
+ }
18
+
19
+ return configuredDir;
20
+ }
21
+
22
+ export function resolvePiAgentDir(
23
+ env: AgentDirEnvironment = process.env,
24
+ homeDirectory = homedir(),
25
+ ): string {
26
+ const configuredDir = env[PI_AGENT_DIR_ENV_VAR];
27
+ if (!configuredDir) {
28
+ return join(homeDirectory, ".pi", "agent");
29
+ }
30
+
31
+ return expandHomeDirectory(configuredDir, homeDirectory);
32
+ }
@@ -237,6 +237,10 @@ function sanitizeMessage(message: string, maxLength = DEFAULT_MAX_MESSAGE_LENGTH
237
237
  return `${clipped.slice(0, safeBoundary).trimEnd()}...`;
238
238
  }
239
239
 
240
+ function getUsableTemplates(templates: string[]): string[] {
241
+ return templates.filter((template) => template.trim().length > 0);
242
+ }
243
+
240
244
  function pickTemplate(templates: string[]): string {
241
245
  const index = Math.floor(Math.random() * templates.length);
242
246
  return templates[index] ?? templates[0] ?? "Notification";
@@ -252,8 +256,11 @@ function getTemplatesForEvent(eventType: string, config: AIMessageConfig): strin
252
256
  }
253
257
 
254
258
  const overrideTemplates = config.templates[eventType];
255
- if (Array.isArray(overrideTemplates) && overrideTemplates.length > 0) {
256
- return overrideTemplates;
259
+ if (Array.isArray(overrideTemplates)) {
260
+ const usableTemplates = getUsableTemplates(overrideTemplates);
261
+ if (usableTemplates.length > 0) {
262
+ return usableTemplates;
263
+ }
257
264
  }
258
265
  return DEFAULT_TEMPLATES[eventType];
259
266
  }
@@ -317,8 +324,20 @@ export class AIMessageService {
317
324
  const templates = getTemplatesForEvent(eventType, this.config);
318
325
  const template = pickTemplate(templates);
319
326
  const variables = buildTemplateVariables(eventType, context);
320
- const message = applyTemplateVariables(template, variables);
321
- return sanitizeMessage(message);
327
+ const message = sanitizeMessage(applyTemplateVariables(template, variables));
328
+ if (message.length > 0) {
329
+ return message;
330
+ }
331
+
332
+ if (isCoreEventType(eventType)) {
333
+ const fallbackTemplate = pickTemplate(DEFAULT_TEMPLATES[eventType]);
334
+ const fallbackMessage = sanitizeMessage(applyTemplateVariables(fallbackTemplate, variables));
335
+ if (fallbackMessage.length > 0) {
336
+ return fallbackMessage;
337
+ }
338
+ }
339
+
340
+ return "Notification: Please check the terminal.";
322
341
  }
323
342
 
324
343
  public async generateAIMessage(eventType: string, context: AIMessageContext = {}): Promise<string | null> {