dsh-qq-stack 0.1.1 → 0.1.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 (4) hide show
  1. package/README.md +10 -0
  2. package/index.js +12 -0
  3. package/package.json +4 -3
  4. package/watch.mjs +22 -0
package/README.md CHANGED
@@ -54,3 +54,13 @@ dsh plugin --profile web add dsh-qq-stack
54
54
  ## 许可
55
55
 
56
56
  MIT
57
+
58
+ ## 卸载
59
+
60
+ 插件卸载后,后台会有一个清理器(20 秒内)自动停掉 QQ、删掉 `~/.dsh/qq-bot`(含 700MB+ 的客户端和登录数据)。
61
+
62
+ 如果想立刻清,也可以在卸载前手动执行:
63
+
64
+ ```bash
65
+ bash ~/.dsh/qq-bot/stop-qq.sh && rm -rf ~/.dsh/qq-bot
66
+ ```
package/index.js CHANGED
@@ -149,6 +149,18 @@ function applyInner(ctx, pluginConfig = {}) {
149
149
  } catch (e) { log(`[qq-stack] 安装启动失败:${e?.message ?? e}`) }
150
150
  }
151
151
 
152
+ ctx.effect(() => {
153
+ try {
154
+ const watchPid = `${cfg.root}/watch.pid`
155
+ let pid = 0
156
+ try { pid = Number(readFileSync(watchPid, 'utf8').trim()) || 0 } catch {}
157
+ if (alive(pid)) return
158
+ const child = spawn(process.execPath, [`${SELF}watch.mjs`, SELF, cfg.root], { detached: true, stdio: 'ignore' })
159
+ child.unref()
160
+ try { writeFileSync(watchPid, String(child.pid)) } catch {}
161
+ } catch (e) { log(`[qq-stack] 卸载清理器启动失败:${e?.message ?? e}`) }
162
+ }, 'dsh-qq-stack: uninstall-watch')
163
+
152
164
  ctx.effect(() => {
153
165
  const timer = setInterval(async () => {
154
166
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-qq-stack",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "description": "DeepSeek Harness 的 QQ 协议端底座:LinuxQQ + NapCat 随引擎自启,扫码一次后自动快登。",
@@ -22,7 +22,8 @@
22
22
  "install.sh",
23
23
  "cordis.patch.yml",
24
24
  "README.md",
25
- "LICENSE"
25
+ "LICENSE",
26
+ "watch.mjs"
26
27
  ],
27
28
  "exports": {
28
29
  ".": "./index.js",
@@ -44,4 +45,4 @@
44
45
  "scripts": {
45
46
  "test": "node --input-type=module -e \"await import('./index.js')\""
46
47
  }
47
- }
48
+ }
package/watch.mjs ADDED
@@ -0,0 +1,22 @@
1
+ import { existsSync, readFileSync } from 'node:fs'
2
+ import { spawnSync, spawn } from 'node:child_process'
3
+
4
+ const [pkgDir, root] = process.argv.slice(2)
5
+ if (!pkgDir || !root) process.exit(0)
6
+
7
+ const alive = (pid) => {
8
+ try { process.kill(Number(pid), 0); return true } catch { return false }
9
+ }
10
+
11
+ function cleanup() {
12
+ try { spawnSync('bash', [`${root}/stop-qq.sh`], { timeout: 30000 }) } catch {}
13
+ try { spawnSync('bash', ['-c', `rm -rf "${root}"`], { timeout: 120000 }) } catch {}
14
+ try {
15
+ const pids = spawnSync('bash', ['-c', "ps -eo pid=,comm= | awk '$2==\"Xvfb\"{print $1}'"], { encoding: 'utf8' }).stdout
16
+ for (const p of String(pids).split(/\s+/).filter(Boolean)) { try { process.kill(Number(p), 'SIGKILL') } catch {} }
17
+ } catch {}
18
+ }
19
+
20
+ setInterval(() => {
21
+ if (!existsSync(`${pkgDir}/package.json`)) { cleanup(); process.exit(0) }
22
+ }, 20000)