@made-by-moonlight/athene-plugin-notifier-desktop 0.9.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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Composio, Inc.
4
+ Copyright (c) 2026 slievr (Athene fork)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,20 @@
1
+ import { type Notifier } from "@made-by-moonlight/athene-core";
2
+ export declare const manifest: {
3
+ name: string;
4
+ slot: "notifier";
5
+ description: string;
6
+ version: string;
7
+ };
8
+ export { escapeAppleScript } from "@made-by-moonlight/athene-core";
9
+ export declare function create(config?: Record<string, unknown>): Notifier;
10
+ declare const _default: {
11
+ manifest: {
12
+ name: string;
13
+ slot: "notifier";
14
+ description: string;
15
+ version: string;
16
+ };
17
+ create: typeof create;
18
+ };
19
+ export default _default;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,KAAK,QAAQ,EAKd,MAAM,gCAAgC,CAAC;AAgCxC,eAAO,MAAM,QAAQ;;;;;CAKpB,CAAC;AAGF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AA+dnE,wBAAgB,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,CA0DjE;;;;;;;;;;AAED,wBAAqE"}
package/dist/index.js ADDED
@@ -0,0 +1,482 @@
1
+ import { execFile, execFileSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { homedir, platform } from "node:os";
4
+ import { join } from "node:path";
5
+ import { escapeAppleScript, getNotificationDataV3, isMac, } from "@made-by-moonlight/athene-core";
6
+ function xmlEscape(s) {
7
+ return s
8
+ .replace(/&/g, "&amp;")
9
+ .replace(/</g, "&lt;")
10
+ .replace(/>/g, "&gt;")
11
+ .replace(/"/g, "&quot;")
12
+ .replace(/'/g, "&apos;");
13
+ }
14
+ function buildWindowsToastScript(title, message, sound) {
15
+ // Build the toast XML — both fields are user content, so XML-escape them.
16
+ const safeTitle = xmlEscape(title);
17
+ const safeMessage = xmlEscape(message);
18
+ const audioNode = sound ? "" : '<audio silent="true" />';
19
+ const xml = `<toast>${audioNode}<visual><binding template="ToastGeneric"><text>${safeTitle}</text><text>${safeMessage}</text></binding></visual></toast>`;
20
+ // PowerShell script — uses WinRT directly (no BurntToast dep). The XML is
21
+ // injected as a single-quoted PS string with embedded apostrophes doubled.
22
+ const psSafeXml = xml.replace(/'/g, "''");
23
+ return [
24
+ "$ErrorActionPreference = 'Stop'",
25
+ "[void][Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]",
26
+ "[void][Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]",
27
+ "$xml = New-Object Windows.Data.Xml.Dom.XmlDocument",
28
+ `$xml.LoadXml('${psSafeXml}')`,
29
+ "$toast = [Windows.UI.Notifications.ToastNotification]::new($xml)",
30
+ "[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Athene').Show($toast)",
31
+ ].join("; ");
32
+ }
33
+ export const manifest = {
34
+ name: "desktop",
35
+ slot: "notifier",
36
+ description: "Notifier plugin: OS desktop notifications",
37
+ version: "0.1.0",
38
+ };
39
+ // Re-export for backwards compatibility
40
+ export { escapeAppleScript } from "@made-by-moonlight/athene-core";
41
+ const PLACEHOLDER_MARKER_NAME = "ao-notifier-placeholder";
42
+ /**
43
+ * Map event priority to notification urgency:
44
+ * - urgent: sound alert
45
+ * - action: normal notification
46
+ * - info/warning: silent
47
+ */
48
+ function shouldPlaySound(priority, soundEnabled) {
49
+ if (!soundEnabled)
50
+ return false;
51
+ return priority === "urgent";
52
+ }
53
+ function titleCaseStatus(value) {
54
+ return value
55
+ .split(/[_\s.-]+/)
56
+ .filter(Boolean)
57
+ .map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)
58
+ .join(" ");
59
+ }
60
+ function truncate(value, maxLength) {
61
+ return value.length > maxLength ? `${value.slice(0, maxLength - 1)}…` : value;
62
+ }
63
+ function eventTitle(event, data) {
64
+ const pr = data?.subject.pr;
65
+ switch (event.type) {
66
+ case "ci.failing":
67
+ return pr ? `CI failing on PR #${pr.number}` : "CI failing";
68
+ case "merge.ready":
69
+ return pr ? `PR #${pr.number} ready to merge` : "Pull request ready to merge";
70
+ case "review.changes_requested":
71
+ return pr ? `Changes requested on PR #${pr.number}` : "Review changes requested";
72
+ case "session.needs_input":
73
+ return "Agent needs input";
74
+ case "session.stuck":
75
+ return "Agent may be stuck";
76
+ case "session.killed":
77
+ case "session.exited":
78
+ return "Agent exited";
79
+ case "pr.closed":
80
+ return pr ? `PR #${pr.number} closed` : "Pull request closed";
81
+ case "summary.all_complete":
82
+ return "All sessions complete";
83
+ default:
84
+ return titleCaseStatus(event.type);
85
+ }
86
+ }
87
+ function formatTitle(event) {
88
+ const data = getNotificationDataV3(event.data);
89
+ const title = eventTitle(event, data);
90
+ if (event.priority === "urgent")
91
+ return `URGENT: ${title}`;
92
+ if (event.priority === "warning")
93
+ return `Warning: ${title}`;
94
+ return title;
95
+ }
96
+ function formatSubtitle(event, data) {
97
+ const segments = [event.projectId, event.sessionId];
98
+ const pr = data?.subject.pr;
99
+ if (pr)
100
+ segments.push(`PR #${pr.number}`);
101
+ else
102
+ segments.push(titleCaseStatus(event.priority));
103
+ return truncate(segments.join(" · "), 120);
104
+ }
105
+ function formatBranch(data) {
106
+ const pr = data?.subject.pr;
107
+ if (pr?.branch && pr.baseBranch)
108
+ return `${pr.branch} → ${pr.baseBranch}`;
109
+ return pr?.branch ?? pr?.baseBranch ?? data?.subject.branch;
110
+ }
111
+ function appendLine(lines, value, maxLength = 180) {
112
+ const trimmed = value?.trim();
113
+ if (!trimmed)
114
+ return;
115
+ lines.push(truncate(trimmed, maxLength));
116
+ }
117
+ function formatStatusLine(data) {
118
+ const segments = [];
119
+ if (data.ci?.status) {
120
+ const failedChecks = data.ci.failedChecks?.map((check) => check.name) ?? [];
121
+ const failedText = failedChecks.length > 0 ? ` (${failedChecks.slice(0, 3).join(", ")})` : "";
122
+ segments.push(`CI: ${titleCaseStatus(data.ci.status)}${failedText}`);
123
+ }
124
+ if (data.review?.decision) {
125
+ const threads = typeof data.review.unresolvedThreads === "number"
126
+ ? `, ${data.review.unresolvedThreads} threads`
127
+ : "";
128
+ segments.push(`Review: ${titleCaseStatus(data.review.decision)}${threads}`);
129
+ }
130
+ if (typeof data.merge?.ready === "boolean") {
131
+ segments.push(`Merge: ${data.merge.ready ? "Ready" : "Not ready"}`);
132
+ }
133
+ if (typeof data.merge?.conflicts === "boolean") {
134
+ segments.push(`Conflicts: ${data.merge.conflicts ? "Found" : "None"}`);
135
+ }
136
+ return segments.length > 0 ? segments.join(" · ") : undefined;
137
+ }
138
+ function formatSubjectLine(data) {
139
+ if (!data)
140
+ return undefined;
141
+ const pr = data.subject.pr;
142
+ const issue = data.subject.issue;
143
+ const segments = [];
144
+ if (pr)
145
+ segments.push(`PR #${pr.number}`);
146
+ if (issue)
147
+ segments.push(issue.id);
148
+ return segments.length > 0 ? segments.join(" · ") : undefined;
149
+ }
150
+ function formatDetailLine(label, value) {
151
+ return value ? `${label}: ${value}` : undefined;
152
+ }
153
+ function formatActionLine(actions, hiddenActionIndexes = new Set()) {
154
+ const visibleActions = (actions ?? []).filter((_, index) => !hiddenActionIndexes.has(index));
155
+ if (visibleActions.length === 0)
156
+ return undefined;
157
+ return `Actions: ${visibleActions.map((action) => action.label).join(" · ")}`;
158
+ }
159
+ function formatBody(event, actions, options = {}) {
160
+ const data = getNotificationDataV3(event.data);
161
+ const lines = [];
162
+ const subtitle = data?.subject.pr?.title ?? data?.subject.summary;
163
+ const branch = formatBranch(data);
164
+ if (subtitle && subtitle !== event.message)
165
+ appendLine(lines, subtitle, 150);
166
+ appendLine(lines, event.message, 180);
167
+ appendLine(lines, formatDetailLine("Context", formatSubjectLine(data)), 160);
168
+ if (data)
169
+ appendLine(lines, formatDetailLine("Status", formatStatusLine(data)), 180);
170
+ appendLine(lines, formatDetailLine("Branch", branch), 140);
171
+ if (data?.transition)
172
+ appendLine(lines, `Transition: ${data.transition.from} → ${data.transition.to}`, 120);
173
+ appendLine(lines, formatActionLine(actions, options.hiddenActionIndexes), 160);
174
+ return lines.join("\n");
175
+ }
176
+ function formatContent(event, actions, options = {}) {
177
+ const data = getNotificationDataV3(event.data);
178
+ return {
179
+ title: formatTitle(event),
180
+ subtitle: formatSubtitle(event, data),
181
+ body: formatBody(event, actions, options),
182
+ };
183
+ }
184
+ function defaultMacAppPath() {
185
+ return join(homedir(), "Applications", "AO Notifier.app");
186
+ }
187
+ function macAppExecutable(appPath) {
188
+ return join(appPath, "Contents", "MacOS", "ao-notifier");
189
+ }
190
+ function macAppPlaceholderMarker(appPath) {
191
+ return join(appPath, "Contents", "Resources", PLACEHOLDER_MARKER_NAME);
192
+ }
193
+ function nativeNotificationId(event, sequence) {
194
+ return `${event.id}.${Date.now()}.${process.pid}.${sequence}`;
195
+ }
196
+ function nativeThreadId() {
197
+ return "ao.notifications";
198
+ }
199
+ function detectAoNotifierApp(appPath) {
200
+ return existsSync(macAppExecutable(appPath)) && !existsSync(macAppPlaceholderMarker(appPath));
201
+ }
202
+ function parseBackend(value) {
203
+ if (value === "auto" ||
204
+ value === "ao-app" ||
205
+ value === "terminal-notifier" ||
206
+ value === "osascript") {
207
+ return value;
208
+ }
209
+ return "auto";
210
+ }
211
+ function dashboardSessionUrl(dashboardUrl, event) {
212
+ if (!dashboardUrl)
213
+ return undefined;
214
+ try {
215
+ const base = new URL(dashboardUrl);
216
+ base.pathname = `/projects/${encodeURIComponent(event.projectId)}/sessions/${encodeURIComponent(event.sessionId)}`;
217
+ base.search = "";
218
+ base.hash = "";
219
+ return base.toString();
220
+ }
221
+ catch {
222
+ return dashboardUrl;
223
+ }
224
+ }
225
+ function firstUrlAction(actions) {
226
+ return actions?.find((action) => typeof action.url === "string")?.url;
227
+ }
228
+ function isAbsoluteHttpUrl(value) {
229
+ if (!value)
230
+ return false;
231
+ try {
232
+ const url = new URL(value);
233
+ return url.protocol === "http:" || url.protocol === "https:";
234
+ }
235
+ catch {
236
+ return false;
237
+ }
238
+ }
239
+ function resolveCallbackEndpoint(callbackEndpoint, dashboardUrl) {
240
+ if (isAbsoluteHttpUrl(callbackEndpoint))
241
+ return callbackEndpoint;
242
+ if (!callbackEndpoint || !dashboardUrl)
243
+ return undefined;
244
+ try {
245
+ const resolved = new URL(callbackEndpoint, dashboardUrl);
246
+ return resolved.protocol === "http:" || resolved.protocol === "https:"
247
+ ? resolved.toString()
248
+ : undefined;
249
+ }
250
+ catch {
251
+ return undefined;
252
+ }
253
+ }
254
+ function nativeActionPayload(action, dashboardUrl) {
255
+ if (typeof action.url === "string") {
256
+ return { label: action.label, url: action.url };
257
+ }
258
+ const callbackEndpoint = resolveCallbackEndpoint(action.callbackEndpoint, dashboardUrl);
259
+ return callbackEndpoint ? { label: action.label, callbackEndpoint } : undefined;
260
+ }
261
+ function nativeActionIndexes(actions, dashboardUrl) {
262
+ const indexes = new Set();
263
+ for (const [index, action] of (actions ?? []).entries()) {
264
+ if (nativeActionPayload(action, dashboardUrl))
265
+ indexes.add(index);
266
+ }
267
+ return indexes;
268
+ }
269
+ function nativeActionPayloads(actions, dashboardUrl) {
270
+ return (actions ?? [])
271
+ .map((action) => nativeActionPayload(action, dashboardUrl))
272
+ .filter((action) => Boolean(action))
273
+ .slice(0, 4);
274
+ }
275
+ function firstActionTarget(actions, dashboardUrl) {
276
+ for (const action of actions ?? []) {
277
+ const target = action.url ?? resolveCallbackEndpoint(action.callbackEndpoint, dashboardUrl);
278
+ if (target)
279
+ return target;
280
+ }
281
+ return undefined;
282
+ }
283
+ function primaryOpenUrl(event, dashboardUrl, actions) {
284
+ return (dashboardSessionUrl(dashboardUrl, event) ??
285
+ getNotificationDataV3(event.data)?.subject.pr?.url ??
286
+ firstUrlAction(actions) ??
287
+ firstActionTarget(actions, dashboardUrl));
288
+ }
289
+ /** Check once at create() time whether terminal-notifier is available. */
290
+ function detectTerminalNotifier() {
291
+ try {
292
+ execFileSync("terminal-notifier", ["--version"], { stdio: "ignore", windowsHide: true });
293
+ return true;
294
+ }
295
+ catch (error) {
296
+ return error.code !== "ENOENT";
297
+ }
298
+ }
299
+ /**
300
+ * Send a desktop notification using terminal-notifier / osascript (macOS) or
301
+ * notify-send (Linux). Falls back gracefully if neither is available.
302
+ *
303
+ * On macOS, when `terminal-notifier` is installed, notifications support
304
+ * click-to-open: clicking the banner opens `openUrl` in the default browser.
305
+ * Without it, the osascript fallback is used (no click-through).
306
+ */
307
+ function sendNotification(content, event, options) {
308
+ return new Promise((resolve, reject) => {
309
+ const os = platform();
310
+ if (os === "darwin") {
311
+ const backend = options.mac.backend === "auto"
312
+ ? detectAoNotifierApp(options.mac.appPath)
313
+ ? "ao-app"
314
+ : options.mac.useTerminalNotifier
315
+ ? "terminal-notifier"
316
+ : "osascript"
317
+ : options.mac.backend;
318
+ if (backend === "ao-app") {
319
+ if (!detectAoNotifierApp(options.mac.appPath)) {
320
+ reject(new Error("AO Notifier.app is not installed. Run: athene setup desktop"));
321
+ return;
322
+ }
323
+ const payload = {
324
+ notificationId: options.notificationId,
325
+ threadId: nativeThreadId(),
326
+ title: content.title,
327
+ subtitle: content.subtitle,
328
+ body: content.body,
329
+ sound: options.sound,
330
+ defaultOpenUrl: options.openUrl,
331
+ event: {
332
+ id: event.id,
333
+ type: event.type,
334
+ priority: event.priority,
335
+ sessionId: event.sessionId,
336
+ projectId: event.projectId,
337
+ timestamp: event.timestamp.toISOString(),
338
+ },
339
+ actions: (options.actions ?? []).map((action) => ({
340
+ label: action.label,
341
+ url: action.url,
342
+ callbackEndpoint: action.callbackEndpoint,
343
+ })),
344
+ };
345
+ const encoded = Buffer.from(JSON.stringify(payload), "utf-8").toString("base64");
346
+ execFile(macAppExecutable(options.mac.appPath), ["--notify-base64", encoded], (err) => {
347
+ if (err)
348
+ reject(err);
349
+ else
350
+ resolve();
351
+ });
352
+ }
353
+ else if (backend === "terminal-notifier") {
354
+ const fallbackContent = options.fallbackContent ?? content;
355
+ const args = ["-title", fallbackContent.title, "-message", fallbackContent.body];
356
+ if (fallbackContent.subtitle) {
357
+ args.push("-subtitle", fallbackContent.subtitle);
358
+ }
359
+ if (options.openUrl) {
360
+ args.push("-open", options.openUrl);
361
+ }
362
+ if (options.sound) {
363
+ args.push("-sound", "default");
364
+ }
365
+ execFile("terminal-notifier", args, (err) => {
366
+ if (err)
367
+ reject(err);
368
+ else
369
+ resolve();
370
+ });
371
+ }
372
+ else {
373
+ const fallbackContent = options.fallbackContent ?? content;
374
+ const safeTitle = escapeAppleScript(fallbackContent.title);
375
+ const safeSubtitle = fallbackContent.subtitle
376
+ ? ` subtitle "${escapeAppleScript(fallbackContent.subtitle)}"`
377
+ : "";
378
+ const safeMessage = escapeAppleScript(fallbackContent.body);
379
+ const soundClause = options.sound ? ' sound name "default"' : "";
380
+ const script = `display notification "${safeMessage}" with title "${safeTitle}"${safeSubtitle}${soundClause}`;
381
+ execFile("osascript", ["-e", script], (err) => {
382
+ if (err)
383
+ reject(err);
384
+ else
385
+ resolve();
386
+ });
387
+ }
388
+ }
389
+ else if (os === "linux") {
390
+ // Linux urgency is driven by event priority, not the macOS sound config
391
+ const args = [];
392
+ if (options.isUrgent) {
393
+ args.push("--urgency=critical");
394
+ }
395
+ const fallbackContent = options.fallbackContent ?? content;
396
+ args.push(fallbackContent.title, fallbackContent.body);
397
+ execFile("notify-send", args, (err) => {
398
+ if (err)
399
+ reject(err);
400
+ else
401
+ resolve();
402
+ });
403
+ }
404
+ else if (os === "win32") {
405
+ // WinRT toast via PowerShell — no third-party deps. Encode the script
406
+ // as UTF-16LE base64 so we never fight with PowerShell's argument
407
+ // tokenizer over quotes, special chars, or newlines in the toast XML.
408
+ const fallbackContent = options.fallbackContent ?? content;
409
+ const script = buildWindowsToastScript(fallbackContent.subtitle ?? fallbackContent.title, fallbackContent.body, options.sound);
410
+ const encoded = Buffer.from(script, "utf16le").toString("base64");
411
+ execFile("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", encoded], { windowsHide: true, timeout: 10_000 }, (err) => {
412
+ if (err) {
413
+ // Don't crash the lifecycle on toast failures — log and resolve.
414
+ // Common causes: stripped-down Windows SKU without WinRT, locked
415
+ // group policy, or the user disabled toast notifications.
416
+ console.warn(`[notifier-desktop] Windows toast failed: ${err.message}`);
417
+ }
418
+ resolve();
419
+ });
420
+ }
421
+ else {
422
+ console.warn(`[notifier-desktop] Desktop notifications not supported on ${os}`);
423
+ resolve();
424
+ }
425
+ });
426
+ }
427
+ export function create(config) {
428
+ let nativeNotificationSequence = 0;
429
+ const soundEnabled = typeof config?.sound === "boolean" ? config.sound : true;
430
+ const dashboardUrl = typeof config?.dashboardUrl === "string" ? config.dashboardUrl : undefined;
431
+ const backend = parseBackend(config?.backend);
432
+ const appPath = typeof config?.appPath === "string" ? config.appPath : defaultMacAppPath();
433
+ const hasTerminalNotifier = isMac() && (backend === "auto" || backend === "terminal-notifier")
434
+ ? detectTerminalNotifier()
435
+ : false;
436
+ const mac = {
437
+ backend,
438
+ appPath,
439
+ useTerminalNotifier: hasTerminalNotifier,
440
+ };
441
+ const nextNativeNotificationId = (event) => {
442
+ nativeNotificationSequence += 1;
443
+ return nativeNotificationId(event, nativeNotificationSequence);
444
+ };
445
+ return {
446
+ name: "desktop",
447
+ async notify(event) {
448
+ const content = formatContent(event);
449
+ const sound = shouldPlaySound(event.priority, soundEnabled);
450
+ const isUrgent = event.priority === "urgent";
451
+ await sendNotification(content, event, {
452
+ sound,
453
+ isUrgent,
454
+ mac,
455
+ notificationId: nextNativeNotificationId(event),
456
+ openUrl: primaryOpenUrl(event, dashboardUrl),
457
+ });
458
+ },
459
+ async notifyWithActions(event, actions) {
460
+ const nativeActions = nativeActionPayloads(actions, dashboardUrl);
461
+ const content = formatContent(event, actions, {
462
+ hiddenActionIndexes: backend === "ao-app" || (backend === "auto" && detectAoNotifierApp(appPath))
463
+ ? nativeActionIndexes(actions, dashboardUrl)
464
+ : undefined,
465
+ });
466
+ const fallbackContent = formatContent(event, actions);
467
+ const sound = shouldPlaySound(event.priority, soundEnabled);
468
+ const isUrgent = event.priority === "urgent";
469
+ await sendNotification(content, event, {
470
+ sound,
471
+ isUrgent,
472
+ mac,
473
+ notificationId: nextNativeNotificationId(event),
474
+ openUrl: primaryOpenUrl(event, dashboardUrl, actions),
475
+ actions: nativeActions,
476
+ fallbackContent,
477
+ });
478
+ },
479
+ };
480
+ }
481
+ export default { manifest, create };
482
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,473 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ // Mock node:child_process
3
+ vi.mock("node:child_process", () => ({
4
+ execFile: vi.fn(),
5
+ execFileSync: vi.fn(),
6
+ }));
7
+ // Mock node:fs
8
+ vi.mock("node:fs", () => ({
9
+ existsSync: vi.fn(() => false),
10
+ }));
11
+ // Mock node:os
12
+ vi.mock("node:os", () => ({
13
+ homedir: vi.fn(() => "/Users/test"),
14
+ platform: vi.fn(() => "darwin"),
15
+ }));
16
+ import { execFile, execFileSync } from "node:child_process";
17
+ import { existsSync } from "node:fs";
18
+ import { platform } from "node:os";
19
+ import { manifest, create, escapeAppleScript } from "./index.js";
20
+ const mockExecFile = execFile;
21
+ const mockExecFileSync = execFileSync;
22
+ const mockExistsSync = existsSync;
23
+ const mockPlatform = platform;
24
+ const originalProcessPlatform = Object.getOwnPropertyDescriptor(process, "platform");
25
+ function setProcessPlatform(value) {
26
+ Object.defineProperty(process, "platform", { value, configurable: true });
27
+ }
28
+ function makeEvent(overrides = {}) {
29
+ return {
30
+ id: "evt-1",
31
+ type: "session.spawned",
32
+ priority: "info",
33
+ sessionId: "app-1",
34
+ projectId: "my-project",
35
+ timestamp: new Date("2025-01-01T00:00:00Z"),
36
+ message: "Session app-1 spawned",
37
+ data: {},
38
+ ...overrides,
39
+ };
40
+ }
41
+ describe("notifier-desktop", () => {
42
+ beforeEach(() => {
43
+ vi.clearAllMocks();
44
+ mockPlatform.mockReturnValue("darwin");
45
+ setProcessPlatform("darwin");
46
+ mockExistsSync.mockReturnValue(false);
47
+ // Default: terminal-notifier not available (osascript fallback)
48
+ mockExecFileSync.mockImplementation(() => {
49
+ const error = new Error("not found");
50
+ error.code = "ENOENT";
51
+ throw error;
52
+ });
53
+ mockExecFile.mockImplementation((..._args) => {
54
+ // execFile may be called as (cmd, args, cb) or (cmd, args, opts, cb).
55
+ // Pick whichever trailing arg is the callback so both shapes work.
56
+ const cb = _args.find((a) => typeof a === "function");
57
+ cb?.(null);
58
+ });
59
+ });
60
+ afterEach(() => {
61
+ if (originalProcessPlatform) {
62
+ Object.defineProperty(process, "platform", originalProcessPlatform);
63
+ }
64
+ });
65
+ describe("manifest", () => {
66
+ it("has correct metadata", () => {
67
+ expect(manifest.name).toBe("desktop");
68
+ expect(manifest.slot).toBe("notifier");
69
+ expect(manifest.version).toBe("0.1.0");
70
+ });
71
+ });
72
+ describe("escapeAppleScript", () => {
73
+ it("escapes double quotes", () => {
74
+ expect(escapeAppleScript('hello "world"')).toBe('hello \\"world\\"');
75
+ });
76
+ it("escapes backslashes", () => {
77
+ expect(escapeAppleScript("path\\to\\file")).toBe("path\\\\to\\\\file");
78
+ });
79
+ it("escapes both backslashes and quotes", () => {
80
+ expect(escapeAppleScript('say \\"hi\\"')).toBe('say \\\\\\"hi\\\\\\"');
81
+ });
82
+ it("returns plain strings unchanged", () => {
83
+ expect(escapeAppleScript("hello world")).toBe("hello world");
84
+ });
85
+ });
86
+ describe("create", () => {
87
+ it("returns a notifier with name 'desktop'", () => {
88
+ const notifier = create();
89
+ expect(notifier.name).toBe("desktop");
90
+ });
91
+ it("has notify and notifyWithActions methods", () => {
92
+ const notifier = create();
93
+ expect(typeof notifier.notify).toBe("function");
94
+ expect(typeof notifier.notifyWithActions).toBe("function");
95
+ });
96
+ });
97
+ describe("notify", () => {
98
+ it("calls osascript on macOS", async () => {
99
+ const notifier = create();
100
+ await notifier.notify(makeEvent());
101
+ expect(mockExecFile).toHaveBeenCalledOnce();
102
+ expect(mockExecFile.mock.calls[0][0]).toBe("osascript");
103
+ expect(mockExecFile.mock.calls[0][1][0]).toBe("-e");
104
+ });
105
+ it("includes session ID in notification subtitle", async () => {
106
+ const notifier = create();
107
+ await notifier.notify(makeEvent({ sessionId: "backend-5" }));
108
+ const script = mockExecFile.mock.calls[0][1][1];
109
+ expect(script).toContain("backend-5");
110
+ });
111
+ it("includes event message in notification body", async () => {
112
+ const notifier = create();
113
+ await notifier.notify(makeEvent({ message: "CI is failing" }));
114
+ const script = mockExecFile.mock.calls[0][1][1];
115
+ expect(script).toContain("CI is failing");
116
+ });
117
+ it("uses URGENT prefix for urgent priority", async () => {
118
+ const notifier = create();
119
+ await notifier.notify(makeEvent({ priority: "urgent" }));
120
+ const script = mockExecFile.mock.calls[0][1][1];
121
+ expect(script).toContain("URGENT");
122
+ });
123
+ it("uses event-aware titles for non-urgent priority", async () => {
124
+ const notifier = create();
125
+ await notifier.notify(makeEvent({ priority: "action" }));
126
+ const script = mockExecFile.mock.calls[0][1][1];
127
+ expect(script).toContain("Session Spawned");
128
+ });
129
+ it("includes sound for urgent notifications", async () => {
130
+ const notifier = create();
131
+ await notifier.notify(makeEvent({ priority: "urgent" }));
132
+ const script = mockExecFile.mock.calls[0][1][1];
133
+ expect(script).toContain('sound name "default"');
134
+ });
135
+ it("does not include sound for info notifications", async () => {
136
+ const notifier = create();
137
+ await notifier.notify(makeEvent({ priority: "info" }));
138
+ const script = mockExecFile.mock.calls[0][1][1];
139
+ expect(script).not.toContain("sound name");
140
+ });
141
+ it("does not include sound for action notifications", async () => {
142
+ const notifier = create();
143
+ await notifier.notify(makeEvent({ priority: "action" }));
144
+ const script = mockExecFile.mock.calls[0][1][1];
145
+ expect(script).not.toContain("sound name");
146
+ });
147
+ it("does not include sound for warning notifications", async () => {
148
+ const notifier = create();
149
+ await notifier.notify(makeEvent({ priority: "warning" }));
150
+ const script = mockExecFile.mock.calls[0][1][1];
151
+ expect(script).not.toContain("sound name");
152
+ });
153
+ it("respects sound=false config even for urgent", async () => {
154
+ const notifier = create({ sound: false });
155
+ await notifier.notify(makeEvent({ priority: "urgent" }));
156
+ const script = mockExecFile.mock.calls[0][1][1];
157
+ expect(script).not.toContain("sound name");
158
+ });
159
+ it("escapes special characters in title and message", async () => {
160
+ const notifier = create();
161
+ await notifier.notify(makeEvent({ sessionId: 'test"inject', message: 'msg with "quotes" and \\backslash' }));
162
+ const script = mockExecFile.mock.calls[0][1][1];
163
+ // Should not contain unescaped quotes (other than the AppleScript string delimiters)
164
+ expect(script).toContain('test\\"inject');
165
+ expect(script).toContain('\\"quotes\\"');
166
+ expect(script).toContain("\\\\backslash");
167
+ });
168
+ it("formats v3 pull request context into a compact desktop summary", async () => {
169
+ const notifier = create();
170
+ await notifier.notify(makeEvent({
171
+ type: "merge.ready",
172
+ priority: "action",
173
+ projectId: "demo",
174
+ sessionId: "demo-agent-29",
175
+ message: "PR #1579 is ready to merge",
176
+ data: {
177
+ schemaVersion: 3,
178
+ subject: {
179
+ session: { id: "demo-agent-29", projectId: "demo" },
180
+ pr: {
181
+ number: 1579,
182
+ title: "Normalize AO notifier payloads",
183
+ url: "https://github.com/slievr/Athene/pull/1579",
184
+ branch: "ao/demo-notifier-harness",
185
+ baseBranch: "main",
186
+ },
187
+ issue: { id: "AO-1579", title: "Make AO notification payloads API-grade" },
188
+ },
189
+ ci: { status: "passing" },
190
+ review: { decision: "approved" },
191
+ merge: { ready: true, conflicts: false },
192
+ transition: { kind: "pr_state", from: "approved", to: "mergeable" },
193
+ },
194
+ }));
195
+ const script = mockExecFile.mock.calls[0][1][1];
196
+ expect(script).toContain("PR #1579 ready to merge");
197
+ expect(script).toContain("Normalize AO notifier payloads");
198
+ expect(script).toContain("demo · demo-agent-29 · PR #1579");
199
+ expect(script).toContain("PR #1579");
200
+ expect(script).toContain("AO-1579");
201
+ expect(script).toContain("Branch: ao/demo-notifier-harness → main");
202
+ expect(script).toContain("CI: Passing");
203
+ expect(script).toContain("Review: Approved");
204
+ expect(script).toContain("Merge: Ready");
205
+ expect(script).toContain("Conflicts: None");
206
+ expect(script).toContain("Transition: approved → mergeable");
207
+ });
208
+ });
209
+ describe("notify on Linux", () => {
210
+ it("calls notify-send on Linux", async () => {
211
+ mockPlatform.mockReturnValue("linux");
212
+ const notifier = create();
213
+ await notifier.notify(makeEvent());
214
+ expect(mockExecFile).toHaveBeenCalledOnce();
215
+ expect(mockExecFile.mock.calls[0][0]).toBe("notify-send");
216
+ });
217
+ it("includes --urgency=critical for urgent on Linux", async () => {
218
+ mockPlatform.mockReturnValue("linux");
219
+ const notifier = create();
220
+ await notifier.notify(makeEvent({ priority: "urgent" }));
221
+ const args = mockExecFile.mock.calls[0][1];
222
+ expect(args).toContain("--urgency=critical");
223
+ // Options must come before title/message for notify-send
224
+ const urgencyIdx = args.indexOf("--urgency=critical");
225
+ const titleIdx = args.findIndex((a) => a.includes("URGENT"));
226
+ expect(urgencyIdx).toBeLessThan(titleIdx);
227
+ });
228
+ it("includes --urgency=critical for urgent even when sound is disabled", async () => {
229
+ mockPlatform.mockReturnValue("linux");
230
+ const notifier = create({ sound: false });
231
+ await notifier.notify(makeEvent({ priority: "urgent" }));
232
+ const args = mockExecFile.mock.calls[0][1];
233
+ expect(args).toContain("--urgency=critical");
234
+ });
235
+ it("does not include --urgency=critical for info on Linux", async () => {
236
+ mockPlatform.mockReturnValue("linux");
237
+ const notifier = create();
238
+ await notifier.notify(makeEvent({ priority: "info" }));
239
+ const args = mockExecFile.mock.calls[0][1];
240
+ expect(args).not.toContain("--urgency=critical");
241
+ });
242
+ });
243
+ describe("notify on Windows", () => {
244
+ it("invokes powershell.exe with an EncodedCommand toast script", async () => {
245
+ mockPlatform.mockReturnValue("win32");
246
+ const notifier = create();
247
+ await notifier.notify(makeEvent({ message: "hello" }));
248
+ expect(mockExecFile).toHaveBeenCalledWith("powershell.exe", expect.arrayContaining(["-EncodedCommand"]), expect.objectContaining({ windowsHide: true }), expect.any(Function));
249
+ const args = mockExecFile.mock.calls[0][1];
250
+ const encoded = args[args.indexOf("-EncodedCommand") + 1];
251
+ const script = Buffer.from(encoded, "base64").toString("utf16le");
252
+ expect(script).toContain("ToastNotificationManager");
253
+ expect(script).toContain("hello");
254
+ });
255
+ it("XML-escapes title and message to prevent toast XML injection", async () => {
256
+ mockPlatform.mockReturnValue("win32");
257
+ const notifier = create();
258
+ await notifier.notify(makeEvent({ sessionId: "<x>", message: 'a"&b' }));
259
+ const args = mockExecFile.mock.calls[0][1];
260
+ const script = Buffer.from(args[args.indexOf("-EncodedCommand") + 1], "base64").toString("utf16le");
261
+ expect(script).toContain("&lt;x&gt;");
262
+ expect(script).toContain("a&quot;&amp;b");
263
+ expect(script).not.toContain("<x>");
264
+ });
265
+ it("logs a warning but does not reject when powershell fails", async () => {
266
+ mockPlatform.mockReturnValue("win32");
267
+ mockExecFile.mockImplementationOnce((..._args) => {
268
+ const cb = _args.find((a) => typeof a === "function");
269
+ cb?.(new Error("WinRT unavailable"));
270
+ });
271
+ const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
272
+ const notifier = create();
273
+ await expect(notifier.notify(makeEvent())).resolves.toBeUndefined();
274
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("WinRT unavailable"));
275
+ warnSpy.mockRestore();
276
+ });
277
+ });
278
+ describe("notify on unsupported platform", () => {
279
+ it("resolves without error on unsupported platform", async () => {
280
+ mockPlatform.mockReturnValue("freebsd");
281
+ const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
282
+ const notifier = create();
283
+ await expect(notifier.notify(makeEvent())).resolves.toBeUndefined();
284
+ expect(mockExecFile).not.toHaveBeenCalled();
285
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("not supported on freebsd"));
286
+ warnSpy.mockRestore();
287
+ });
288
+ });
289
+ describe("notifyWithActions", () => {
290
+ it("includes action labels in the message", async () => {
291
+ const notifier = create();
292
+ const actions = [
293
+ { label: "Merge", url: "https://github.com/pr/1" },
294
+ { label: "Kill", callbackEndpoint: "/api/kill" },
295
+ ];
296
+ await notifier.notifyWithActions(makeEvent(), actions);
297
+ const script = mockExecFile.mock.calls[0][1][1];
298
+ expect(script).toContain("Merge");
299
+ expect(script).toContain("Kill");
300
+ });
301
+ it("includes sound for urgent with actions", async () => {
302
+ const notifier = create();
303
+ const actions = [{ label: "Fix", url: "https://example.com" }];
304
+ await notifier.notifyWithActions(makeEvent({ priority: "urgent" }), actions);
305
+ const script = mockExecFile.mock.calls[0][1][1];
306
+ expect(script).toContain('sound name "default"');
307
+ });
308
+ });
309
+ describe("error handling", () => {
310
+ it("rejects when execFile fails", async () => {
311
+ mockExecFile.mockImplementation((_cmd, _args, cb) => {
312
+ cb(new Error("osascript not found"));
313
+ });
314
+ const notifier = create();
315
+ await expect(notifier.notify(makeEvent())).rejects.toThrow("osascript not found");
316
+ });
317
+ });
318
+ describe("terminal-notifier on macOS", () => {
319
+ beforeEach(() => {
320
+ // terminal-notifier is available
321
+ mockExecFileSync.mockReturnValue(Buffer.from("/usr/local/bin/terminal-notifier\n"));
322
+ });
323
+ it("uses terminal-notifier when available", async () => {
324
+ const notifier = create();
325
+ await notifier.notify(makeEvent());
326
+ expect(mockExecFile).toHaveBeenCalledOnce();
327
+ expect(mockExecFile.mock.calls[0][0]).toBe("terminal-notifier");
328
+ });
329
+ it("passes -title, -subtitle, and -message args", async () => {
330
+ const notifier = create();
331
+ await notifier.notify(makeEvent({ sessionId: "s-1", message: "hello" }));
332
+ const args = mockExecFile.mock.calls[0][1];
333
+ expect(args).toContain("-title");
334
+ expect(args).toContain("-subtitle");
335
+ expect(args).toContain("-message");
336
+ expect(args[args.indexOf("-subtitle") + 1]).toBe("my-project · s-1 · Info");
337
+ expect(args[args.indexOf("-message") + 1]).toContain("hello");
338
+ });
339
+ it("passes session deep link with dashboardUrl when configured", async () => {
340
+ const notifier = create({ dashboardUrl: "http://localhost:8080" });
341
+ await notifier.notify(makeEvent());
342
+ const args = mockExecFile.mock.calls[0][1];
343
+ expect(args).toContain("-open");
344
+ expect(args[args.indexOf("-open") + 1]).toBe("http://localhost:8080/projects/my-project/sessions/app-1");
345
+ });
346
+ it("does not pass -open when dashboardUrl is not configured", async () => {
347
+ const notifier = create();
348
+ await notifier.notify(makeEvent());
349
+ const args = mockExecFile.mock.calls[0][1];
350
+ expect(args).not.toContain("-open");
351
+ });
352
+ it("passes -sound default for urgent notifications", async () => {
353
+ const notifier = create();
354
+ await notifier.notify(makeEvent({ priority: "urgent" }));
355
+ const args = mockExecFile.mock.calls[0][1];
356
+ expect(args).toContain("-sound");
357
+ expect(args[args.indexOf("-sound") + 1]).toBe("default");
358
+ });
359
+ it("does not pass -sound for non-urgent notifications", async () => {
360
+ const notifier = create();
361
+ await notifier.notify(makeEvent({ priority: "info" }));
362
+ const args = mockExecFile.mock.calls[0][1];
363
+ expect(args).not.toContain("-sound");
364
+ });
365
+ it("respects sound=false config", async () => {
366
+ const notifier = create({ sound: false });
367
+ await notifier.notify(makeEvent({ priority: "urgent" }));
368
+ const args = mockExecFile.mock.calls[0][1];
369
+ expect(args).not.toContain("-sound");
370
+ });
371
+ it("falls back to osascript when terminal-notifier is not found", async () => {
372
+ mockExecFileSync.mockImplementation(() => {
373
+ const error = new Error("not found");
374
+ error.code = "ENOENT";
375
+ throw error;
376
+ });
377
+ const notifier = create();
378
+ await notifier.notify(makeEvent());
379
+ expect(mockExecFile.mock.calls[0][0]).toBe("osascript");
380
+ });
381
+ it("does not use terminal-notifier on Linux", async () => {
382
+ mockPlatform.mockReturnValue("linux");
383
+ const notifier = create();
384
+ await notifier.notify(makeEvent());
385
+ expect(mockExecFile.mock.calls[0][0]).toBe("notify-send");
386
+ });
387
+ it("uses terminal-notifier for notifyWithActions too", async () => {
388
+ const notifier = create({ dashboardUrl: "http://localhost:3000" });
389
+ const actions = [{ label: "View", url: "https://example.com" }];
390
+ await notifier.notifyWithActions(makeEvent(), actions);
391
+ expect(mockExecFile.mock.calls[0][0]).toBe("terminal-notifier");
392
+ const args = mockExecFile.mock.calls[0][1];
393
+ expect(args).toContain("-open");
394
+ });
395
+ });
396
+ describe("AO Notifier.app backend", () => {
397
+ beforeEach(() => {
398
+ mockExistsSync.mockImplementation((path) => path.endsWith("AO Notifier.app/Contents/MacOS/ao-notifier"));
399
+ });
400
+ it("uses AO Notifier.app before terminal-notifier in auto mode", async () => {
401
+ mockExecFileSync.mockReturnValue(Buffer.from("/usr/local/bin/terminal-notifier\n"));
402
+ const notifier = create({ dashboardUrl: "http://localhost:3000" });
403
+ await notifier.notify(makeEvent({ message: "native app" }));
404
+ expect(mockExecFile.mock.calls[0][0]).toBe("/Users/test/Applications/AO Notifier.app/Contents/MacOS/ao-notifier");
405
+ expect(mockExecFile.mock.calls[0][1][0]).toBe("--notify-base64");
406
+ });
407
+ it("passes event metadata and default open URL to AO Notifier.app", async () => {
408
+ const notifier = create({ backend: "ao-app", dashboardUrl: "http://localhost:3001" });
409
+ await notifier.notify(makeEvent({ id: "evt-native", sessionId: "s-9" }));
410
+ const encoded = mockExecFile.mock.calls[0][1][1];
411
+ const payload = JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
412
+ expect(payload.notificationId).toMatch(/^evt-native\./);
413
+ expect(payload.threadId).toBe("ao.notifications");
414
+ expect(payload.subtitle).toBe("my-project · s-9 · Info");
415
+ expect(payload.defaultOpenUrl).toBe("http://localhost:3001/projects/my-project/sessions/s-9");
416
+ expect(payload.event).toMatchObject({ id: "evt-native", sessionId: "s-9" });
417
+ });
418
+ it("scopes native notification sequence to each notifier instance", async () => {
419
+ const first = create({ backend: "ao-app" });
420
+ const second = create({ backend: "ao-app" });
421
+ await first.notify(makeEvent({ id: "evt-first" }));
422
+ await second.notify(makeEvent({ id: "evt-second" }));
423
+ const firstEncoded = mockExecFile.mock.calls[0][1][1];
424
+ const secondEncoded = mockExecFile.mock.calls[1][1][1];
425
+ const firstPayload = JSON.parse(Buffer.from(firstEncoded, "base64").toString("utf-8"));
426
+ const secondPayload = JSON.parse(Buffer.from(secondEncoded, "base64").toString("utf-8"));
427
+ expect(firstPayload.notificationId).toMatch(/^evt-first\..*\.1$/);
428
+ expect(secondPayload.notificationId).toMatch(/^evt-second\..*\.1$/);
429
+ });
430
+ it("passes URL actions to AO Notifier.app", async () => {
431
+ const notifier = create({ backend: "ao-app" });
432
+ const actions = [
433
+ { label: "Open PR", url: "https://github.com/example/pr/1" },
434
+ { label: "Kill", callbackEndpoint: "/api/kill" },
435
+ ];
436
+ await notifier.notifyWithActions(makeEvent(), actions);
437
+ const encoded = mockExecFile.mock.calls[0][1][1];
438
+ const payload = JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
439
+ expect(payload.actions).toEqual([
440
+ { label: "Open PR", url: "https://github.com/example/pr/1" },
441
+ ]);
442
+ expect(payload.body).toContain("Kill");
443
+ expect(payload.body).not.toContain("Open PR");
444
+ });
445
+ it("passes callback actions to AO Notifier.app when they resolve against dashboardUrl", async () => {
446
+ const notifier = create({ backend: "ao-app", dashboardUrl: "http://localhost:3000" });
447
+ const actions = [
448
+ { label: "Kill", callbackEndpoint: "/api/sessions/app-1/kill" },
449
+ ];
450
+ await notifier.notifyWithActions(makeEvent(), actions);
451
+ const encoded = mockExecFile.mock.calls[0][1][1];
452
+ const payload = JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
453
+ expect(payload.actions).toEqual([
454
+ { label: "Kill", callbackEndpoint: "http://localhost:3000/api/sessions/app-1/kill" },
455
+ ]);
456
+ expect(payload.body).not.toContain("Kill");
457
+ });
458
+ it("fails when backend ao-app is configured but the app is missing", async () => {
459
+ mockExistsSync.mockReturnValue(false);
460
+ const notifier = create({ backend: "ao-app" });
461
+ await expect(notifier.notify(makeEvent())).rejects.toThrow("athene setup desktop");
462
+ expect(mockExecFile).not.toHaveBeenCalled();
463
+ });
464
+ it("does not use a placeholder AO Notifier.app in auto mode", async () => {
465
+ mockExistsSync.mockImplementation((path) => path.endsWith("AO Notifier.app/Contents/MacOS/ao-notifier") ||
466
+ path.endsWith("AO Notifier.app/Contents/Resources/ao-notifier-placeholder"));
467
+ const notifier = create();
468
+ await notifier.notify(makeEvent());
469
+ expect(mockExecFile.mock.calls[0][0]).toBe("osascript");
470
+ });
471
+ });
472
+ });
473
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@made-by-moonlight/athene-plugin-notifier-desktop",
3
+ "version": "0.9.1",
4
+ "description": "Notifier plugin: OS desktop notifications",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/slievr/Athene.git",
21
+ "directory": "packages/plugins/notifier-desktop"
22
+ },
23
+ "homepage": "https://github.com/slievr/Athene",
24
+ "bugs": {
25
+ "url": "https://github.com/slievr/Athene/issues"
26
+ },
27
+ "engines": {
28
+ "node": ">=20.0.0"
29
+ },
30
+ "dependencies": {
31
+ "@made-by-moonlight/athene-core": "0.9.1"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^25.2.3",
35
+ "typescript": "^5.7.0",
36
+ "vitest": "^3.0.0"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "typecheck": "tsc --noEmit",
44
+ "test": "vitest run",
45
+ "clean": "rm -rf dist"
46
+ }
47
+ }