opencode-zombie-monitor 1.0.1 → 1.0.2

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/index.mjs +27 -23
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -18,29 +18,32 @@ const getLang = () => {
18
18
  return "en"
19
19
  }
20
20
 
21
+ // Format memory size
22
+ const formatMB = (mb) => mb >= 1024 ? `${(mb / 1024).toFixed(1)}GB` : `${Math.round(mb)}MB`
23
+
21
24
  // Localized messages
22
25
  const i18n = {
23
26
  en: {
24
- killed: (n) => `🧟 Killed ${n} zombie opencode process${n > 1 ? "es" : ""} | Freed ~${n * 100}MB RAM`,
25
- found: (n) => `🧟 ${n} zombie opencode process${n > 1 ? "es" : ""} | ~${n * 100}MB RAM | Fix: oc-kill-zombies`,
26
- status: (zombies, total) => zombies > 0
27
- ? `🧟 ${zombies} zombie${zombies > 1 ? "s" : ""} of ${total} process${total > 1 ? "es" : ""} | ~${zombies * 100}MB RAM | Fix: oc-kill-zombies`
27
+ killed: (n, mb) => `🧟 Killed ${n} zombie opencode process${n > 1 ? "es" : ""} | Freed ${formatMB(mb)} RAM`,
28
+ found: (n, mb) => `🧟 ${n} zombie opencode process${n > 1 ? "es" : ""} | ${formatMB(mb)} RAM | Fix: oc-kill-zombies`,
29
+ status: (zombies, total, mb) => zombies > 0
30
+ ? `🧟 ${zombies} zombie${zombies > 1 ? "s" : ""} of ${total} process${total > 1 ? "es" : ""} | ${formatMB(mb)} RAM | Fix: oc-kill-zombies`
28
31
  : `✅ ${total} process${total > 1 ? "es" : ""}, no zombies`,
29
32
  commandDesc: "Check zombie opencode processes"
30
33
  },
31
34
  ru: {
32
- killed: (n) => `🧟 Убито ${n} зомби-процессов opencode | Освобождено ~${n * 100}MB RAM`,
33
- found: (n) => `🧟 ${n} зомби-процессов opencode | ~${n * 100}MB RAM | Fix: oc-kill-zombies`,
34
- status: (zombies, total) => zombies > 0
35
- ? `🧟 ${zombies} зомби из ${total} процессов | ~${zombies * 100}MB RAM | Fix: oc-kill-zombies`
35
+ killed: (n, mb) => `🧟 Убито ${n} зомби-процессов opencode | Освобождено ${formatMB(mb)} RAM`,
36
+ found: (n, mb) => `🧟 ${n} зомби-процессов opencode | ${formatMB(mb)} RAM | Fix: oc-kill-zombies`,
37
+ status: (zombies, total, mb) => zombies > 0
38
+ ? `🧟 ${zombies} зомби из ${total} процессов | ${formatMB(mb)} RAM | Fix: oc-kill-zombies`
36
39
  : `✅ ${total} процессов, зомби нет`,
37
40
  commandDesc: "Проверить зомби-процессы opencode"
38
41
  },
39
42
  zh: {
40
- killed: (n) => `🧟 已击杀 ${n} 个僵尸 opencode 进程 | 释放 ~${n * 100}MB 内存`,
41
- found: (n) => `🧟 发现 ${n} 个僵尸 opencode 进程 | ~${n * 100}MB 内存 | 修复: oc-kill-zombies`,
42
- status: (zombies, total) => zombies > 0
43
- ? `🧟 ${total} 个进程中有 ${zombies} 个僵尸 | ~${zombies * 100}MB 内存 | 修复: oc-kill-zombies`
43
+ killed: (n, mb) => `🧟 已击杀 ${n} 个僵尸 opencode 进程 | 释放 ${formatMB(mb)} 内存`,
44
+ found: (n, mb) => `🧟 发现 ${n} 个僵尸 opencode 进程 | ${formatMB(mb)} 内存 | 修复: oc-kill-zombies`,
45
+ status: (zombies, total, mb) => zombies > 0
46
+ ? `🧟 ${total} 个进程中有 ${zombies} 个僵尸 | ${formatMB(mb)} 内存 | 修复: oc-kill-zombies`
44
47
  : `✅ ${total} 个进程,没有僵尸`,
45
48
  commandDesc: "检查僵尸 opencode 进程"
46
49
  }
@@ -48,15 +51,16 @@ const i18n = {
48
51
 
49
52
  const t = i18n[getLang()]
50
53
 
51
- // Count only processes WITHOUT terminal (real zombies)
52
- const getZombieCount = async () => {
54
+ // Get zombie count and their total memory (RSS in MB)
55
+ const getZombieStats = async () => {
53
56
  try {
54
- // macOS: TTY = "??" | Linux: TTY = "?"
55
57
  const ttyPattern = isMac ? '??' : '?'
56
- const { stdout } = await execAsync(`ps aux | grep "[o]pencode" | grep -v "opencode/" | awk '$7 == "${ttyPattern}" {count++} END {print count+0}'`)
57
- return parseInt(stdout.trim()) || 0
58
+ // $6 = RSS in KB on both macOS and Linux
59
+ const { stdout } = await execAsync(`ps aux | grep "[o]pencode" | grep -v "opencode/" | awk '$7 == "${ttyPattern}" {count++; mem+=$6} END {print count+0, mem/1024}'`)
60
+ const [count, mb] = stdout.trim().split(/\s+/)
61
+ return { count: parseInt(count) || 0, mb: parseFloat(mb) || 0 }
58
62
  } catch {
59
- return 0
63
+ return { count: 0, mb: 0 }
60
64
  }
61
65
  }
62
66
 
@@ -119,13 +123,13 @@ export const ZombieMonitor = async ({ client }) => {
119
123
  const sessionId = getSessionIdFromMessages(output.messages)
120
124
  if (!sessionId) return
121
125
 
122
- const zombies = await getZombieCount()
126
+ const { count: zombies, mb } = await getZombieStats()
123
127
 
124
128
  // Auto-kill if zombies >= threshold
125
129
  if (zombies >= AUTO_KILL_THRESHOLD) {
126
130
  await killZombies()
127
131
  try {
128
- await sendNotification(client, sessionId, t.killed(zombies))
132
+ await sendNotification(client, sessionId, t.killed(zombies, mb))
129
133
  } catch (e) {}
130
134
  lastNotifiedCount = 0
131
135
  }
@@ -133,7 +137,7 @@ export const ZombieMonitor = async ({ client }) => {
133
137
  else if (zombies > 0 && zombies > lastNotifiedCount) {
134
138
  lastNotifiedCount = zombies
135
139
  try {
136
- await sendNotification(client, sessionId, t.found(zombies))
140
+ await sendNotification(client, sessionId, t.found(zombies, mb))
137
141
  } catch (e) {}
138
142
  } else if (zombies === 0) {
139
143
  lastNotifiedCount = 0
@@ -143,10 +147,10 @@ export const ZombieMonitor = async ({ client }) => {
143
147
  "command.execute.before": async (input) => {
144
148
  if (input.command !== "zombies") return
145
149
 
146
- const zombies = await getZombieCount()
150
+ const { count: zombies, mb } = await getZombieStats()
147
151
  const total = await getTotalCount()
148
152
 
149
- await sendNotification(client, input.sessionID, t.status(zombies, total))
153
+ await sendNotification(client, input.sessionID, t.status(zombies, total, mb))
150
154
  throw new Error("__ZOMBIES_HANDLED__")
151
155
  }
152
156
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-zombie-monitor",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Auto-kill zombie opencode processes. Supports macOS and Linux with auto language detection (EN/RU).",
5
5
  "main": "index.mjs",
6
6
  "type": "module",