@mohak34/opencode-notifier 0.1.30-beta.5 → 0.1.30

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.
Files changed (2) hide show
  1. package/dist/index.js +67 -208
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3728,7 +3728,7 @@ var require_node_notifier = __commonJS((exports, module) => {
3728
3728
 
3729
3729
  // src/index.ts
3730
3730
  import { basename } from "path";
3731
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
3731
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
3732
3732
 
3733
3733
  // src/config.ts
3734
3734
  import { readFileSync, existsSync } from "fs";
@@ -4222,49 +4222,6 @@ function runCommand2(config, event, message, sessionTitle, projectName, timestam
4222
4222
 
4223
4223
  // src/focus.ts
4224
4224
  import { execSync } from "child_process";
4225
- import { readFileSync as readFileSync2 } from "fs";
4226
- var TERMINAL_MAP = {
4227
- ghostty: { name: "Ghostty", macProcessNames: ["Ghostty", "ghostty"] },
4228
- kitty: { name: "kitty", macProcessNames: ["kitty"] },
4229
- alacritty: { name: "Alacritty", macProcessNames: ["Alacritty", "alacritty"] },
4230
- wezterm: { name: "WezTerm", macProcessNames: ["WezTerm", "wezterm-gui"] },
4231
- apple_terminal: { name: "Terminal", macProcessNames: ["Terminal"] },
4232
- iterm: { name: "iTerm2", macProcessNames: ["iTerm2", "iTerm"] },
4233
- warp: { name: "Warp", macProcessNames: ["Warp"] },
4234
- vscode: { name: "VS Code", macProcessNames: ["Code", "Code - Insiders", "Cursor", "cursor"] },
4235
- windows_terminal: { name: "Windows Terminal", macProcessNames: [] },
4236
- tmux: { name: "tmux", macProcessNames: [] }
4237
- };
4238
- var cachedTerminal = undefined;
4239
- function detectTerminal() {
4240
- if (cachedTerminal !== undefined)
4241
- return cachedTerminal;
4242
- const env = process.env;
4243
- let result = null;
4244
- if (env.GHOSTTY_RESOURCES_DIR) {
4245
- result = TERMINAL_MAP.ghostty;
4246
- } else if (env.KITTY_PID) {
4247
- result = TERMINAL_MAP.kitty;
4248
- } else if (env.ALACRITTY_SOCKET || env.ALACRITTY_LOG) {
4249
- result = TERMINAL_MAP.alacritty;
4250
- } else if (env.WEZTERM_EXECUTABLE) {
4251
- result = TERMINAL_MAP.wezterm;
4252
- } else if (env.WT_SESSION) {
4253
- result = TERMINAL_MAP.windows_terminal;
4254
- } else if (env.VSCODE_PID || env.TERM_PROGRAM === "vscode") {
4255
- result = TERMINAL_MAP.vscode;
4256
- } else if (env.TERM_PROGRAM === "Apple_Terminal") {
4257
- result = TERMINAL_MAP.apple_terminal;
4258
- } else if (env.TERM_PROGRAM === "iTerm.app") {
4259
- result = TERMINAL_MAP.iterm;
4260
- } else if (env.TERM_PROGRAM === "WarpTerminal") {
4261
- result = TERMINAL_MAP.warp;
4262
- } else if (env.TMUX || env.TERM_PROGRAM === "tmux") {
4263
- result = TERMINAL_MAP.tmux;
4264
- }
4265
- cachedTerminal = result;
4266
- return result;
4267
- }
4268
4225
  function execWithTimeout(command, timeoutMs = 500) {
4269
4226
  try {
4270
4227
  return execSync(command, { timeout: timeoutMs, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
@@ -4272,205 +4229,107 @@ function execWithTimeout(command, timeoutMs = 500) {
4272
4229
  return null;
4273
4230
  }
4274
4231
  }
4275
- function isMacOSFocused(terminal) {
4276
- const frontApp = execWithTimeout(`osascript -e 'tell application "System Events" to get name of first application process whose frontmost is true'`);
4277
- if (!frontApp)
4278
- return false;
4279
- return terminal.macProcessNames.some((name) => name.toLowerCase() === frontApp.toLowerCase());
4280
- }
4281
- function getParentPid(pid) {
4282
- try {
4283
- const stat = readFileSync2(`/proc/${pid}/stat`, "utf-8");
4284
- const closingParen = stat.lastIndexOf(")");
4285
- if (closingParen === -1)
4286
- return null;
4287
- const fields = stat.slice(closingParen + 2).split(" ");
4288
- const ppid = parseInt(fields[1], 10);
4289
- return Number.isFinite(ppid) ? ppid : null;
4290
- } catch {
4291
- return null;
4292
- }
4293
- }
4294
- function getProcessTreeRoot() {
4295
- if (process.env.TMUX) {
4296
- const clientPidStr = execWithTimeout("tmux display-message -p '#{client_pid}'");
4297
- if (clientPidStr) {
4298
- const clientPid = parseInt(clientPidStr, 10);
4299
- if (Number.isFinite(clientPid) && clientPid > 0)
4300
- return clientPid;
4301
- }
4302
- }
4303
- return process.pid;
4304
- }
4305
- function isPidAncestorOfProcess(targetPid, startPid) {
4306
- let currentPid = startPid;
4307
- for (let depth = 0;depth < 20; depth++) {
4308
- if (currentPid === targetPid)
4309
- return true;
4310
- if (currentPid <= 1)
4311
- return false;
4312
- const ppid = getParentPid(currentPid);
4313
- if (ppid === null)
4314
- return false;
4315
- currentPid = ppid;
4316
- }
4317
- return false;
4318
- }
4319
- function isFocusedWindowOurs(windowPid) {
4320
- return isPidAncestorOfProcess(windowPid, getProcessTreeRoot());
4321
- }
4322
- var tmuxPane = process.env.TMUX_PANE ?? null;
4323
- function isTmuxPaneActive() {
4324
- if (!tmuxPane)
4325
- return true;
4326
- const result = execWithTimeout(`tmux display-message -t ${tmuxPane} -p '#{session_attached} #{window_active} #{pane_active}'`);
4327
- if (!result)
4328
- return false;
4329
- const [sessionAttached, windowActive, paneActive] = result.split(" ");
4330
- return sessionAttached === "1" && windowActive === "1" && paneActive === "1";
4331
- }
4332
- function isLinuxX11Focused() {
4333
- const pidStr = execWithTimeout("xdotool getactivewindow getwindowpid");
4334
- if (!pidStr)
4335
- return false;
4336
- const pid = parseInt(pidStr, 10);
4337
- if (!Number.isFinite(pid) || pid <= 0)
4338
- return false;
4339
- return isFocusedWindowOurs(pid);
4340
- }
4341
- function isHyprlandFocused() {
4232
+ function getHyprlandActiveWindowId() {
4342
4233
  const output = execWithTimeout("hyprctl activewindow -j");
4343
4234
  if (!output)
4344
- return false;
4235
+ return null;
4345
4236
  try {
4346
4237
  const data = JSON.parse(output);
4347
- const pid = data?.pid;
4348
- if (typeof pid !== "number" || pid <= 0)
4349
- return false;
4350
- return isFocusedWindowOurs(pid);
4238
+ return typeof data?.address === "string" ? data.address : null;
4351
4239
  } catch {
4352
- return false;
4353
- }
4354
- }
4355
- function isSwayFocused() {
4356
- const output = execWithTimeout("swaymsg -t get_tree", 1000);
4357
- if (!output)
4358
- return false;
4359
- try {
4360
- const tree = JSON.parse(output);
4361
- const pid = findFocusedPid(tree);
4362
- if (pid === null)
4363
- return false;
4364
- return isFocusedWindowOurs(pid);
4365
- } catch {
4366
- return false;
4240
+ return null;
4367
4241
  }
4368
4242
  }
4369
- function findFocusedPid(node) {
4370
- if (node.focused === true && typeof node.pid === "number") {
4371
- return node.pid;
4243
+ function findFocusedWindowId(node) {
4244
+ if (node.focused === true && typeof node.id === "number") {
4245
+ return String(node.id);
4372
4246
  }
4373
4247
  if (Array.isArray(node.nodes)) {
4374
4248
  for (const child of node.nodes) {
4375
- const pid = findFocusedPid(child);
4376
- if (pid !== null)
4377
- return pid;
4249
+ const id = findFocusedWindowId(child);
4250
+ if (id !== null)
4251
+ return id;
4378
4252
  }
4379
4253
  }
4380
4254
  if (Array.isArray(node.floating_nodes)) {
4381
4255
  for (const child of node.floating_nodes) {
4382
- const pid = findFocusedPid(child);
4383
- if (pid !== null)
4384
- return pid;
4256
+ const id = findFocusedWindowId(child);
4257
+ if (id !== null)
4258
+ return id;
4385
4259
  }
4386
4260
  }
4387
4261
  return null;
4388
4262
  }
4389
- function isKDEWaylandFocused() {
4390
- const windowId = execWithTimeout("kdotool getactivewindow");
4391
- if (!windowId)
4392
- return false;
4393
- const pidStr = execWithTimeout(`kdotool getwindowpid ${windowId}`);
4394
- if (!pidStr)
4395
- return false;
4396
- const pid = parseInt(pidStr, 10);
4397
- if (!Number.isFinite(pid) || pid <= 0)
4398
- return false;
4399
- return isFocusedWindowOurs(pid);
4263
+ function getSwayActiveWindowId() {
4264
+ const output = execWithTimeout("swaymsg -t get_tree", 1000);
4265
+ if (!output)
4266
+ return null;
4267
+ try {
4268
+ const tree = JSON.parse(output);
4269
+ return findFocusedWindowId(tree);
4270
+ } catch {
4271
+ return null;
4272
+ }
4400
4273
  }
4401
- function isLinuxWaylandFocused() {
4274
+ function getLinuxWaylandActiveWindowId() {
4402
4275
  const env = process.env;
4403
- if (env.HYPRLAND_INSTANCE_SIGNATURE) {
4404
- return isHyprlandFocused();
4405
- }
4406
- if (env.SWAYSOCK) {
4407
- return isSwayFocused();
4408
- }
4409
- if (env.KDE_SESSION_VERSION) {
4410
- return isKDEWaylandFocused();
4411
- }
4412
- return false;
4276
+ if (env.HYPRLAND_INSTANCE_SIGNATURE)
4277
+ return getHyprlandActiveWindowId();
4278
+ if (env.SWAYSOCK)
4279
+ return getSwayActiveWindowId();
4280
+ if (env.KDE_SESSION_VERSION)
4281
+ return execWithTimeout("kdotool getactivewindow");
4282
+ return null;
4413
4283
  }
4414
- function isWindowsFocused() {
4284
+ function getWindowsActiveWindowId() {
4415
4285
  const script = `
4416
4286
  Add-Type @"
4417
4287
  using System;
4418
4288
  using System.Runtime.InteropServices;
4419
4289
  public class FocusHelper {
4420
4290
  [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();
4421
- [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint pid);
4422
4291
  }
4423
4292
  "@
4424
4293
  $hwnd = [FocusHelper]::GetForegroundWindow()
4425
- $pid = 0
4426
- [void][FocusHelper]::GetWindowThreadProcessId($hwnd, [ref]$pid)
4427
- Write-Output $pid
4294
+ Write-Output $hwnd
4428
4295
  `.trim().replace(/\n/g, "; ");
4429
- const pidStr = execWithTimeout(`powershell -NoProfile -Command "${script}"`, 1000);
4430
- if (!pidStr)
4431
- return false;
4432
- const pid = parseInt(pidStr, 10);
4433
- if (!Number.isFinite(pid) || pid <= 0)
4434
- return false;
4435
- const startPid = getProcessTreeRoot();
4436
- let currentPid = startPid;
4437
- for (let depth = 0;depth < 20; depth++) {
4438
- if (currentPid === pid)
4439
- return true;
4440
- if (currentPid <= 1)
4441
- return false;
4442
- const parentPidStr = execWithTimeout(`powershell -NoProfile -Command "(Get-Process -Id ${currentPid}).Parent.Id"`, 500);
4443
- if (!parentPidStr)
4444
- return false;
4445
- currentPid = parseInt(parentPidStr, 10);
4446
- if (!Number.isFinite(currentPid))
4447
- return false;
4296
+ return execWithTimeout(`powershell -NoProfile -Command "${script}"`, 1000);
4297
+ }
4298
+ function getMacOSActiveWindowId() {
4299
+ return execWithTimeout(`osascript -e 'tell application "System Events" to return id of window 1 of (first application process whose frontmost is true)'`);
4300
+ }
4301
+ function getActiveWindowId() {
4302
+ const platform3 = process.platform;
4303
+ if (platform3 === "darwin")
4304
+ return getMacOSActiveWindowId();
4305
+ if (platform3 === "linux") {
4306
+ if (process.env.WAYLAND_DISPLAY)
4307
+ return getLinuxWaylandActiveWindowId();
4308
+ if (process.env.DISPLAY)
4309
+ return execWithTimeout("xdotool getactivewindow");
4310
+ return null;
4448
4311
  }
4449
- return false;
4312
+ if (platform3 === "win32")
4313
+ return getWindowsActiveWindowId();
4314
+ return null;
4315
+ }
4316
+ var cachedWindowId = getActiveWindowId();
4317
+ var tmuxPane = process.env.TMUX_PANE ?? null;
4318
+ function isTmuxPaneActive() {
4319
+ if (!tmuxPane)
4320
+ return true;
4321
+ const result = execWithTimeout(`tmux display-message -t ${tmuxPane} -p '#{session_attached} #{window_active} #{pane_active}'`);
4322
+ if (!result)
4323
+ return false;
4324
+ const [sessionAttached, windowActive, paneActive] = result.split(" ");
4325
+ return sessionAttached === "1" && windowActive === "1" && paneActive === "1";
4450
4326
  }
4451
4327
  function isTerminalFocused() {
4452
4328
  try {
4453
- const platform3 = process.platform;
4454
- let windowFocused = false;
4455
- if (platform3 === "darwin") {
4456
- const terminal = detectTerminal();
4457
- if (!terminal || terminal.macProcessNames.length === 0)
4458
- return false;
4459
- windowFocused = isMacOSFocused(terminal);
4460
- } else if (platform3 === "linux") {
4461
- if (process.env.WAYLAND_DISPLAY) {
4462
- windowFocused = isLinuxWaylandFocused();
4463
- } else if (process.env.DISPLAY) {
4464
- windowFocused = isLinuxX11Focused();
4465
- } else {
4466
- return false;
4467
- }
4468
- } else if (platform3 === "win32") {
4469
- windowFocused = isWindowsFocused();
4470
- } else {
4329
+ if (!cachedWindowId)
4471
4330
  return false;
4472
- }
4473
- if (!windowFocused)
4331
+ const currentId = getActiveWindowId();
4332
+ if (currentId !== cachedWindowId)
4474
4333
  return false;
4475
4334
  if (process.env.TMUX)
4476
4335
  return isTmuxPaneActive();
@@ -4489,7 +4348,7 @@ var sessionLastBusyAt = new Map;
4489
4348
  var globalTurnCount = null;
4490
4349
  function loadTurnCount() {
4491
4350
  try {
4492
- const content = readFileSync3(getStatePath(), "utf-8");
4351
+ const content = readFileSync2(getStatePath(), "utf-8");
4493
4352
  const state = JSON.parse(content);
4494
4353
  if (typeof state.turn === "number" && Number.isFinite(state.turn) && state.turn >= 0) {
4495
4354
  return state.turn;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohak34/opencode-notifier",
3
- "version": "0.1.30-beta.5",
3
+ "version": "0.1.30",
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",