claw-subagent-service 0.0.124 → 0.0.125

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.
@@ -224,9 +224,9 @@ stop_docker() {
224
224
  kill -15 "$p" 2>/dev/null || log_warn "kill -15 $p 失败"
225
225
  done
226
226
 
227
- # 等待 3 秒让服务优雅退出
228
- log_info "等待 3 秒让服务优雅退出..."
229
- sleep 3
227
+ # 等待 5 秒让服务优雅退出
228
+ log_info "等待 5 秒让服务优雅退出..."
229
+ sleep 5
230
230
 
231
231
  # 检查是否已停止
232
232
  local pid_after_graceful
@@ -243,7 +243,20 @@ stop_docker() {
243
243
 
244
244
  # 强制停止模式(直接发送 SIGKILL)
245
245
  log_info "正在强制停止 OpenClaw 服务(SIGKILL)..."
246
- for p in $all_pids; do
246
+
247
+ # 获取最新的进程列表(因为优雅停止后可能有新进程)
248
+ local current_pids=""
249
+ if command -v pgrep &>/dev/null; then
250
+ current_pids=$(pgrep -f "openclaw" | tr '\n' ' ')
251
+ elif command -v pidof &>/dev/null; then
252
+ current_pids=$(pidof openclaw)
253
+ else
254
+ current_pids=$(ps aux | grep -v grep | grep "openclaw" | awk '{print $2}' | tr '\n' ' ')
255
+ fi
256
+
257
+ log_info "当前 openclaw 进程: $current_pids"
258
+
259
+ for p in $current_pids; do
247
260
  log_info "执行: kill -9 $p"
248
261
  kill -9 "$p" 2>/dev/null || log_warn "kill -9 $p 失败"
249
262
  done
@@ -253,12 +266,15 @@ stop_docker() {
253
266
  log_info "执行: killall -9 openclaw"
254
267
  killall -9 openclaw 2>/dev/null || log_warn "killall 失败"
255
268
 
269
+ # 等待 2 秒让进程退出
270
+ sleep 2
271
+
256
272
  # 连续监控模式:每秒检查并杀死看门狗重启的进程
257
273
  # 这样即使看门狗立即重启,也会被再次杀死
258
- log_info "进入连续监控模式(最多 15 秒),防止看门狗自动重启..."
274
+ log_info "进入连续监控模式(最多 20 秒),防止看门狗自动重启..."
259
275
  local elapsed=0
260
276
  local consecutive_empty=0
261
- while [ $elapsed -lt 15 ]; do
277
+ while [ $elapsed -lt 20 ]; do
262
278
  sleep 1
263
279
 
264
280
  # 检查是否还有 openclaw 进程
@@ -291,6 +307,9 @@ stop_docker() {
291
307
  consecutive_empty=0
292
308
  if [ -n "$remaining_pids" ]; then
293
309
  log_info "第 $elapsed 秒: 发现新进程 $remaining_pids,再次 kill..."
310
+ for rp in $remaining_pids; do
311
+ kill -9 "$rp" 2>/dev/null || true
312
+ done
294
313
  fi
295
314
  if [ "$port_listening" = true ]; then
296
315
  log_info "第 $elapsed 秒: 端口 $PORT 仍在监听,尝试 fuser 终止..."
@@ -305,6 +324,14 @@ stop_docker() {
305
324
  elapsed=$((elapsed + 1))
306
325
  done
307
326
 
327
+ # 最终验证前,再执行一次全面清理
328
+ log_info "执行最终清理..."
329
+ pkill -9 -f "openclaw" 2>/dev/null || true
330
+ killall -9 openclaw 2>/dev/null || true
331
+
332
+ # 等待 2 秒
333
+ sleep 2
334
+
308
335
  # 最终验证
309
336
  local remaining_pids=""
310
337
  if command -v pgrep &>/dev/null; then
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claw-subagent-service",
3
- "version": "0.0.124",
3
+ "version": "0.0.125",
4
4
  "description": "虾说智能助手",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -20,13 +20,14 @@ class HeartbeatManager {
20
20
 
21
21
  try {
22
22
  const mac = getMacAddress();
23
+ // 真实检测 openclaw 状态(通过端口检查)
23
24
  const status = await getOpenClawStatus(this.config.openclawPort || 18789);
24
25
  const sent = await this.messageSender.sendProtocolMessage(
25
26
  RongyunMessageTypeEnum.HEARTBEAT,
26
27
  {
27
28
  mac_address: mac,
28
29
  nickname: this.config.nodeName,
29
- open_claw_status: status,
30
+ open_claw_status: status, // 1=运行中, 0=未运行(真实检测)
30
31
  client_status: 1,
31
32
  }
32
33
  );
@@ -168,26 +168,46 @@ async function verifyCommandResult(command, result, scriptOutput = '') {
168
168
  }
169
169
 
170
170
  if (portStatus === 1) {
171
- console.error(`[OpenClawControl] 停止失败: 端口 18789 仍在监听。尝试强制停止...`);
171
+ console.error(`[OpenClawControl] 停止失败: 端口 18789 仍在监听。尝试直接强制终止进程...`);
172
172
 
173
- // 尝试强制停止
174
- const forceScriptResult = await executeWithScript(command);
175
- const forceResult = forceScriptResult.result;
176
- console.log(`[OpenClawControl] 强制停止结果: ${forceResult.status} - ${forceResult.message}`);
177
-
178
- // 再次验证端口
179
- await new Promise(resolve => setTimeout(resolve, 3000));
180
- const finalPortStatus = await getOpenClawStatus(18789);
181
-
182
- if (finalPortStatus !== 1) {
183
- console.log(`[OpenClawControl] 强制停止成功: 端口已关闭`);
184
- return {
185
- status: OpenClawServiceStatus.STOP_SUCCESS,
186
- message: '服务已停止(强制停止)'
187
- };
173
+ // 直接执行强制终止命令(不通过脚本)
174
+ try {
175
+ const { execSync } = require('child_process');
176
+
177
+ // 先尝试 pkill
178
+ try {
179
+ execSync('pkill -9 -f "openclaw"', { timeout: 5000 });
180
+ console.log('[OpenClawControl] pkill -9 -f openclaw 执行成功');
181
+ } catch (e) {
182
+ console.log('[OpenClawControl] pkill 执行失败或没有匹配进程');
183
+ }
184
+
185
+ // 再尝试 killall
186
+ try {
187
+ execSync('killall -9 openclaw', { timeout: 5000 });
188
+ console.log('[OpenClawControl] killall -9 openclaw 执行成功');
189
+ } catch (e) {
190
+ console.log('[OpenClawControl] killall 执行失败或没有匹配进程');
191
+ }
192
+
193
+ // 等待进程退出
194
+ await new Promise(resolve => setTimeout(resolve, 5000));
195
+
196
+ // 再次验证端口
197
+ const finalPortStatus = await getOpenClawStatus(18789);
198
+
199
+ if (finalPortStatus !== 1) {
200
+ console.log(`[OpenClawControl] 强制停止成功: 端口已关闭`);
201
+ return {
202
+ status: OpenClawServiceStatus.STOP_SUCCESS,
203
+ message: '服务已停止(强制停止)'
204
+ };
205
+ }
206
+ } catch (err) {
207
+ console.error(`[OpenClawControl] 强制停止异常: ${err.message}`);
188
208
  }
189
209
 
190
- console.error(`[OpenClawControl] 停止失败: 端口 18789 仍在监听。stop.sh 可能未能成功停止服务。`);
210
+ console.error(`[OpenClawControl] 停止失败: 端口 18789 仍在监听。所有停止方法均已尝试。`);
191
211
  return {
192
212
  status: OpenClawServiceStatus.ERROR,
193
213
  message: '停止失败: 服务仍在运行'
@@ -276,12 +296,33 @@ async function executeCommand(command, window, sendResponse) {
276
296
  if (sendResponse) {
277
297
  let httpStatus = 'success';
278
298
  if (result.status === OpenClawServiceStatus.ERROR) httpStatus = 'error';
299
+
300
+ // 获取操作后的真实状态
301
+ let realStatus = result.status;
302
+ if (command === OpenClawCommandEnum.STOP || command === OpenClawCommandEnum.START || command === OpenClawCommandEnum.RESTART) {
303
+ try {
304
+ const { getOpenClawStatus } = require('./port-checker');
305
+ const portStatus = await getOpenClawStatus(18789);
306
+ // 更新真实状态
307
+ if (command === OpenClawCommandEnum.STOP) {
308
+ realStatus = portStatus === 1 ? OpenClawServiceStatus.RUNNING : OpenClawServiceStatus.STOP_SUCCESS;
309
+ } else if (command === OpenClawCommandEnum.START) {
310
+ realStatus = portStatus === 1 ? OpenClawServiceStatus.START_SUCCESS : OpenClawServiceStatus.ERROR;
311
+ } else if (command === OpenClawCommandEnum.RESTART) {
312
+ realStatus = portStatus === 1 ? OpenClawServiceStatus.RESTART_SUCCESS : OpenClawServiceStatus.ERROR;
313
+ }
314
+ console.log(`[OpenClawControl] 操作后真实状态检测: portStatus=${portStatus}, realStatus=${realStatus}`);
315
+ } catch (e) {
316
+ console.error(`[OpenClawControl] 真实状态检测失败: ${e.message}`);
317
+ }
318
+ }
319
+
279
320
  sendResponse({
280
321
  type: 'command_result',
281
322
  command,
282
323
  status: httpStatus,
283
324
  message: result.message,
284
- service_status: result.status
325
+ service_status: realStatus
285
326
  });
286
327
  }
287
328
 
@@ -337,10 +337,23 @@ class RongyunMessageHandler {
337
337
  this.logInfo(`[RongyunMessageHandler] 收到设备状态请求, from=${targetId}, requestId=${requestId}`);
338
338
 
339
339
  try {
340
- // 获取 OpenClaw 运行状态(检查端口 18789)
340
+ // 获取 OpenClaw 真实运行状态(检查端口 18789)
341
341
  const openClawStatus = await getOpenClawStatus();
342
342
 
343
- // 构建状态数据
343
+ // 获取真实的版本信息(如果可能)
344
+ let version = 'unknown';
345
+ try {
346
+ const { execSync } = require('child_process');
347
+ const versionOutput = execSync('openclaw --version', { encoding: 'utf8', timeout: 5000 }).trim();
348
+ const match = versionOutput.match(/(\d+\.\d+\.\d+)/);
349
+ if (match) {
350
+ version = match[1];
351
+ }
352
+ } catch (e) {
353
+ // 忽略版本获取失败
354
+ }
355
+
356
+ // 构建真实状态数据
344
357
  // openClawStatus: 1=端口监听正常(服务可用), 0=未运行(端口未监听)
345
358
  const statusMessage = openClawStatus === 1 ? '运行中' : '未运行';
346
359
 
@@ -348,11 +361,11 @@ class RongyunMessageHandler {
348
361
  open_claw_status: openClawStatus, // 1=运行中, 0=未运行
349
362
  status_message: statusMessage,
350
363
  mac_address: getMacAddress(),
351
- version: '0.0.20',
364
+ version: version,
352
365
  timestamp: Date.now(),
353
366
  };
354
367
 
355
- this.logInfo(`[RongyunMessageHandler] 设备状态: openClawStatus=${openClawStatus}`);
368
+ this.logInfo(`[RongyunMessageHandler] 设备真实状态: openClawStatus=${openClawStatus}, version=${version}`);
356
369
  await this.sendDeviceStatusReport(targetId, requestId, statusData);
357
370
  } catch (e) {
358
371
  const msg = e instanceof Error ? e.message : String(e);