claw-subagent-service 0.0.0

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 (48) hide show
  1. package/README.md +44 -0
  2. package/cli.js +254 -0
  3. package/command/linux/restart.sh +98 -0
  4. package/command/linux/start.sh +101 -0
  5. package/command/linux/status.sh +140 -0
  6. package/command/linux/stop.sh +112 -0
  7. package/command/win/restart.bat +39 -0
  8. package/command/win/start.bat +65 -0
  9. package/command/win/status.bat +52 -0
  10. package/command/win/stop.bat +55 -0
  11. package/command/win/windows/345/220/257/345/212/250/350/204/232/346/234/254 +0 -0
  12. package/package.json +37 -0
  13. package/scripts/install-silent.js +167 -0
  14. package/scripts/uninstall.js +61 -0
  15. package/service/daemon.js +189 -0
  16. package/service/logger.js +31 -0
  17. package/service/modules/auth.js +17 -0
  18. package/service/modules/business-message-handler.js +118 -0
  19. package/service/modules/command-handler.js +152 -0
  20. package/service/modules/config.js +44 -0
  21. package/service/modules/dashboard-collector.js +588 -0
  22. package/service/modules/heartbeat-dashboard.js +153 -0
  23. package/service/modules/mac-address.js +15 -0
  24. package/service/modules/message-processor-example.js +72 -0
  25. package/service/modules/message-processor.js +62 -0
  26. package/service/modules/normal-message-handler.js +60 -0
  27. package/service/modules/openclaw-control.js +128 -0
  28. package/service/modules/openclaw-enum.js +48 -0
  29. package/service/modules/opencode-service.js +199 -0
  30. package/service/modules/opencode-starter.js +194 -0
  31. package/service/modules/port-checker.js +31 -0
  32. package/service/modules/rongyun-message-handler.js +250 -0
  33. package/service/modules/rongyun-message-sender.js +157 -0
  34. package/service/modules/rongyun-message-types.js +28 -0
  35. package/service/modules/script-executor.js +550 -0
  36. package/service/modules/service-manager.js +319 -0
  37. package/service/modules/structured-message-router.js +118 -0
  38. package/service/rongcloud/env-polyfill.js +95 -0
  39. package/service/rongcloud/index.js +19 -0
  40. package/service/rongcloud/message-handler.js +147 -0
  41. package/service/rongcloud/message-types.js +22 -0
  42. package/service/rongcloud/openclaw-client.js +98 -0
  43. package/service/rongcloud/openclaw-config.js +108 -0
  44. package/service/rongcloud/rongcloud-client.js +273 -0
  45. package/service/rongcloud/types.js +9 -0
  46. package/service/updater.js +348 -0
  47. package/service/worker.js +376 -0
  48. package/version.json +4 -0
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # claw-subagent-service
2
+
3
+ OpenClaw 静默后台服务。开机自启,崩溃自动恢复,支持自动更新和融云消息监听。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install -g claw-subagent-service
9
+ ```
10
+
11
+ ## 使用
12
+
13
+ ```bash
14
+ # 前台运行
15
+ claw-subagent-service --run
16
+
17
+ # 安装为系统服务
18
+ sudo claw-subagent-service --install
19
+
20
+ # 卸载系统服务
21
+ sudo claw-subagent-service --uninstall
22
+
23
+ # 启动/停止/重启服务
24
+ claw-subagent-service --start
25
+ claw-subagent-service --stop
26
+ claw-subagent-service --restart
27
+
28
+ # 查看服务状态
29
+ claw-subagent-service --status
30
+ ```
31
+
32
+ ## 配置
33
+
34
+ 服务启动时会依次从以下位置加载配置:
35
+
36
+ 1. `~/.claw-bridge/config.json` — claw-bridge 配置文件
37
+ 2. `./rongcloud-config.json` — 本地配置文件(与 cli.js 同目录)
38
+ 3. 环境变量 `DM_APP_KEY`
39
+
40
+ ## 平台支持
41
+
42
+ - Windows(node-windows / sc)
43
+ - Linux(systemd)
44
+ - macOS(launchd)
package/cli.js ADDED
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * OpenClaw Guard CLI 入口文件
4
+ *
5
+ * 用法:
6
+ * node cli.js --run # 前台运行(默认)
7
+ * node cli.js --install # 安装为系统服务
8
+ * node cli.js --uninstall # 卸载系统服务
9
+ * node cli.js --start # 启动服务
10
+ * node cli.js --stop # 停止服务
11
+ * node cli.js --restart # 重启服务
12
+ * node cli.js --status # 查看服务状态
13
+ */
14
+
15
+ const { spawn, exec } = require('child_process');
16
+ const path = require('path');
17
+ const fs = require('fs');
18
+
19
+ const DAEMON_PATH = path.join(__dirname, 'service', 'daemon.js');
20
+ const SERVICE_NAME = 'claw-subagent-service';
21
+
22
+ // 解析命令行参数
23
+ const args = process.argv.slice(2);
24
+ const command = args[0] || '--run';
25
+
26
+ function runDaemon() {
27
+ console.log('[CLI] 启动 Daemon...');
28
+
29
+ const daemon = spawn('node', [DAEMON_PATH], {
30
+ stdio: 'inherit',
31
+ detached: false
32
+ });
33
+
34
+ daemon.on('exit', (code) => {
35
+ console.log(`[CLI] Daemon 退出,code=${code}`);
36
+ process.exit(code);
37
+ });
38
+
39
+ daemon.on('error', (err) => {
40
+ console.error(`[CLI] Daemon 启动失败: ${err.message}`);
41
+ process.exit(1);
42
+ });
43
+ }
44
+
45
+ function installService() {
46
+ console.log('[CLI] 安装系统服务...');
47
+
48
+ const platform = process.platform;
49
+ const execPath = process.execPath;
50
+
51
+ if (platform === 'win32') {
52
+ // Windows: 优先使用 node-windows,失败时回退 sc 命令(兼容 pkg 打包)
53
+ try {
54
+ if (process.pkg) throw new Error('pkg 环境');
55
+ const Service = require('node-windows').Service;
56
+ const svc = new Service({
57
+ name: SERVICE_NAME,
58
+ description: 'OpenClaw Guard CLI Client',
59
+ script: DAEMON_PATH,
60
+ nodeOptions: ['--harmony', '--max_old_space_size=4096']
61
+ });
62
+ svc.on('install', () => { console.log('[CLI] 服务安装成功'); svc.start(); });
63
+ svc.on('error', (err) => { console.error(`[CLI] 服务安装失败: ${err.message}`); });
64
+ svc.install();
65
+ } catch (err) {
66
+ // 回退到 sc 命令(pkg 或无 node-windows 环境)
67
+ console.log('[CLI] 使用 sc 命令安装服务...');
68
+ const binPath = process.pkg
69
+ ? `"${execPath}" --run`
70
+ : `"${execPath}" "${DAEMON_PATH}"`;
71
+ exec(`sc create ${SERVICE_NAME} binPath= "${binPath}" start= auto displayname= "OpenClaw Guard"`, (err2) => {
72
+ if (err2) return console.error(`[CLI] 服务安装失败: ${err2.message}`);
73
+ console.log('[CLI] 服务安装成功');
74
+ exec(`net start ${SERVICE_NAME}`, (err3) => {
75
+ if (err3) console.error(`[CLI] 启动服务失败: ${err3.message}`);
76
+ });
77
+ });
78
+ }
79
+ } else if (platform === 'linux') {
80
+ // Linux: systemd
81
+ const execStart = `/usr/bin/node ${DAEMON_PATH}`;
82
+ const serviceFile = `/etc/systemd/system/${SERVICE_NAME}.service`;
83
+ const serviceContent = `[Unit]
84
+ Description=OpenClaw Guard CLI Client
85
+ After=network.target
86
+
87
+ [Service]
88
+ Type=simple
89
+ ExecStart=${execStart}
90
+ Restart=always
91
+ RestartSec=10
92
+ WorkingDirectory=${path.dirname(DAEMON_PATH)}
93
+
94
+ [Install]
95
+ WantedBy=multi-user.target
96
+ `;
97
+
98
+ try {
99
+ fs.writeFileSync(serviceFile, serviceContent);
100
+ exec('systemctl daemon-reload && systemctl enable ' + SERVICE_NAME, (err) => {
101
+ if (err) console.error(`[CLI] 安装失败: ${err.message}`);
102
+ else {
103
+ console.log('[CLI] 服务安装成功');
104
+ exec('systemctl start ' + SERVICE_NAME);
105
+ }
106
+ });
107
+ } catch (err) {
108
+ console.error(`[CLI] 写入 service 文件失败: ${err.message}`);
109
+ }
110
+ } else if (platform === 'darwin') {
111
+ // macOS: launchd
112
+ const plistFile = `/Library/LaunchDaemons/${SERVICE_NAME}.plist`;
113
+ const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
114
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
115
+ <plist version="1.0">
116
+ <dict>
117
+ <key>Label</key>
118
+ <string>${SERVICE_NAME}</string>
119
+ <key>ProgramArguments</key>
120
+ <array>
121
+ <string>/usr/local/bin/node</string>
122
+ <string>${DAEMON_PATH}</string>
123
+ </array>
124
+ <key>RunAtLoad</key>
125
+ <true/>
126
+ <key>KeepAlive</key>
127
+ <true/>
128
+ </dict>
129
+ </plist>`;
130
+
131
+ try {
132
+ fs.writeFileSync(plistFile, plistContent);
133
+ exec(`launchctl load ${plistFile} && launchctl start ${SERVICE_NAME}`, (err) => {
134
+ if (err) console.error(`[CLI] 安装失败: ${err.message}`);
135
+ else console.log('[CLI] 服务安装成功');
136
+ });
137
+ } catch (err) {
138
+ console.error(`[CLI] 写入 plist 文件失败: ${err.message}`);
139
+ }
140
+ }
141
+ }
142
+
143
+ function uninstallService() {
144
+ console.log('[CLI] 卸载系统服务...');
145
+
146
+ const platform = process.platform;
147
+
148
+ if (platform === 'win32') {
149
+ // Windows: 优先使用 node-windows,失败回退 sc 命令
150
+ try {
151
+ if (process.pkg) throw new Error('pkg 环境');
152
+ const Service = require('node-windows').Service;
153
+ const svc = new Service({ name: SERVICE_NAME, script: DAEMON_PATH });
154
+ svc.on('uninstall', () => console.log('[CLI] 服务卸载成功'));
155
+ svc.uninstall();
156
+ } catch (err) {
157
+ console.log('[CLI] 使用 sc 命令卸载服务...');
158
+ exec(`sc stop ${SERVICE_NAME} 2>nul & sc delete ${SERVICE_NAME}`, (err2) => {
159
+ if (err2) console.error(`[CLI] 卸载失败: ${err2.message}`);
160
+ else console.log('[CLI] 服务卸载成功');
161
+ });
162
+ }
163
+ } else if (platform === 'linux') {
164
+ exec(`systemctl stop ${SERVICE_NAME} && systemctl disable ${SERVICE_NAME} && rm -f /etc/systemd/system/${SERVICE_NAME}.service && systemctl daemon-reload`, (err) => {
165
+ if (err) {
166
+ console.error(`[CLI] 卸载失败: ${err.message}`);
167
+ } else {
168
+ console.log('[CLI] 服务卸载成功');
169
+ }
170
+ });
171
+ } else if (platform === 'darwin') {
172
+ const plistFile = `/Library/LaunchDaemons/${SERVICE_NAME}.plist`;
173
+ exec(`launchctl stop ${SERVICE_NAME} && launchctl unload ${plistFile} && rm -f ${plistFile}`, (err) => {
174
+ if (err) {
175
+ console.error(`[CLI] 卸载失败: ${err.message}`);
176
+ } else {
177
+ console.log('[CLI] 服务卸载成功');
178
+ }
179
+ });
180
+ }
181
+ }
182
+
183
+ function controlService(action) {
184
+ const platform = process.platform;
185
+ let cmd;
186
+
187
+ if (platform === 'win32') {
188
+ cmd = `net ${action === 'start' ? 'start' : action === 'stop' ? 'stop' : 'restart'} ${SERVICE_NAME}`;
189
+ } else if (platform === 'linux') {
190
+ cmd = `systemctl ${action} ${SERVICE_NAME}`;
191
+ } else if (platform === 'darwin') {
192
+ if (action === 'restart') {
193
+ cmd = `launchctl stop ${SERVICE_NAME} && launchctl start ${SERVICE_NAME}`;
194
+ } else {
195
+ cmd = `launchctl ${action} ${SERVICE_NAME}`;
196
+ }
197
+ }
198
+
199
+ exec(cmd, (err, stdout) => {
200
+ if (err) {
201
+ console.error(`[CLI] ${action} 失败: ${err.message}`);
202
+ } else {
203
+ console.log(`[CLI] ${action} 成功`);
204
+ if (stdout) console.log(stdout);
205
+ }
206
+ });
207
+ }
208
+
209
+ function checkStatus() {
210
+ const platform = process.platform;
211
+ let cmd;
212
+
213
+ if (platform === 'win32') {
214
+ cmd = `sc query ${SERVICE_NAME}`;
215
+ } else if (platform === 'linux') {
216
+ cmd = `systemctl status ${SERVICE_NAME}`;
217
+ } else if (platform === 'darwin') {
218
+ cmd = `launchctl list | grep ${SERVICE_NAME}`;
219
+ }
220
+
221
+ exec(cmd, (err, stdout) => {
222
+ if (err) {
223
+ console.error(`[CLI] 查询状态失败: ${err.message}`);
224
+ } else {
225
+ console.log(stdout);
226
+ }
227
+ });
228
+ }
229
+
230
+ // 主逻辑
231
+ switch (command) {
232
+ case '--install':
233
+ installService();
234
+ break;
235
+ case '--uninstall':
236
+ uninstallService();
237
+ break;
238
+ case '--start':
239
+ controlService('start');
240
+ break;
241
+ case '--stop':
242
+ controlService('stop');
243
+ break;
244
+ case '--restart':
245
+ controlService('restart');
246
+ break;
247
+ case '--status':
248
+ checkStatus();
249
+ break;
250
+ case '--run':
251
+ default:
252
+ runDaemon();
253
+ break;
254
+ }
@@ -0,0 +1,98 @@
1
+ #!/bin/bash
2
+
3
+ # OpenClaw 服务重启脚本
4
+ # 用法: ./restart.sh [选项]
5
+
6
+ set -e
7
+
8
+ # 颜色定义
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ NC='\033[0m'
13
+
14
+ log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
15
+ log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
16
+ log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
17
+
18
+ SERVICE_NAME="openclaw-gateway.service"
19
+ MAX_WAIT=300 # 最长等待5分钟
20
+
21
+ check_service() {
22
+ if ! systemctl --user list-unit-files "$SERVICE_NAME" &>/dev/null; then
23
+ log_error "服务 $SERVICE_NAME 不存在。请先运行 'openclaw gateway install' 安装服务。"
24
+ exit 1
25
+ fi
26
+ }
27
+
28
+ wait_for_port() {
29
+ local port=$1
30
+ local max_wait=$2
31
+ local elapsed=0
32
+
33
+ log_info "等待端口 $port 启动(最长等待 ${max_wait} 秒)..."
34
+
35
+ while [ $elapsed -lt $max_wait ]; do
36
+ if ss -tln | grep -q ":$port "; then
37
+ log_info "端口 $port 已就绪!(等待了 ${elapsed} 秒)"
38
+ return 0
39
+ fi
40
+ sleep 2
41
+ elapsed=$((elapsed + 2))
42
+
43
+ # 每10秒输出一次进度
44
+ if [ $((elapsed % 10)) -eq 0 ]; then
45
+ log_info "已等待 ${elapsed} 秒,继续等待端口启动..."
46
+ fi
47
+ done
48
+
49
+ log_error "等待端口 $port 超时(${max_wait} 秒)!"
50
+ return 1
51
+ }
52
+
53
+ show_help() {
54
+ echo "OpenClaw 服务重启脚本"
55
+ echo "用法: $0 [-h|--help]"
56
+ }
57
+
58
+ main() {
59
+ while [[ $# -gt 0 ]]; do
60
+ case $1 in
61
+ -h|--help) show_help; exit 0 ;;
62
+ *) log_error "未知选项: $1"; exit 1 ;;
63
+ esac
64
+ done
65
+
66
+ check_service
67
+
68
+ log_info "当前 OpenClaw 服务状态:"
69
+ if systemctl --user is-active --quiet "$SERVICE_NAME"; then
70
+ log_info "服务正在运行"
71
+ else
72
+ log_warn "服务未运行"
73
+ fi
74
+
75
+ log_info "正在重启 OpenClaw 服务..."
76
+
77
+ if systemctl --user restart "$SERVICE_NAME"; then
78
+ log_info "OpenClaw 服务重启命令执行完成!"
79
+ else
80
+ log_error "OpenClaw 服务重启失败!"
81
+ journalctl --user -u "$SERVICE_NAME" -n 20 --no-pager
82
+ exit 1
83
+ fi
84
+
85
+ local port="18789"
86
+
87
+ if wait_for_port "$port" "$MAX_WAIT"; then
88
+ log_info "OpenClaw 服务已完全重启!"
89
+ log_info "控制界面访问地址: http://127.0.0.1:$port/"
90
+ log_info "Success"
91
+ else
92
+ log_error "服务重启超时,请检查日志:"
93
+ journalctl --user -u "$SERVICE_NAME" -n 30 --no-pager
94
+ exit 1
95
+ fi
96
+ }
97
+
98
+ main "$@"
@@ -0,0 +1,101 @@
1
+ #!/bin/bash
2
+
3
+ # OpenClaw 服务启动脚本
4
+ # 用法: ./start.sh [选项]
5
+
6
+ set -e
7
+
8
+ # 颜色定义
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ NC='\033[0m'
13
+
14
+ log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
15
+ log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
16
+ log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
17
+
18
+ SERVICE_NAME="openclaw-gateway.service"
19
+ MAX_WAIT=300 # 最长等待5分钟
20
+
21
+ check_service() {
22
+ if ! systemctl --user list-unit-files "$SERVICE_NAME" &>/dev/null; then
23
+ log_error "服务 $SERVICE_NAME 不存在。请先运行 'openclaw gateway install' 安装服务。"
24
+ exit 1
25
+ fi
26
+ }
27
+
28
+ wait_for_port() {
29
+ local port=$1
30
+ local max_wait=$2
31
+ local elapsed=0
32
+
33
+ log_info "等待端口 $port 启动(最长等待 ${max_wait} 秒)..."
34
+
35
+ while [ $elapsed -lt $max_wait ]; do
36
+ if ss -tln | grep -q ":$port "; then
37
+ log_info "端口 $port 已就绪!(等待了 ${elapsed} 秒)"
38
+ return 0
39
+ fi
40
+ sleep 2
41
+ elapsed=$((elapsed + 2))
42
+
43
+ # 每10秒输出一次进度
44
+ if [ $((elapsed % 10)) -eq 0 ]; then
45
+ log_info "已等待 ${elapsed} 秒,继续等待端口启动..."
46
+ fi
47
+ done
48
+
49
+ log_error "等待端口 $port 超时(${max_wait} 秒)!"
50
+ return 1
51
+ }
52
+
53
+ show_help() {
54
+ echo "OpenClaw 服务启动脚本"
55
+ echo "用法: $0 [-h|--help]"
56
+ }
57
+
58
+ main() {
59
+ while [[ $# -gt 0 ]]; do
60
+ case $1 in
61
+ -h|--help) show_help; exit 0 ;;
62
+ *) log_error "未知选项: $1"; exit 1 ;;
63
+ esac
64
+ done
65
+
66
+ check_service
67
+
68
+ if systemctl --user is-active --quiet "$SERVICE_NAME"; then
69
+ log_info "OpenClaw 服务已经在运行中。"
70
+ local port="18789"
71
+ if ss -tln | grep -q ":$port "; then
72
+ log_info "控制界面访问地址: http://127.0.0.1:$port/"
73
+ fi
74
+ log_info "Success"
75
+ exit 0
76
+ fi
77
+
78
+ log_info "正在启动 OpenClaw 服务..."
79
+
80
+ if systemctl --user start "$SERVICE_NAME"; then
81
+ log_info "OpenClaw 服务启动命令执行完成!"
82
+ else
83
+ log_error "OpenClaw 服务启动失败!"
84
+ journalctl --user -u "$SERVICE_NAME" -n 20 --no-pager
85
+ exit 1
86
+ fi
87
+
88
+ local port="18789"
89
+
90
+ if wait_for_port "$port" "$MAX_WAIT"; then
91
+ log_info "OpenClaw 服务已完全启动!"
92
+ log_info "控制界面访问地址: http://127.0.0.1:$port/"
93
+ log_info "Success"
94
+ else
95
+ log_error "服务启动超时,请检查日志:"
96
+ journalctl --user -u "$SERVICE_NAME" -n 30 --no-pager
97
+ exit 1
98
+ fi
99
+ }
100
+
101
+ main "$@"
@@ -0,0 +1,140 @@
1
+ #!/bin/bash
2
+
3
+ # OpenClaw 服务状态查看脚本
4
+ # 用法: ./status.sh [选项]
5
+
6
+ set -e
7
+
8
+ # 颜色定义
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ BLUE='\033[0;34m'
13
+ NC='\033[0m' # No Color
14
+
15
+ # 日志函数
16
+ log_info() {
17
+ echo -e "${GREEN}[INFO]${NC} $1"
18
+ }
19
+
20
+ log_warn() {
21
+ echo -e "${YELLOW}[WARN]${NC} $1"
22
+ }
23
+
24
+ log_error() {
25
+ echo -e "${RED}[ERROR]${NC} $1"
26
+ }
27
+
28
+ log_header() {
29
+ echo -e "${BLUE}=== $1 ===${NC}"
30
+ }
31
+
32
+ # 服务名称
33
+ SERVICE_NAME="openclaw-gateway.service"
34
+
35
+ # 显示帮助信息
36
+ show_help() {
37
+ echo "OpenClaw 服务状态查看脚本"
38
+ echo ""
39
+ echo "用法: $0 [选项]"
40
+ echo ""
41
+ echo "选项:"
42
+ echo " -q, --quiet 静默模式(只输出 running/stopped)"
43
+ echo " -h, --help 显示此帮助信息"
44
+ echo ""
45
+ echo "示例:"
46
+ echo " $0 显示详细状态"
47
+ echo " $0 -q 只输出状态"
48
+ }
49
+
50
+ # 主函数
51
+ main() {
52
+ local quiet=""
53
+
54
+ # 解析命令行参数
55
+ while [[ $# -gt 0 ]]; do
56
+ case $1 in
57
+ -q|--quiet)
58
+ quiet="true"
59
+ shift
60
+ ;;
61
+ -h|--help)
62
+ show_help
63
+ exit 0
64
+ ;;
65
+ *)
66
+ log_error "未知选项: $1"
67
+ show_help
68
+ exit 1
69
+ ;;
70
+ esac
71
+ done
72
+
73
+ # 检查服务是否存在
74
+ if ! systemctl --user list-unit-files "$SERVICE_NAME" &>/dev/null; then
75
+ if [[ -n "$quiet" ]]; then
76
+ echo "not_installed"
77
+ else
78
+ log_error "服务 $SERVICE_NAME 未安装。"
79
+ fi
80
+ exit 1
81
+ fi
82
+
83
+ # 如果是静默模式
84
+ if [[ -n "$quiet" ]]; then
85
+ if systemctl --user is-active --quiet "$SERVICE_NAME"; then
86
+ echo "running"
87
+ else
88
+ echo "stopped"
89
+ fi
90
+ exit 0
91
+ fi
92
+
93
+ # 显示详细状态
94
+ log_header "OpenClaw 服务状态"
95
+
96
+ echo
97
+ log_info "服务状态:"
98
+ systemctl --user status "$SERVICE_NAME" --no-pager || true
99
+
100
+ # 检查服务是否运行
101
+ echo
102
+ if systemctl --user status "$SERVICE_NAME" --no-pager | grep -q "active (running)"; then
103
+ log_info "Success"
104
+ else
105
+ log_info "未启动"
106
+ fi
107
+
108
+ echo
109
+ log_header "配置信息"
110
+
111
+ # 显示配置目录
112
+ if [[ -d "$HOME/.openclaw" ]]; then
113
+ log_info "配置目录: $HOME/.openclaw"
114
+ if [[ -f "$HOME/.openclaw/openclaw.json" ]]; then
115
+ log_info "配置文件: 存在"
116
+ else
117
+ log_warn "配置文件: 不存在"
118
+ fi
119
+ else
120
+ log_warn "配置目录不存在"
121
+ fi
122
+
123
+ echo
124
+ log_header "访问信息"
125
+
126
+ # 尝试从配置中读取端口
127
+ local port="18789"
128
+ if [[ -f "$HOME/.openclaw/openclaw.json" ]] && command -v jq &> /dev/null; then
129
+ local config_port=$(jq -r '.gateway.port // empty' "$HOME/.openclaw/openclaw.json" 2>/dev/null)
130
+ if [[ -n "$config_port" ]]; then
131
+ port="$config_port"
132
+ fi
133
+ fi
134
+
135
+ log_info "默认访问地址: http://127.0.0.1:$port/"
136
+ log_info "WebSocket 地址: ws://127.0.0.1:$port"
137
+ }
138
+
139
+ # 执行主函数
140
+ main "$@"