@mohak34/opencode-notifier 0.1.14 → 0.1.16
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 +11 -1
- package/dist/index.js +332 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -92,6 +92,7 @@ To customize the plugin, create `~/.config/opencode/opencode-notifier.json`:
|
|
|
92
92
|
"notification": true,
|
|
93
93
|
"timeout": 5,
|
|
94
94
|
"showProjectName": true,
|
|
95
|
+
"suppressWhenFocused": false,
|
|
95
96
|
"command": {
|
|
96
97
|
"enabled": false,
|
|
97
98
|
"path": "/path/to/command",
|
|
@@ -108,7 +109,7 @@ To customize the plugin, create `~/.config/opencode/opencode-notifier.json`:
|
|
|
108
109
|
"messages": {
|
|
109
110
|
"permission": "Session needs permission",
|
|
110
111
|
"complete": "Session has finished",
|
|
111
|
-
"subagent_complete": "Subagent
|
|
112
|
+
"subagent_complete": "Subagent task completed",
|
|
112
113
|
"error": "Session encountered an error",
|
|
113
114
|
"question": "Session has a question"
|
|
114
115
|
},
|
|
@@ -130,6 +131,7 @@ To customize the plugin, create `~/.config/opencode/opencode-notifier.json`:
|
|
|
130
131
|
| `notification` | boolean | `true` | Global toggle for all notifications |
|
|
131
132
|
| `timeout` | number | `5` | Notification duration in seconds (Linux only) |
|
|
132
133
|
| `showProjectName` | boolean | `true` | Show project folder name in notification title |
|
|
134
|
+
| `suppressWhenFocused` | boolean | `false` | Suppress notifications when terminal is focused |
|
|
133
135
|
| `command` | object | — | Command execution settings (enabled/path/args/minDuration) |
|
|
134
136
|
|
|
135
137
|
### Events
|
|
@@ -164,6 +166,14 @@ Or use a boolean to toggle both:
|
|
|
164
166
|
|
|
165
167
|
Note: `complete` fires for primary (main) session completion, while `subagent_complete` fires for subagent completion. `subagent_complete` defaults to disabled (both sound and notification are false).
|
|
166
168
|
|
|
169
|
+
### Suppress when focused
|
|
170
|
+
|
|
171
|
+
When `suppressWhenFocused` is enabled, notifications are skipped if your terminal is the frontmost window.
|
|
172
|
+
|
|
173
|
+
- macOS: works out of the box
|
|
174
|
+
- Windows: uses PowerShell to detect the foreground app
|
|
175
|
+
- Linux: requires one of `xdotool`, `wmctrl`, or `xprop` (install via your package manager). If none are installed, suppression is skipped.
|
|
176
|
+
|
|
167
177
|
### Messages
|
|
168
178
|
|
|
169
179
|
Customize notification text:
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,231 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
18
18
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
19
19
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
20
20
|
|
|
21
|
+
// node_modules/detect-terminal/dist/index.js
|
|
22
|
+
var require_dist = __commonJS((exports, module) => {
|
|
23
|
+
var __create2 = Object.create;
|
|
24
|
+
var __defProp2 = Object.defineProperty;
|
|
25
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
26
|
+
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
27
|
+
var __getProtoOf2 = Object.getPrototypeOf;
|
|
28
|
+
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
29
|
+
var __name = (target, value) => __defProp2(target, "name", { value, configurable: true });
|
|
30
|
+
var __export = (target, all) => {
|
|
31
|
+
for (var name in all)
|
|
32
|
+
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
33
|
+
};
|
|
34
|
+
var __copyProps = (to, from, except, desc) => {
|
|
35
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
36
|
+
for (let key of __getOwnPropNames2(from))
|
|
37
|
+
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
38
|
+
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
39
|
+
}
|
|
40
|
+
return to;
|
|
41
|
+
};
|
|
42
|
+
var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod));
|
|
43
|
+
var __toCommonJS = (mod) => __copyProps(__defProp2({}, "__esModule", { value: true }), mod);
|
|
44
|
+
var detect_terminal_exports = {};
|
|
45
|
+
__export(detect_terminal_exports, {
|
|
46
|
+
default: () => detect_terminal_default,
|
|
47
|
+
detectFromEnv: () => detectFromEnv,
|
|
48
|
+
detectFromProcessTitle: () => detectFromProcessTitle,
|
|
49
|
+
detectFromShell: () => detectFromShell,
|
|
50
|
+
detectTerminal: () => detectTerminal
|
|
51
|
+
});
|
|
52
|
+
module.exports = __toCommonJS(detect_terminal_exports);
|
|
53
|
+
var import_node_child_process = __require("child_process");
|
|
54
|
+
var import_node_path = __toESM2(__require("path"));
|
|
55
|
+
var detectFromEnv = /* @__PURE__ */ __name(() => {
|
|
56
|
+
const platform = process.platform;
|
|
57
|
+
if (platform === "android" && process.env.TERMUX_VERSION) {
|
|
58
|
+
return "termux";
|
|
59
|
+
}
|
|
60
|
+
let termProgram = process.env.TERM_PROGRAM?.trim()?.toLowerCase();
|
|
61
|
+
if (platform === "darwin" && termProgram) {
|
|
62
|
+
termProgram = import_node_path.default.parse(termProgram).name;
|
|
63
|
+
}
|
|
64
|
+
if (termProgram) {
|
|
65
|
+
switch (termProgram) {
|
|
66
|
+
case "apple_terminal":
|
|
67
|
+
return "terminal";
|
|
68
|
+
case "eterm":
|
|
69
|
+
return "eterm";
|
|
70
|
+
case "gnome-terminal":
|
|
71
|
+
return "gnome_terminal";
|
|
72
|
+
case "gnome-terminal-server":
|
|
73
|
+
return "gnome_terminal";
|
|
74
|
+
case "hyper":
|
|
75
|
+
return "hyper";
|
|
76
|
+
case "iterm.app":
|
|
77
|
+
return "iterm";
|
|
78
|
+
case "iterm":
|
|
79
|
+
return "iterm";
|
|
80
|
+
case "iterm2":
|
|
81
|
+
return "iterm";
|
|
82
|
+
case "kitty":
|
|
83
|
+
return "kitty";
|
|
84
|
+
case "konsole":
|
|
85
|
+
return "konsole";
|
|
86
|
+
case "mate-terminal":
|
|
87
|
+
return "mate_terminal";
|
|
88
|
+
case "powershell":
|
|
89
|
+
return "powershell";
|
|
90
|
+
case "putty":
|
|
91
|
+
return "putty";
|
|
92
|
+
case "qterminal":
|
|
93
|
+
return "qterminal";
|
|
94
|
+
case "rxvt":
|
|
95
|
+
return "rxvt";
|
|
96
|
+
case "terminal.app":
|
|
97
|
+
return "terminal_app";
|
|
98
|
+
case "terminal":
|
|
99
|
+
return "terminal";
|
|
100
|
+
case "terminator":
|
|
101
|
+
return "terminator";
|
|
102
|
+
case "termux":
|
|
103
|
+
return "termux";
|
|
104
|
+
case "vscode":
|
|
105
|
+
return "vscode";
|
|
106
|
+
case "warp":
|
|
107
|
+
return "warp";
|
|
108
|
+
case "wezterm":
|
|
109
|
+
return "wezterm";
|
|
110
|
+
case "xfce4-terminal":
|
|
111
|
+
return "xfce4_terminal";
|
|
112
|
+
case "alacritty":
|
|
113
|
+
return "alacritty";
|
|
114
|
+
default:
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
return termProgram.replace(/[^a-z0-9]+/g, "_");
|
|
118
|
+
}
|
|
119
|
+
if (typeof process.env.VSCODE_PID !== "undefined" || typeof process.env.TERM_PROGRAM_VERSION !== "undefined" && /vscode/i.test(process.env.TERM_PROGRAM_VERSION)) {
|
|
120
|
+
return "vscode";
|
|
121
|
+
}
|
|
122
|
+
const term = process.env.TERM?.trim()?.toLowerCase();
|
|
123
|
+
if (term && term !== "unknown") {
|
|
124
|
+
if (term === "xterm" || term === "xterm-256color") {
|
|
125
|
+
if (process.env.VTE_VERSION) {
|
|
126
|
+
const vteVersion = parseInt(process.env.VTE_VERSION, 10);
|
|
127
|
+
if (vteVersion >= 3803) {
|
|
128
|
+
return "gnome_terminal";
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
for (const [key] of Object.entries(process.env)) {
|
|
132
|
+
if (/konsole/i.test(key)) {
|
|
133
|
+
return "konsole";
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (platform === "darwin") {
|
|
137
|
+
return "terminal";
|
|
138
|
+
}
|
|
139
|
+
return "xterm";
|
|
140
|
+
}
|
|
141
|
+
if (/screen/.test(term))
|
|
142
|
+
return "screen";
|
|
143
|
+
if (/tmux/.test(term))
|
|
144
|
+
return "tmux";
|
|
145
|
+
if (/rxvt/.test(term))
|
|
146
|
+
return "rxvt";
|
|
147
|
+
if (/vt100/.test(term))
|
|
148
|
+
return "vt100";
|
|
149
|
+
if (/linux/.test(term))
|
|
150
|
+
return "linux_console";
|
|
151
|
+
if (/alacritty/.test(term))
|
|
152
|
+
return "alacritty";
|
|
153
|
+
if (/dopamine/.test(term))
|
|
154
|
+
return "dopamine";
|
|
155
|
+
if (/kitty/.test(term))
|
|
156
|
+
return "kitty";
|
|
157
|
+
if (/ghostty/.test(term))
|
|
158
|
+
return "ghostty";
|
|
159
|
+
return term.replace(/[^a-z0-9]+/g, "_");
|
|
160
|
+
}
|
|
161
|
+
const colorTerm = process.env.COLORTERM?.trim()?.toLowerCase();
|
|
162
|
+
if (colorTerm === "truecolor" || colorTerm === "24bit") {
|
|
163
|
+
return "truecolor_terminal";
|
|
164
|
+
}
|
|
165
|
+
if (colorTerm) {
|
|
166
|
+
return colorTerm.replace(/[^a-z0-9]+/g, "_");
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}, "detectFromEnv");
|
|
170
|
+
var detectFromShell = /* @__PURE__ */ __name(() => {
|
|
171
|
+
try {
|
|
172
|
+
const isWindows = process.platform === "win32";
|
|
173
|
+
if (isWindows) {
|
|
174
|
+
if (process.env.WT_SESSION)
|
|
175
|
+
return "windows_terminal";
|
|
176
|
+
const shell = process.env.COMSPEC?.toLowerCase() || "";
|
|
177
|
+
if (/powershell/i.test(shell))
|
|
178
|
+
return "powershell";
|
|
179
|
+
if (/pwsh/i.test(shell))
|
|
180
|
+
return "powershell";
|
|
181
|
+
if (/cmd\.exe/i.test(shell))
|
|
182
|
+
return "cmd";
|
|
183
|
+
if (/wt\.exe/i.test(shell))
|
|
184
|
+
return "windows_terminal";
|
|
185
|
+
if (/conhost\.exe/i.test(shell))
|
|
186
|
+
return "conhost";
|
|
187
|
+
return "windows_cmd";
|
|
188
|
+
}
|
|
189
|
+
const terminal = (0, import_node_child_process.execSync)("echo $TERM", {
|
|
190
|
+
encoding: "utf8",
|
|
191
|
+
timeout: 1000,
|
|
192
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
193
|
+
}).trim().toLowerCase();
|
|
194
|
+
return terminal ? terminal.replace(/[^a-z0-9]+/g, "_") : null;
|
|
195
|
+
} catch {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
}, "detectFromShell");
|
|
199
|
+
var detectFromProcessTitle = /* @__PURE__ */ __name(() => {
|
|
200
|
+
const processTitle = process.title?.toLowerCase() ?? "";
|
|
201
|
+
if (/^alacritty/.test(processTitle))
|
|
202
|
+
return "alacritty";
|
|
203
|
+
if (/^kitty/.test(processTitle))
|
|
204
|
+
return "kitty";
|
|
205
|
+
if (/^wezterm/.test(processTitle))
|
|
206
|
+
return "wezterm";
|
|
207
|
+
if (/^hyper/.test(processTitle))
|
|
208
|
+
return "hyper";
|
|
209
|
+
if (/bash/.test(processTitle))
|
|
210
|
+
return "bash";
|
|
211
|
+
if (/zsh/.test(processTitle))
|
|
212
|
+
return "zsh";
|
|
213
|
+
if (/ksh/.test(processTitle))
|
|
214
|
+
return "ksh";
|
|
215
|
+
if (/fish/.test(processTitle))
|
|
216
|
+
return "fish";
|
|
217
|
+
if (/csh/.test(processTitle))
|
|
218
|
+
return "csh";
|
|
219
|
+
if (/tcsh/.test(processTitle))
|
|
220
|
+
return "tcsh";
|
|
221
|
+
if (/pwsh/.test(processTitle))
|
|
222
|
+
return "powershell";
|
|
223
|
+
if (/powershell/.test(processTitle))
|
|
224
|
+
return "powershell";
|
|
225
|
+
if (/cmd/.test(processTitle))
|
|
226
|
+
return "cmd";
|
|
227
|
+
if (/sh$/.test(processTitle))
|
|
228
|
+
return "sh";
|
|
229
|
+
if (/^node/.test(processTitle))
|
|
230
|
+
return "node";
|
|
231
|
+
return null;
|
|
232
|
+
}, "detectFromProcessTitle");
|
|
233
|
+
var detectTerminal = /* @__PURE__ */ __name(() => {
|
|
234
|
+
let terminal = detectFromEnv();
|
|
235
|
+
if (!terminal) {
|
|
236
|
+
terminal = detectFromShell();
|
|
237
|
+
}
|
|
238
|
+
if (!terminal) {
|
|
239
|
+
terminal = detectFromProcessTitle();
|
|
240
|
+
}
|
|
241
|
+
return terminal || "unknown";
|
|
242
|
+
}, "detectTerminal");
|
|
243
|
+
var detect_terminal_default = detectTerminal;
|
|
244
|
+
});
|
|
245
|
+
|
|
21
246
|
// node_modules/shellwords/lib/shellwords.js
|
|
22
247
|
var require_shellwords = __commonJS((exports) => {
|
|
23
248
|
(function() {
|
|
@@ -3502,7 +3727,7 @@ var require_version = __commonJS((exports) => {
|
|
|
3502
3727
|
});
|
|
3503
3728
|
|
|
3504
3729
|
// node_modules/uuid/dist/index.js
|
|
3505
|
-
var
|
|
3730
|
+
var require_dist2 = __commonJS((exports) => {
|
|
3506
3731
|
Object.defineProperty(exports, "__esModule", {
|
|
3507
3732
|
value: true
|
|
3508
3733
|
});
|
|
@@ -3582,7 +3807,7 @@ var require_toaster = __commonJS((exports, module) => {
|
|
|
3582
3807
|
var utils = require_utils();
|
|
3583
3808
|
var Balloon = require_balloon();
|
|
3584
3809
|
var os = __require("os");
|
|
3585
|
-
var { v4: uuid } =
|
|
3810
|
+
var { v4: uuid } = require_dist2();
|
|
3586
3811
|
var EventEmitter = __require("events").EventEmitter;
|
|
3587
3812
|
var util = __require("util");
|
|
3588
3813
|
var fallback;
|
|
@@ -3742,6 +3967,7 @@ var DEFAULT_CONFIG = {
|
|
|
3742
3967
|
notification: true,
|
|
3743
3968
|
timeout: 5,
|
|
3744
3969
|
showProjectName: true,
|
|
3970
|
+
suppressWhenFocused: false,
|
|
3745
3971
|
command: {
|
|
3746
3972
|
enabled: false,
|
|
3747
3973
|
path: "",
|
|
@@ -3809,6 +4035,7 @@ function loadConfig() {
|
|
|
3809
4035
|
notification: globalNotification,
|
|
3810
4036
|
timeout: typeof userConfig.timeout === "number" && userConfig.timeout > 0 ? userConfig.timeout : DEFAULT_CONFIG.timeout,
|
|
3811
4037
|
showProjectName: userConfig.showProjectName ?? DEFAULT_CONFIG.showProjectName,
|
|
4038
|
+
suppressWhenFocused: typeof userConfig.suppressWhenFocused === "boolean" ? userConfig.suppressWhenFocused : DEFAULT_CONFIG.suppressWhenFocused,
|
|
3812
4039
|
command: {
|
|
3813
4040
|
enabled: typeof userCommand.enabled === "boolean" ? userCommand.enabled : DEFAULT_CONFIG.command.enabled,
|
|
3814
4041
|
path: typeof userCommand.path === "string" ? userCommand.path : DEFAULT_CONFIG.command.path,
|
|
@@ -3854,6 +4081,10 @@ function getSoundPath(config, event) {
|
|
|
3854
4081
|
return config.sounds[event];
|
|
3855
4082
|
}
|
|
3856
4083
|
|
|
4084
|
+
// src/index.ts
|
|
4085
|
+
var import_detect_terminal = __toESM(require_dist(), 1);
|
|
4086
|
+
import { execFile } from "child_process";
|
|
4087
|
+
|
|
3857
4088
|
// src/notify.ts
|
|
3858
4089
|
var import_node_notifier = __toESM(require_node_notifier(), 1);
|
|
3859
4090
|
import os from "os";
|
|
@@ -4030,6 +4261,12 @@ async function handleEvent(config, eventType, projectName, elapsedSeconds) {
|
|
|
4030
4261
|
const promises = [];
|
|
4031
4262
|
const message = getMessage(config, eventType);
|
|
4032
4263
|
if (isEventNotificationEnabled(config, eventType)) {
|
|
4264
|
+
if (config.suppressWhenFocused) {
|
|
4265
|
+
const shouldSuppress = await isTerminalFocused();
|
|
4266
|
+
if (shouldSuppress) {
|
|
4267
|
+
return;
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
4033
4270
|
const title = getNotificationTitle(config, projectName);
|
|
4034
4271
|
promises.push(sendNotification(title, message, config.timeout));
|
|
4035
4272
|
}
|
|
@@ -4044,6 +4281,99 @@ async function handleEvent(config, eventType, projectName, elapsedSeconds) {
|
|
|
4044
4281
|
}
|
|
4045
4282
|
await Promise.allSettled(promises);
|
|
4046
4283
|
}
|
|
4284
|
+
async function runExecCommand(command, args) {
|
|
4285
|
+
return new Promise((resolve) => {
|
|
4286
|
+
execFile(command, args, (error, stdout) => {
|
|
4287
|
+
if (error) {
|
|
4288
|
+
resolve(null);
|
|
4289
|
+
return;
|
|
4290
|
+
}
|
|
4291
|
+
resolve(stdout.trim());
|
|
4292
|
+
});
|
|
4293
|
+
});
|
|
4294
|
+
}
|
|
4295
|
+
async function runOsascript(script) {
|
|
4296
|
+
if (process.platform !== "darwin")
|
|
4297
|
+
return null;
|
|
4298
|
+
return runExecCommand("osascript", ["-e", script]);
|
|
4299
|
+
}
|
|
4300
|
+
async function getFrontmostAppMac() {
|
|
4301
|
+
return runOsascript('tell application "System Events" to get name of first application process whose frontmost is true');
|
|
4302
|
+
}
|
|
4303
|
+
async function getFrontmostProcessWindows() {
|
|
4304
|
+
if (process.platform !== "win32")
|
|
4305
|
+
return null;
|
|
4306
|
+
const script = [
|
|
4307
|
+
'Add-Type @"',
|
|
4308
|
+
"using System;",
|
|
4309
|
+
"using System.Runtime.InteropServices;",
|
|
4310
|
+
"public class Win32 {",
|
|
4311
|
+
' [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();',
|
|
4312
|
+
' [DllImport("user32.dll")] public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId);',
|
|
4313
|
+
"}",
|
|
4314
|
+
'"@',
|
|
4315
|
+
"$hwnd = [Win32]::GetForegroundWindow()",
|
|
4316
|
+
"$pid = 0",
|
|
4317
|
+
"[Win32]::GetWindowThreadProcessId($hwnd, [ref]$pid) | Out-Null",
|
|
4318
|
+
"(Get-Process -Id $pid).ProcessName"
|
|
4319
|
+
].join(`
|
|
4320
|
+
`);
|
|
4321
|
+
return runExecCommand("powershell", ["-NoProfile", "-Command", script]);
|
|
4322
|
+
}
|
|
4323
|
+
function extractQuotedStrings(input) {
|
|
4324
|
+
const matches = input.match(/"([^"]+)"/g);
|
|
4325
|
+
if (!matches)
|
|
4326
|
+
return [];
|
|
4327
|
+
return matches.map((value) => value.replace(/"/g, ""));
|
|
4328
|
+
}
|
|
4329
|
+
async function getActiveWindowClassLinux() {
|
|
4330
|
+
if (process.platform !== "linux")
|
|
4331
|
+
return null;
|
|
4332
|
+
const xdotoolClass = await runExecCommand("xdotool", ["getactivewindow", "getwindowclassname"]);
|
|
4333
|
+
if (xdotoolClass)
|
|
4334
|
+
return xdotoolClass;
|
|
4335
|
+
const activeWindow = await runExecCommand("xprop", ["-root", "_NET_ACTIVE_WINDOW"]);
|
|
4336
|
+
if (!activeWindow)
|
|
4337
|
+
return null;
|
|
4338
|
+
const idMatch = activeWindow.match(/0x[0-9a-fA-F]+/);
|
|
4339
|
+
if (!idMatch)
|
|
4340
|
+
return null;
|
|
4341
|
+
const wmClass = await runExecCommand("xprop", ["-id", idMatch[0], "WM_CLASS"]);
|
|
4342
|
+
if (!wmClass)
|
|
4343
|
+
return null;
|
|
4344
|
+
const names = extractQuotedStrings(wmClass);
|
|
4345
|
+
if (names.length === 0)
|
|
4346
|
+
return null;
|
|
4347
|
+
return names[names.length - 1];
|
|
4348
|
+
}
|
|
4349
|
+
function normalizeAppName(value) {
|
|
4350
|
+
return value.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
4351
|
+
}
|
|
4352
|
+
function matchesTerminal(frontmost, terminal) {
|
|
4353
|
+
const frontNormalized = normalizeAppName(frontmost);
|
|
4354
|
+
const terminalNormalized = normalizeAppName(terminal);
|
|
4355
|
+
if (!frontNormalized || !terminalNormalized)
|
|
4356
|
+
return false;
|
|
4357
|
+
return frontNormalized.includes(terminalNormalized) || terminalNormalized.includes(frontNormalized);
|
|
4358
|
+
}
|
|
4359
|
+
async function isTerminalFocused() {
|
|
4360
|
+
const terminalName = import_detect_terminal.default({ preferOuter: true });
|
|
4361
|
+
if (!terminalName)
|
|
4362
|
+
return false;
|
|
4363
|
+
if (process.platform === "darwin") {
|
|
4364
|
+
const frontmost = await getFrontmostAppMac();
|
|
4365
|
+
return frontmost ? matchesTerminal(frontmost, terminalName) : false;
|
|
4366
|
+
}
|
|
4367
|
+
if (process.platform === "win32") {
|
|
4368
|
+
const frontmostProcess = await getFrontmostProcessWindows();
|
|
4369
|
+
return frontmostProcess ? matchesTerminal(frontmostProcess, terminalName) : false;
|
|
4370
|
+
}
|
|
4371
|
+
if (process.platform === "linux") {
|
|
4372
|
+
const frontmostClass = await getActiveWindowClassLinux();
|
|
4373
|
+
return frontmostClass ? matchesTerminal(frontmostClass, terminalName) : false;
|
|
4374
|
+
}
|
|
4375
|
+
return false;
|
|
4376
|
+
}
|
|
4047
4377
|
function getSessionIDFromEvent(event) {
|
|
4048
4378
|
const sessionID = event?.properties?.sessionID;
|
|
4049
4379
|
if (typeof sessionID === "string" && sessionID.length > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mohak34/opencode-notifier",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
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",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"alerts"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
+
"detect-terminal": "^2.0.0",
|
|
35
36
|
"node-notifier": "^10.0.1"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|