@pi-unipi/notify 2.3.0 → 2.4.1
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 +2 -0
- package/events.ts +23 -13
- package/package.json +2 -2
- package/tools.ts +17 -8
- package/types.ts +5 -1
package/README.md
CHANGED
|
@@ -47,6 +47,8 @@ notify_user({
|
|
|
47
47
|
})
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
An explicit semantic priority overrides configured urgency for that dispatch on platforms that support it: `low`/`normal`/`high` map to Gotify `2`/`5`/`8` and ntfy `2`/`3`/`5`. Native and Telegram have no priority input and ignore it. When omitted, Gotify and ntfy retain their configured numeric priorities.
|
|
51
|
+
|
|
50
52
|
## Platforms
|
|
51
53
|
|
|
52
54
|
### Native OS
|
package/events.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
9
9
|
import { UNIPI_EVENTS, emitEvent } from "@pi-unipi/core";
|
|
10
|
-
import type { NotifyConfig, NotifyPlatform, NotifyDispatchResult } from "./types.js";
|
|
10
|
+
import type { NotifyConfig, NotifyPlatform, NotifyDispatchResult, NotifyPriority } from "./types.js";
|
|
11
11
|
import { loadNtfyConfig } from "./ntfy-config.js";
|
|
12
12
|
import { sendNativeNotification, SuppressedError } from "./platforms/native.js";
|
|
13
13
|
import { sendGotifyNotification } from "./platforms/gotify.js";
|
|
@@ -170,7 +170,8 @@ export async function dispatchNotification(
|
|
|
170
170
|
eventPlatforms: NotifyPlatform[],
|
|
171
171
|
eventType: string,
|
|
172
172
|
config: NotifyConfig,
|
|
173
|
-
cwd: string
|
|
173
|
+
cwd: string,
|
|
174
|
+
priority?: NotifyPriority,
|
|
174
175
|
): Promise<NotifyDispatchResult> {
|
|
175
176
|
// Resolve ntfy config from project/global ntfy.json
|
|
176
177
|
const ntfyConfig = loadNtfyConfig(cwd);
|
|
@@ -194,8 +195,8 @@ export async function dispatchNotification(
|
|
|
194
195
|
const results = await Promise.all(
|
|
195
196
|
enabledPlatforms.map(async (platform) => {
|
|
196
197
|
try {
|
|
197
|
-
await sendToPlatform(platform, title, message, config, cwd);
|
|
198
|
-
return { platform, success: true };
|
|
198
|
+
const effectivePriority = await sendToPlatform(platform, title, message, config, cwd, priority);
|
|
199
|
+
return { platform, success: true, ...(effectivePriority === undefined ? {} : { priority: effectivePriority }) };
|
|
199
200
|
} catch (err) {
|
|
200
201
|
// SuppressedError is intentional, not a failure
|
|
201
202
|
if (err instanceof SuppressedError) {
|
|
@@ -230,20 +231,29 @@ export async function dispatchNotification(
|
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
/** Send to a single platform */
|
|
234
|
+
export function mapNotifyPriority(platform: "gotify" | "ntfy", priority: NotifyPriority): number {
|
|
235
|
+
const mappings = {
|
|
236
|
+
gotify: { low: 2, normal: 5, high: 8 },
|
|
237
|
+
ntfy: { low: 2, normal: 3, high: 5 },
|
|
238
|
+
} as const;
|
|
239
|
+
return mappings[platform][priority];
|
|
240
|
+
}
|
|
241
|
+
|
|
233
242
|
async function sendToPlatform(
|
|
234
243
|
platform: NotifyPlatform,
|
|
235
244
|
title: string,
|
|
236
245
|
message: string,
|
|
237
246
|
config: NotifyConfig,
|
|
238
|
-
cwd: string
|
|
239
|
-
|
|
247
|
+
cwd: string,
|
|
248
|
+
priority?: NotifyPriority,
|
|
249
|
+
): Promise<number | undefined> {
|
|
240
250
|
switch (platform) {
|
|
241
251
|
case "native":
|
|
242
252
|
await sendNativeNotification(title, message, {
|
|
243
253
|
windowsAppId: config.native.windowsAppId,
|
|
244
254
|
suppressWhenFocused: config.native.suppressWhenFocused,
|
|
245
255
|
});
|
|
246
|
-
|
|
256
|
+
return undefined;
|
|
247
257
|
case "gotify":
|
|
248
258
|
if (!config.gotify.serverUrl || !config.gotify.appToken) {
|
|
249
259
|
throw new Error("Gotify: serverUrl and appToken are required");
|
|
@@ -253,9 +263,9 @@ async function sendToPlatform(
|
|
|
253
263
|
config.gotify.appToken,
|
|
254
264
|
title,
|
|
255
265
|
message,
|
|
256
|
-
config.gotify.priority
|
|
266
|
+
priority ? mapNotifyPriority("gotify", priority) : config.gotify.priority
|
|
257
267
|
);
|
|
258
|
-
|
|
268
|
+
return priority ? mapNotifyPriority("gotify", priority) : config.gotify.priority;
|
|
259
269
|
case "telegram":
|
|
260
270
|
if (!config.telegram.botToken || !config.telegram.chatId) {
|
|
261
271
|
throw new Error("Telegram: botToken and chatId are required");
|
|
@@ -266,10 +276,10 @@ async function sendToPlatform(
|
|
|
266
276
|
title,
|
|
267
277
|
message
|
|
268
278
|
);
|
|
269
|
-
|
|
279
|
+
return undefined;
|
|
270
280
|
case "ntfy": {
|
|
271
281
|
const ntfyConfig = loadNtfyConfig(cwd);
|
|
272
|
-
if (!ntfyConfig.enabled) return;
|
|
282
|
+
if (!ntfyConfig.enabled) return undefined;
|
|
273
283
|
if (!ntfyConfig.serverUrl || !ntfyConfig.topic) {
|
|
274
284
|
throw new Error("ntfy: serverUrl and topic are required");
|
|
275
285
|
}
|
|
@@ -278,10 +288,10 @@ async function sendToPlatform(
|
|
|
278
288
|
ntfyConfig.topic,
|
|
279
289
|
title,
|
|
280
290
|
message,
|
|
281
|
-
ntfyConfig.priority,
|
|
291
|
+
priority ? mapNotifyPriority("ntfy", priority) : ntfyConfig.priority,
|
|
282
292
|
ntfyConfig.token
|
|
283
293
|
);
|
|
284
|
-
|
|
294
|
+
return priority ? mapNotifyPriority("ntfy", priority) : ntfyConfig.priority;
|
|
285
295
|
}
|
|
286
296
|
}
|
|
287
297
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/notify",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "Cross-platform notification extension for Pi — native OS, Gotify, and Telegram notifications for agent lifecycle events",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@pi-unipi/core": "2.
|
|
37
|
+
"@pi-unipi/core": "2.4.1",
|
|
38
38
|
"node-notifier": "^10.0.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
package/tools.ts
CHANGED
|
@@ -8,7 +8,8 @@ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-a
|
|
|
8
8
|
import { Type } from "typebox";
|
|
9
9
|
import { NOTIFY_TOOLS } from "@pi-unipi/core";
|
|
10
10
|
import { loadConfig } from "./settings.js";
|
|
11
|
-
import { dispatchNotification } from "./events.js";
|
|
11
|
+
import { dispatchNotification, mapNotifyPriority } from "./events.js";
|
|
12
|
+
import type { NotifyPriority } from "./types.js";
|
|
12
13
|
|
|
13
14
|
/** Schema for notify_user tool parameters */
|
|
14
15
|
const NotifyUserSchema = Type.Object({
|
|
@@ -19,7 +20,6 @@ const NotifyUserSchema = Type.Object({
|
|
|
19
20
|
priority: Type.Optional(
|
|
20
21
|
Type.String({
|
|
21
22
|
enum: ["low", "normal", "high"],
|
|
22
|
-
default: "normal",
|
|
23
23
|
description: "Priority level",
|
|
24
24
|
})
|
|
25
25
|
),
|
|
@@ -46,12 +46,12 @@ export function registerNotifyTools(pi: ExtensionAPI): void {
|
|
|
46
46
|
const {
|
|
47
47
|
message,
|
|
48
48
|
title,
|
|
49
|
-
priority
|
|
49
|
+
priority,
|
|
50
50
|
platforms,
|
|
51
51
|
} = params as {
|
|
52
52
|
message: string;
|
|
53
53
|
title?: string;
|
|
54
|
-
priority?:
|
|
54
|
+
priority?: NotifyPriority;
|
|
55
55
|
platforms?: Array<"native" | "gotify" | "telegram" | "ntfy">;
|
|
56
56
|
};
|
|
57
57
|
|
|
@@ -65,18 +65,27 @@ export function registerNotifyTools(pi: ExtensionAPI): void {
|
|
|
65
65
|
|
|
66
66
|
// Fire-and-forget: dispatch in background so the tool doesn't block the agent
|
|
67
67
|
const cwd = process.cwd();
|
|
68
|
-
dispatchNotification(
|
|
68
|
+
const dispatchPromise = dispatchNotification(
|
|
69
69
|
pi,
|
|
70
70
|
notifTitle,
|
|
71
71
|
message,
|
|
72
72
|
notifPlatforms,
|
|
73
73
|
"agent_tool",
|
|
74
74
|
config,
|
|
75
|
-
cwd
|
|
76
|
-
|
|
75
|
+
cwd,
|
|
76
|
+
priority,
|
|
77
|
+
);
|
|
78
|
+
void dispatchPromise.catch(() => {
|
|
77
79
|
// Silently ignore — background dispatch failure is non-blocking.
|
|
78
80
|
});
|
|
79
81
|
|
|
82
|
+
const priorityByPlatform = priority ? Object.fromEntries(
|
|
83
|
+
notifPlatforms.flatMap((platform) => {
|
|
84
|
+
if (platform === "gotify" || platform === "ntfy") return [[platform, mapNotifyPriority(platform, priority)]];
|
|
85
|
+
return [];
|
|
86
|
+
}),
|
|
87
|
+
) : undefined;
|
|
88
|
+
|
|
80
89
|
return {
|
|
81
90
|
content: [
|
|
82
91
|
{
|
|
@@ -84,7 +93,7 @@ export function registerNotifyTools(pi: ExtensionAPI): void {
|
|
|
84
93
|
text: `Notification sending to ${notifPlatforms.length} platform(s): ${notifPlatforms.join(", ")}`,
|
|
85
94
|
},
|
|
86
95
|
],
|
|
87
|
-
details: { platforms: notifPlatforms },
|
|
96
|
+
details: { platforms: notifPlatforms, priority, priorityByPlatform },
|
|
88
97
|
};
|
|
89
98
|
},
|
|
90
99
|
});
|
package/types.ts
CHANGED
|
@@ -90,13 +90,15 @@ export interface NotifyConfig {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
/** Parameters for the notify_user agent tool */
|
|
93
|
+
export type NotifyPriority = "low" | "normal" | "high";
|
|
94
|
+
|
|
93
95
|
export interface NotifyUserParams {
|
|
94
96
|
/** Notification message body */
|
|
95
97
|
message: string;
|
|
96
98
|
/** Notification title (default: "Pi Notification") */
|
|
97
99
|
title?: string;
|
|
98
100
|
/** Priority level */
|
|
99
|
-
priority?:
|
|
101
|
+
priority?: NotifyPriority;
|
|
100
102
|
/** Override platforms for this notification */
|
|
101
103
|
platforms?: NotifyPlatform[];
|
|
102
104
|
}
|
|
@@ -109,6 +111,8 @@ export interface NotifyResult {
|
|
|
109
111
|
success: boolean;
|
|
110
112
|
/** True when the notification was intentionally suppressed (e.g. window focused) */
|
|
111
113
|
suppressed?: boolean;
|
|
114
|
+
/** Effective numeric priority for platforms that support it. */
|
|
115
|
+
priority?: number;
|
|
112
116
|
/** Error message if failed */
|
|
113
117
|
error?: string;
|
|
114
118
|
}
|