claw-subagent-service 0.0.134 → 0.0.136

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.
@@ -246,14 +246,53 @@ start_docker() {
246
246
  cat /tmp/openclaw-run-help.txt | head -30
247
247
  fi
248
248
 
249
+ # 先停止所有已有的 openclaw 进程,避免端口冲突
250
+ log_info "检查并停止已有的 openclaw 进程..."
251
+ local existing_pids=""
252
+ if command -v pgrep &>/dev/null; then
253
+ existing_pids=$(pgrep -f "openclaw" | tr '\n' ' ')
254
+ elif command -v pidof &>/dev/null; then
255
+ existing_pids=$(pidof openclaw)
256
+ else
257
+ existing_pids=$(ps aux | grep -v grep | grep "openclaw" | awk '{print $2}' | tr '\n' ' ')
258
+ fi
259
+
260
+ if [ -n "$existing_pids" ]; then
261
+ log_warn "发现已有 openclaw 进程: $existing_pids,先停止它们..."
262
+ for ep in $existing_pids; do
263
+ log_info "停止进程 $ep..."
264
+ kill -15 "$ep" 2>/dev/null || true
265
+ done
266
+ # 等待 3 秒让进程优雅退出
267
+ sleep 3
268
+ # 检查是否还有残留进程,如果有则强制停止
269
+ local remaining_pids=""
270
+ if command -v pgrep &>/dev/null; then
271
+ remaining_pids=$(pgrep -f "openclaw" | tr '\n' ' ')
272
+ fi
273
+ if [ -n "$remaining_pids" ]; then
274
+ log_warn "强制停止残留进程: $remaining_pids"
275
+ for rp in $remaining_pids; do
276
+ kill -9 "$rp" 2>/dev/null || true
277
+ done
278
+ sleep 1
279
+ fi
280
+ fi
281
+
282
+ # 确保端口未被占用
283
+ if command -v fuser &>/dev/null; then
284
+ fuser -k "${PORT}/tcp" 2>/dev/null || true
285
+ fi
286
+
249
287
  # 尝试使用正确的参数启动
250
288
  # 注意:openclaw gateway 可能使用不同的参数名
251
- # 在 Docker 环境中,使用 run 子命令前台运行,而不是后台启动
252
289
  log_info "尝试启动: openclaw gateway run --port $PORT"
290
+
291
+ # 使用 nohup 后台启动,将输出重定向到日志文件
253
292
  nohup openclaw gateway run --port "$PORT" > "$log_file" 2>&1 &
254
293
 
255
- # 等待 10 秒检查进程是否启动(给更多时间)
256
- sleep 10
294
+ # 等待 15 秒检查进程是否启动(给更多时间初始化)
295
+ sleep 15
257
296
  local started_pid=$!
258
297
  log_info "启动的进程 PID: $started_pid"
259
298
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claw-subagent-service",
3
- "version": "0.0.134",
3
+ "version": "0.0.136",
4
4
  "description": "虾说智能助手",
5
5
  "main": "cli.js",
6
6
  "bin": {
package/service/daemon.js CHANGED
@@ -28,6 +28,31 @@ let crashCount = 0;
28
28
  let lastCrashTime = 0;
29
29
  const updater = new Updater();
30
30
 
31
+ // 检测是否是 npm 更新后的重启
32
+ const VERSION_FILE = path.join(os.tmpdir(), '.claw-subagent-service.version');
33
+ function detectUpdateRestart() {
34
+ try {
35
+ const currentVersion = updater.loadCurrentVersion();
36
+ let previousVersion = null;
37
+
38
+ if (fs.existsSync(VERSION_FILE)) {
39
+ previousVersion = fs.readFileSync(VERSION_FILE, 'utf8').trim();
40
+ }
41
+
42
+ // 写入当前版本
43
+ fs.writeFileSync(VERSION_FILE, currentVersion);
44
+
45
+ // 如果之前有版本记录,且当前版本不同,说明是更新后的重启
46
+ if (previousVersion && previousVersion !== currentVersion) {
47
+ log.info(`[DAEMON] 检测到版本变化: ${previousVersion} → ${currentVersion},这是更新后的重启`);
48
+ return true;
49
+ }
50
+ } catch (err) {
51
+ log.warn(`[DAEMON] 检测版本变化失败: ${err.message}`);
52
+ }
53
+ return false;
54
+ }
55
+
31
56
  process.chdir(__dirname);
32
57
 
33
58
  /**
@@ -359,7 +384,14 @@ process.on('message', (msg) => {
359
384
  if (msg === 'shutdown') gracefulShutdown();
360
385
  });
361
386
 
362
- startWorker(false, null);
387
+ // 检测是否是 npm 更新后的重启
388
+ const isAfterNpmUpdate = detectUpdateRestart();
389
+ if (isAfterNpmUpdate) {
390
+ log.info('[DAEMON] npm 更新后的重启,启动 Worker 并设置健康观察...');
391
+ startWorker(true, null);
392
+ } else {
393
+ startWorker(false, null);
394
+ }
363
395
  updater.startSchedule(restartWorkerWithUpdate);
364
396
 
365
397
  process.on('uncaughtException', (err) => {
@@ -58,14 +58,61 @@ function getCommandName(command) {
58
58
 
59
59
  /**
60
60
  * 检测是否在 Docker 环境(无 systemd)
61
+ * 使用多种方法检测,提高可靠性
61
62
  */
62
63
  function isDockerEnvironment() {
63
64
  try {
64
65
  const fs = require('fs');
65
- // 检查 /proc/1/cgroup 是否包含 docker
66
- const cgroup = fs.readFileSync('/proc/1/cgroup', 'utf8');
67
- return cgroup.includes('docker');
66
+ const { execSync } = require('child_process');
67
+
68
+ // 方法1: 检查 /proc/1/cgroup 是否包含 docker
69
+ try {
70
+ const cgroup = fs.readFileSync('/proc/1/cgroup', 'utf8');
71
+ if (cgroup.includes('docker') || cgroup.includes('containerd')) {
72
+ console.log('[OpenClawControl] Docker 检测: /proc/1/cgroup 包含 docker/containerd');
73
+ return true;
74
+ }
75
+ } catch (e) {
76
+ // 文件不存在或读取失败
77
+ }
78
+
79
+ // 方法2: 检查 /.dockerenv 文件是否存在
80
+ try {
81
+ fs.accessSync('/.dockerenv', fs.constants.F_OK);
82
+ console.log('[OpenClawControl] Docker 检测: /.dockerenv 文件存在');
83
+ return true;
84
+ } catch (e) {
85
+ // 文件不存在
86
+ }
87
+
88
+ // 方法3: 检查环境变量
89
+ if (process.env.DOCKER_CONTAINER || process.env.KUBERNETES_SERVICE_HOST) {
90
+ console.log('[OpenClawControl] Docker 检测: 环境变量指示 Docker/K8s');
91
+ return true;
92
+ }
93
+
94
+ // 方法4: 检查 systemd 是否运行(Docker 通常没有 systemd)
95
+ try {
96
+ // 如果 systemctl 命令不存在,可能是 Docker
97
+ execSync('command -v systemctl', { stdio: 'ignore' });
98
+ // systemctl 存在,检查是否实际运行
99
+ try {
100
+ execSync('systemctl status', { stdio: 'ignore', timeout: 2000 });
101
+ // systemd 正在运行,不是 Docker
102
+ console.log('[OpenClawControl] Docker 检测: systemd 正在运行,不是 Docker');
103
+ return false;
104
+ } catch (e) {
105
+ // systemctl 存在但无法使用,可能是 Docker
106
+ console.log('[OpenClawControl] Docker 检测: systemctl 存在但无法使用,可能是 Docker');
107
+ return true;
108
+ }
109
+ } catch (e) {
110
+ // systemctl 命令不存在,可能是 Docker
111
+ console.log('[OpenClawControl] Docker 检测: systemctl 命令不存在,可能是 Docker');
112
+ return true;
113
+ }
68
114
  } catch (e) {
115
+ console.error('[OpenClawControl] Docker 检测异常:', e.message);
69
116
  return false;
70
117
  }
71
118
  }