@mohak34/opencode-notifier 0.1.27-beta.1 → 0.1.27
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 +22 -0
- package/dist/index.js +65 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,6 +55,9 @@ Create `~/.config/opencode/opencode-notifier.json` with the defaults:
|
|
|
55
55
|
"showSessionTitle": false,
|
|
56
56
|
"showIcon": true,
|
|
57
57
|
"notificationSystem": "osascript",
|
|
58
|
+
"linux": {
|
|
59
|
+
"grouping": false
|
|
60
|
+
},
|
|
58
61
|
"command": {
|
|
59
62
|
"enabled": false,
|
|
60
63
|
"path": "/path/to/command",
|
|
@@ -115,6 +118,7 @@ Create `~/.config/opencode/opencode-notifier.json` with the defaults:
|
|
|
115
118
|
- `showSessionTitle` - Include the session title in notification messages via `{sessionTitle}` placeholder (default: true)
|
|
116
119
|
- `showIcon` - Show OpenCode icon, Windows/Linux only (default: true)
|
|
117
120
|
- `notificationSystem` - macOS only: `"osascript"` or `"node-notifier"` (default: "osascript")
|
|
121
|
+
- `linux.grouping` - Linux only: replace notifications in-place instead of stacking (default: false). Requires `notify-send` 0.8+
|
|
118
122
|
|
|
119
123
|
### Events
|
|
120
124
|
|
|
@@ -263,6 +267,24 @@ Run your own script when something happens. Use `{event}`, `{message}`, and `{se
|
|
|
263
267
|
|
|
264
268
|
**NOTE:** If you go with node-notifier and start missing notifications, just switch back or remove the option from the config. Users have reported issues with using node-notifier for receiving only sounds and no notification popups.
|
|
265
269
|
|
|
270
|
+
## Linux: Notification Grouping
|
|
271
|
+
|
|
272
|
+
By default, each notification appears as a separate entry. During active sessions this can create noise when multiple events fire quickly (e.g. permission + complete + question).
|
|
273
|
+
|
|
274
|
+
Enable grouping to replace notifications in-place instead of stacking:
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"linux": {
|
|
279
|
+
"grouping": true
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
With grouping enabled, each new notification replaces the previous one so you only see the latest event. This requires `notify-send` 0.8+ (standard on Ubuntu 22.04+, Debian 12+, Fedora 36+, Arch). On older systems it falls back to the default stacking behavior automatically.
|
|
285
|
+
|
|
286
|
+
Works with all major notification daemons (GNOME, dunst, mako, swaync, etc.) on both X11 and Wayland.
|
|
287
|
+
|
|
266
288
|
## Updating
|
|
267
289
|
|
|
268
290
|
If Opencode does not update the plugin or there is an issue with the cache version:
|
package/dist/index.js
CHANGED
|
@@ -3746,6 +3746,9 @@ var DEFAULT_CONFIG = {
|
|
|
3746
3746
|
showSessionTitle: false,
|
|
3747
3747
|
showIcon: true,
|
|
3748
3748
|
notificationSystem: "osascript",
|
|
3749
|
+
linux: {
|
|
3750
|
+
grouping: false
|
|
3751
|
+
},
|
|
3749
3752
|
command: {
|
|
3750
3753
|
enabled: false,
|
|
3751
3754
|
path: "",
|
|
@@ -3842,6 +3845,9 @@ function loadConfig() {
|
|
|
3842
3845
|
showSessionTitle: userConfig.showSessionTitle ?? DEFAULT_CONFIG.showSessionTitle,
|
|
3843
3846
|
showIcon: userConfig.showIcon ?? DEFAULT_CONFIG.showIcon,
|
|
3844
3847
|
notificationSystem: userConfig.notificationSystem === "node-notifier" ? "node-notifier" : "osascript",
|
|
3848
|
+
linux: {
|
|
3849
|
+
grouping: typeof userConfig.linux?.grouping === "boolean" ? userConfig.linux.grouping : DEFAULT_CONFIG.linux.grouping
|
|
3850
|
+
},
|
|
3845
3851
|
command: {
|
|
3846
3852
|
enabled: typeof userCommand.enabled === "boolean" ? userCommand.enabled : DEFAULT_CONFIG.command.enabled,
|
|
3847
3853
|
path: typeof userCommand.path === "string" ? userCommand.path : DEFAULT_CONFIG.command.path,
|
|
@@ -3928,7 +3934,7 @@ function interpolateMessage(message, context) {
|
|
|
3928
3934
|
// src/notify.ts
|
|
3929
3935
|
var import_node_notifier = __toESM(require_node_notifier(), 1);
|
|
3930
3936
|
import os from "os";
|
|
3931
|
-
import { exec } from "child_process";
|
|
3937
|
+
import { exec, execFile } from "child_process";
|
|
3932
3938
|
var DEBOUNCE_MS = 1000;
|
|
3933
3939
|
var platform = os.type();
|
|
3934
3940
|
var platformNotifier;
|
|
@@ -3942,7 +3948,53 @@ if (platform === "Linux" || platform.match(/BSD$/)) {
|
|
|
3942
3948
|
platformNotifier = import_node_notifier.default;
|
|
3943
3949
|
}
|
|
3944
3950
|
var lastNotificationTime = {};
|
|
3945
|
-
|
|
3951
|
+
var lastLinuxNotificationId = null;
|
|
3952
|
+
var linuxNotifySendSupportsReplace = null;
|
|
3953
|
+
function detectNotifySendCapabilities() {
|
|
3954
|
+
return new Promise((resolve) => {
|
|
3955
|
+
execFile("notify-send", ["--version"], (error, stdout) => {
|
|
3956
|
+
if (error) {
|
|
3957
|
+
resolve(false);
|
|
3958
|
+
return;
|
|
3959
|
+
}
|
|
3960
|
+
const match = stdout.match(/(\d+)\.(\d+)/);
|
|
3961
|
+
if (match) {
|
|
3962
|
+
const major = parseInt(match[1], 10);
|
|
3963
|
+
const minor = parseInt(match[2], 10);
|
|
3964
|
+
resolve(major > 0 || major === 0 && minor >= 8);
|
|
3965
|
+
return;
|
|
3966
|
+
}
|
|
3967
|
+
resolve(false);
|
|
3968
|
+
});
|
|
3969
|
+
});
|
|
3970
|
+
}
|
|
3971
|
+
function sendLinuxNotificationDirect(title, message, timeout, iconPath, grouping = true) {
|
|
3972
|
+
return new Promise((resolve) => {
|
|
3973
|
+
const args = [];
|
|
3974
|
+
if (iconPath) {
|
|
3975
|
+
args.push("--icon", iconPath);
|
|
3976
|
+
}
|
|
3977
|
+
args.push("--expire-time", String(timeout * 1000));
|
|
3978
|
+
args.push("--app-name", "OpenCode");
|
|
3979
|
+
if (grouping && lastLinuxNotificationId !== null) {
|
|
3980
|
+
args.push("--replace-id", String(lastLinuxNotificationId));
|
|
3981
|
+
}
|
|
3982
|
+
if (grouping) {
|
|
3983
|
+
args.push("--print-id");
|
|
3984
|
+
}
|
|
3985
|
+
args.push("--", title, message);
|
|
3986
|
+
execFile("notify-send", args, (error, stdout) => {
|
|
3987
|
+
if (!error && grouping && stdout) {
|
|
3988
|
+
const id = parseInt(stdout.trim(), 10);
|
|
3989
|
+
if (!isNaN(id)) {
|
|
3990
|
+
lastLinuxNotificationId = id;
|
|
3991
|
+
}
|
|
3992
|
+
}
|
|
3993
|
+
resolve();
|
|
3994
|
+
});
|
|
3995
|
+
});
|
|
3996
|
+
}
|
|
3997
|
+
async function sendNotification(title, message, timeout, iconPath, notificationSystem = "osascript", linuxGrouping = true) {
|
|
3946
3998
|
const now = Date.now();
|
|
3947
3999
|
if (lastNotificationTime[message] && now - lastNotificationTime[message] < DEBOUNCE_MS) {
|
|
3948
4000
|
return;
|
|
@@ -3970,6 +4022,16 @@ async function sendNotification(title, message, timeout, iconPath, notificationS
|
|
|
3970
4022
|
});
|
|
3971
4023
|
});
|
|
3972
4024
|
}
|
|
4025
|
+
if (platform === "Linux" || platform.match(/BSD$/)) {
|
|
4026
|
+
if (linuxGrouping) {
|
|
4027
|
+
if (linuxNotifySendSupportsReplace === null) {
|
|
4028
|
+
linuxNotifySendSupportsReplace = await detectNotifySendCapabilities();
|
|
4029
|
+
}
|
|
4030
|
+
if (linuxNotifySendSupportsReplace) {
|
|
4031
|
+
return sendLinuxNotificationDirect(title, message, timeout, iconPath, true);
|
|
4032
|
+
}
|
|
4033
|
+
}
|
|
4034
|
+
}
|
|
3973
4035
|
return new Promise((resolve) => {
|
|
3974
4036
|
const notificationOptions = {
|
|
3975
4037
|
title,
|
|
@@ -4169,7 +4231,7 @@ async function handleEvent(config, eventType, projectName, elapsedSeconds, sessi
|
|
|
4169
4231
|
if (isEventNotificationEnabled(config, eventType)) {
|
|
4170
4232
|
const title = getNotificationTitle(config, projectName);
|
|
4171
4233
|
const iconPath = getIconPath(config);
|
|
4172
|
-
promises.push(sendNotification(title, message, config.timeout, iconPath, config.notificationSystem));
|
|
4234
|
+
promises.push(sendNotification(title, message, config.timeout, iconPath, config.notificationSystem, config.linux.grouping));
|
|
4173
4235
|
}
|
|
4174
4236
|
if (isEventSoundEnabled(config, eventType)) {
|
|
4175
4237
|
const customSoundPath = getSoundPath(config, eventType);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mohak34/opencode-notifier",
|
|
3
|
-
"version": "0.1.27
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"description": "OpenCode plugin that sends system notifications and plays sounds when permission is needed, generation completes, or errors occur",
|
|
5
5
|
"author": "mohak34",
|
|
6
6
|
"license": "MIT",
|