@mohak34/opencode-notifier 0.1.11 → 0.1.13
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 +19 -10
- package/dist/index.js +43 -20
- package/package.json +1 -1
- package/sounds/question.wav +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# opencode-notifier
|
|
2
2
|
|
|
3
|
-
OpenCode plugin that plays sounds and sends system notifications when permission is needed, generation completes, or
|
|
3
|
+
OpenCode plugin that plays sounds and sends system notifications when permission is needed, generation completes, errors occur, or the question tool is invoked. Works on macOS, Linux, and Windows.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -91,20 +91,24 @@ To customize the plugin, create `~/.config/opencode/opencode-notifier.json`:
|
|
|
91
91
|
"sound": true,
|
|
92
92
|
"notification": true,
|
|
93
93
|
"timeout": 5,
|
|
94
|
+
"showProjectName": true,
|
|
94
95
|
"events": {
|
|
95
96
|
"permission": { "sound": true, "notification": true },
|
|
96
97
|
"complete": { "sound": true, "notification": true },
|
|
97
|
-
"error": { "sound": true, "notification": true }
|
|
98
|
+
"error": { "sound": true, "notification": true },
|
|
99
|
+
"question": { "sound": true, "notification": true }
|
|
98
100
|
},
|
|
99
101
|
"messages": {
|
|
100
|
-
"permission": "
|
|
101
|
-
"complete": "
|
|
102
|
-
"error": "
|
|
102
|
+
"permission": "Session needs permission",
|
|
103
|
+
"complete": "Session has finished",
|
|
104
|
+
"error": "Session encountered an error",
|
|
105
|
+
"question": "Session has a question"
|
|
103
106
|
},
|
|
104
107
|
"sounds": {
|
|
105
108
|
"permission": "/path/to/custom/sound.wav",
|
|
106
109
|
"complete": "/path/to/custom/sound.wav",
|
|
107
|
-
"error": "/path/to/custom/sound.wav"
|
|
110
|
+
"error": "/path/to/custom/sound.wav",
|
|
111
|
+
"question": "/path/to/custom/sound.wav"
|
|
108
112
|
}
|
|
109
113
|
}
|
|
110
114
|
```
|
|
@@ -116,6 +120,7 @@ To customize the plugin, create `~/.config/opencode/opencode-notifier.json`:
|
|
|
116
120
|
| `sound` | boolean | `true` | Global toggle for all sounds |
|
|
117
121
|
| `notification` | boolean | `true` | Global toggle for all notifications |
|
|
118
122
|
| `timeout` | number | `5` | Notification duration in seconds (Linux only) |
|
|
123
|
+
| `showProjectName` | boolean | `true` | Show project folder name in notification title |
|
|
119
124
|
|
|
120
125
|
### Events
|
|
121
126
|
|
|
@@ -126,7 +131,8 @@ Control sound and notification separately for each event:
|
|
|
126
131
|
"events": {
|
|
127
132
|
"permission": { "sound": true, "notification": true },
|
|
128
133
|
"complete": { "sound": false, "notification": true },
|
|
129
|
-
"error": { "sound": true, "notification": false }
|
|
134
|
+
"error": { "sound": true, "notification": false },
|
|
135
|
+
"question": { "sound": true, "notification": true }
|
|
130
136
|
}
|
|
131
137
|
}
|
|
132
138
|
```
|
|
@@ -138,7 +144,8 @@ Or use a boolean to toggle both:
|
|
|
138
144
|
"events": {
|
|
139
145
|
"permission": true,
|
|
140
146
|
"complete": false,
|
|
141
|
-
"error": true
|
|
147
|
+
"error": true,
|
|
148
|
+
"question": true
|
|
142
149
|
}
|
|
143
150
|
}
|
|
144
151
|
```
|
|
@@ -152,7 +159,8 @@ Customize notification text:
|
|
|
152
159
|
"messages": {
|
|
153
160
|
"permission": "Action required",
|
|
154
161
|
"complete": "Done!",
|
|
155
|
-
"error": "Something went wrong"
|
|
162
|
+
"error": "Something went wrong",
|
|
163
|
+
"question": "Input needed"
|
|
156
164
|
}
|
|
157
165
|
}
|
|
158
166
|
```
|
|
@@ -166,7 +174,8 @@ Use your own sound files:
|
|
|
166
174
|
"sounds": {
|
|
167
175
|
"permission": "/home/user/sounds/alert.wav",
|
|
168
176
|
"complete": "/home/user/sounds/done.wav",
|
|
169
|
-
"error": "/home/user/sounds/error.wav"
|
|
177
|
+
"error": "/home/user/sounds/error.wav",
|
|
178
|
+
"question": "/home/user/sounds/question.wav"
|
|
170
179
|
}
|
|
171
180
|
}
|
|
172
181
|
```
|
package/dist/index.js
CHANGED
|
@@ -3726,6 +3726,9 @@ var require_node_notifier = __commonJS((exports, module) => {
|
|
|
3726
3726
|
module.exports.Growl = Growl;
|
|
3727
3727
|
});
|
|
3728
3728
|
|
|
3729
|
+
// src/index.ts
|
|
3730
|
+
import { basename } from "path";
|
|
3731
|
+
|
|
3729
3732
|
// src/config.ts
|
|
3730
3733
|
import { readFileSync, existsSync } from "fs";
|
|
3731
3734
|
import { join } from "path";
|
|
@@ -3738,20 +3741,24 @@ var DEFAULT_CONFIG = {
|
|
|
3738
3741
|
sound: true,
|
|
3739
3742
|
notification: true,
|
|
3740
3743
|
timeout: 5,
|
|
3744
|
+
showProjectName: true,
|
|
3741
3745
|
events: {
|
|
3742
3746
|
permission: { ...DEFAULT_EVENT_CONFIG },
|
|
3743
3747
|
complete: { ...DEFAULT_EVENT_CONFIG },
|
|
3744
|
-
error: { ...DEFAULT_EVENT_CONFIG }
|
|
3748
|
+
error: { ...DEFAULT_EVENT_CONFIG },
|
|
3749
|
+
question: { ...DEFAULT_EVENT_CONFIG }
|
|
3745
3750
|
},
|
|
3746
3751
|
messages: {
|
|
3747
|
-
permission: "
|
|
3748
|
-
complete: "
|
|
3749
|
-
error: "
|
|
3752
|
+
permission: "Session needs permission",
|
|
3753
|
+
complete: "Session has finished",
|
|
3754
|
+
error: "Session encountered an error",
|
|
3755
|
+
question: "Session has a question"
|
|
3750
3756
|
},
|
|
3751
3757
|
sounds: {
|
|
3752
3758
|
permission: null,
|
|
3753
3759
|
complete: null,
|
|
3754
|
-
error: null
|
|
3760
|
+
error: null,
|
|
3761
|
+
question: null
|
|
3755
3762
|
}
|
|
3756
3763
|
};
|
|
3757
3764
|
function getConfigPath() {
|
|
@@ -3790,20 +3797,24 @@ function loadConfig() {
|
|
|
3790
3797
|
sound: globalSound,
|
|
3791
3798
|
notification: globalNotification,
|
|
3792
3799
|
timeout: typeof userConfig.timeout === "number" && userConfig.timeout > 0 ? userConfig.timeout : DEFAULT_CONFIG.timeout,
|
|
3800
|
+
showProjectName: userConfig.showProjectName ?? DEFAULT_CONFIG.showProjectName,
|
|
3793
3801
|
events: {
|
|
3794
3802
|
permission: parseEventConfig(userConfig.events?.permission ?? userConfig.permission, defaultWithGlobal),
|
|
3795
3803
|
complete: parseEventConfig(userConfig.events?.complete ?? userConfig.complete, defaultWithGlobal),
|
|
3796
|
-
error: parseEventConfig(userConfig.events?.error ?? userConfig.error, defaultWithGlobal)
|
|
3804
|
+
error: parseEventConfig(userConfig.events?.error ?? userConfig.error, defaultWithGlobal),
|
|
3805
|
+
question: parseEventConfig(userConfig.events?.question ?? userConfig.question, defaultWithGlobal)
|
|
3797
3806
|
},
|
|
3798
3807
|
messages: {
|
|
3799
3808
|
permission: userConfig.messages?.permission ?? DEFAULT_CONFIG.messages.permission,
|
|
3800
3809
|
complete: userConfig.messages?.complete ?? DEFAULT_CONFIG.messages.complete,
|
|
3801
|
-
error: userConfig.messages?.error ?? DEFAULT_CONFIG.messages.error
|
|
3810
|
+
error: userConfig.messages?.error ?? DEFAULT_CONFIG.messages.error,
|
|
3811
|
+
question: userConfig.messages?.question ?? DEFAULT_CONFIG.messages.question
|
|
3802
3812
|
},
|
|
3803
3813
|
sounds: {
|
|
3804
3814
|
permission: userConfig.sounds?.permission ?? DEFAULT_CONFIG.sounds.permission,
|
|
3805
3815
|
complete: userConfig.sounds?.complete ?? DEFAULT_CONFIG.sounds.complete,
|
|
3806
|
-
error: userConfig.sounds?.error ?? DEFAULT_CONFIG.sounds.error
|
|
3816
|
+
error: userConfig.sounds?.error ?? DEFAULT_CONFIG.sounds.error,
|
|
3817
|
+
question: userConfig.sounds?.question ?? DEFAULT_CONFIG.sounds.question
|
|
3807
3818
|
}
|
|
3808
3819
|
};
|
|
3809
3820
|
} catch {
|
|
@@ -3827,7 +3838,6 @@ function getSoundPath(config, event) {
|
|
|
3827
3838
|
var import_node_notifier = __toESM(require_node_notifier(), 1);
|
|
3828
3839
|
import os from "os";
|
|
3829
3840
|
import { exec } from "child_process";
|
|
3830
|
-
var NOTIFICATION_TITLE = "OpenCode";
|
|
3831
3841
|
var DEBOUNCE_MS = 1000;
|
|
3832
3842
|
var platform = os.type();
|
|
3833
3843
|
var platformNotifier;
|
|
@@ -3841,7 +3851,7 @@ if (platform === "Linux" || platform.match(/BSD$/)) {
|
|
|
3841
3851
|
platformNotifier = import_node_notifier.default;
|
|
3842
3852
|
}
|
|
3843
3853
|
var lastNotificationTime = {};
|
|
3844
|
-
async function sendNotification(message, timeout) {
|
|
3854
|
+
async function sendNotification(title, message, timeout) {
|
|
3845
3855
|
const now = Date.now();
|
|
3846
3856
|
if (lastNotificationTime[message] && now - lastNotificationTime[message] < DEBOUNCE_MS) {
|
|
3847
3857
|
return;
|
|
@@ -3850,7 +3860,7 @@ async function sendNotification(message, timeout) {
|
|
|
3850
3860
|
if (platform === "Darwin") {
|
|
3851
3861
|
return new Promise((resolve) => {
|
|
3852
3862
|
const escapedMessage = message.replace(/"/g, "\\\"");
|
|
3853
|
-
const escapedTitle =
|
|
3863
|
+
const escapedTitle = title.replace(/"/g, "\\\"");
|
|
3854
3864
|
exec(`osascript -e 'display notification "${escapedMessage}" with title "${escapedTitle}"'`, () => {
|
|
3855
3865
|
resolve();
|
|
3856
3866
|
});
|
|
@@ -3858,7 +3868,7 @@ async function sendNotification(message, timeout) {
|
|
|
3858
3868
|
}
|
|
3859
3869
|
return new Promise((resolve) => {
|
|
3860
3870
|
const notificationOptions = {
|
|
3861
|
-
title
|
|
3871
|
+
title,
|
|
3862
3872
|
message,
|
|
3863
3873
|
timeout,
|
|
3864
3874
|
icon: undefined
|
|
@@ -3971,11 +3981,18 @@ async function playSound(event, customPath) {
|
|
|
3971
3981
|
}
|
|
3972
3982
|
|
|
3973
3983
|
// src/index.ts
|
|
3974
|
-
|
|
3984
|
+
function getNotificationTitle(config, projectName) {
|
|
3985
|
+
if (config.showProjectName && projectName) {
|
|
3986
|
+
return `OpenCode (${projectName})`;
|
|
3987
|
+
}
|
|
3988
|
+
return "OpenCode";
|
|
3989
|
+
}
|
|
3990
|
+
async function handleEvent(config, eventType, projectName) {
|
|
3975
3991
|
const promises = [];
|
|
3976
3992
|
if (isEventNotificationEnabled(config, eventType)) {
|
|
3993
|
+
const title = getNotificationTitle(config, projectName);
|
|
3977
3994
|
const message = getMessage(config, eventType);
|
|
3978
|
-
promises.push(sendNotification(message, config.timeout));
|
|
3995
|
+
promises.push(sendNotification(title, message, config.timeout));
|
|
3979
3996
|
}
|
|
3980
3997
|
if (isEventSoundEnabled(config, eventType)) {
|
|
3981
3998
|
const customSoundPath = getSoundPath(config, eventType);
|
|
@@ -3983,25 +4000,31 @@ async function handleEvent(config, eventType) {
|
|
|
3983
4000
|
}
|
|
3984
4001
|
await Promise.allSettled(promises);
|
|
3985
4002
|
}
|
|
3986
|
-
var NotifierPlugin = async () => {
|
|
4003
|
+
var NotifierPlugin = async ({ project, client, $, directory, worktree }) => {
|
|
3987
4004
|
const config = loadConfig();
|
|
4005
|
+
const projectName = directory ? basename(directory) : null;
|
|
3988
4006
|
return {
|
|
3989
4007
|
event: async ({ event }) => {
|
|
3990
4008
|
if (event.type === "permission.updated") {
|
|
3991
|
-
await handleEvent(config, "permission");
|
|
4009
|
+
await handleEvent(config, "permission", projectName);
|
|
3992
4010
|
}
|
|
3993
4011
|
if (event.type === "permission.asked") {
|
|
3994
|
-
await handleEvent(config, "permission");
|
|
4012
|
+
await handleEvent(config, "permission", projectName);
|
|
3995
4013
|
}
|
|
3996
4014
|
if (event.type === "session.idle") {
|
|
3997
|
-
await handleEvent(config, "complete");
|
|
4015
|
+
await handleEvent(config, "complete", projectName);
|
|
3998
4016
|
}
|
|
3999
4017
|
if (event.type === "session.error") {
|
|
4000
|
-
await handleEvent(config, "error");
|
|
4018
|
+
await handleEvent(config, "error", projectName);
|
|
4001
4019
|
}
|
|
4002
4020
|
},
|
|
4003
4021
|
"permission.ask": async () => {
|
|
4004
|
-
await handleEvent(config, "permission");
|
|
4022
|
+
await handleEvent(config, "permission", projectName);
|
|
4023
|
+
},
|
|
4024
|
+
"tool.execute.before": async (input, output) => {
|
|
4025
|
+
if (input.tool === "question") {
|
|
4026
|
+
await handleEvent(config, "question", projectName);
|
|
4027
|
+
}
|
|
4005
4028
|
}
|
|
4006
4029
|
};
|
|
4007
4030
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mohak34/opencode-notifier",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
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",
|
|
Binary file
|