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 +8 -0
- package/package.json +74 -74
- package/src/agent-dir.ts +32 -32
- package/src/ai-messages.ts +23 -4
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.
|
|
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.
|
|
70
|
-
},
|
|
71
|
-
"devDependencies": {
|
|
72
|
-
"@types/node": "25.9.
|
|
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
|
+
}
|
package/src/ai-messages.ts
CHANGED
|
@@ -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)
|
|
256
|
-
|
|
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
|
-
|
|
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> {
|