openclaw-service 0.6.1 → 0.7.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.
package/README.zh-CN.md CHANGED
@@ -1,212 +1,80 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/Sobranier/openclaw-cli/main/assets/welcome.png" alt="OpenClaw Doctor" width="400" />
2
+ <img src="https://raw.githubusercontent.com/Sobranier/openclaw-cli/main/assets/hero.png" alt="OpenClaw CLI" width="700" />
3
3
  </p>
4
4
 
5
- <h1 align="center">OpenClaw Doctor</h1>
5
+ <h1 align="center">OpenClaw CLI</h1>
6
6
 
7
7
  <p align="center">
8
8
  让你的 OpenClaw 服务永不宕机。
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="./README.md">English</a>
12
+ <a href="./README.md">EN</a> | <a href="https://openclaw-cli.app">openclaw-cli.app</a>
13
13
  </p>
14
14
 
15
- ## 开始使用
15
+ <p align="center">
16
+ <a href="https://www.npmjs.com/package/openclaw-cli"><img src="https://img.shields.io/npm/v/openclaw-cli?label=openclaw-cli&color=blue" alt="openclaw-cli" /></a>
17
+ &nbsp;
18
+ <a href="https://www.npmjs.com/package/openclaw-cli"><img src="https://img.shields.io/npm/dm/openclaw-cli?color=blue" alt="downloads" /></a>
19
+ &nbsp;
20
+ <a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-brightgreen" alt="license" /></a>
21
+ &nbsp;
22
+ <img src="https://img.shields.io/node/v/openclaw-cli" alt="node" />
23
+ </p>
16
24
 
17
- ```bash
18
- npm install -g openclaw-doctor
19
- openclaw-doctor watch -d
20
- ```
25
+ ---
21
26
 
22
- 就这样。Doctor 在后台监控你的 OpenClaw 网关,挂了自动重启,全程通知你。无需任何配置——它会自动读取你现有的 OpenClaw 设置。
27
+ ## 为什么需要它?
23
28
 
24
- ## 核心命令
29
+ OpenClaw 以本地守护进程的方式运行。网络抖动、系统唤醒、意外更新——任何一个都可能让它悄悄挂掉,而你只有在用 AI 助手的时候才会发现。
25
30
 
26
- ```bash
27
- openclaw-doctor watch # 开始监控(前台)
28
- openclaw-doctor watch -d # 开始监控(后台)
29
- openclaw-doctor unwatch # 停止监控
31
+ OpenClaw CLI 替你盯着网关。检测到故障,自动重启,全程通知。零配置,不用盯。
30
32
 
31
- openclaw-doctor status # 快速健康检查
32
- ```
33
-
34
- 这四个命令覆盖日常 90% 的使用场景。
35
-
36
- ## 网关管理
33
+ ## 开始使用
37
34
 
38
35
  ```bash
39
- openclaw-doctor gateway start # 启动 OpenClaw 网关
40
- openclaw-doctor gateway stop # 停止网关
41
- openclaw-doctor gateway restart # 重启网关
36
+ npm install -g openclaw-cli
37
+ openclaw-cli watch -d
42
38
  ```
43
39
 
44
- ## 诊断和日志
45
-
46
- ```bash
47
- openclaw-doctor doctor # 完整诊断(二进制、网关、通道)
48
- openclaw-doctor logs # 查看网关日志
49
- openclaw-doctor logs --error # 只看错误日志
50
- openclaw-doctor logs --doctor # 查看 Doctor 自身事件日志
51
- openclaw-doctor dashboard # Web 管理面板(http://localhost:9090)
52
- ```
40
+ 就这样。OpenClaw CLI 现在在后台运行了。
53
41
 
54
- ## 安装
42
+ ## 核心命令
55
43
 
56
44
  ```bash
57
- # npm(推荐)
58
- npm install -g openclaw-doctor
59
-
60
- # 或免安装直接跑
61
- npx openclaw-doctor status
62
- ```
45
+ openclaw-cli watch # 开始监控(前台)
46
+ openclaw-cli watch -d # 开始监控(后台)
47
+ openclaw-cli unwatch # 停止监控
63
48
 
64
- 需要 Node >= 22(和 OpenClaw 一致)。
65
-
66
- ## 工作原理
67
-
68
- Doctor 自动探测你的 OpenClaw 安装:
69
-
70
- - 读取 `~/.openclaw/openclaw.json` 获取网关端口、通道、Agent 信息
71
- - 扫描 `~/Library/LaunchAgents/` 找到 launchd 服务
72
- - 通过 `openclaw health --json` 检查健康(真正的网关 RPC,不是 HTTP 探测)
73
- - 需要时通过 `launchctl kickstart` 重启
74
-
75
- **你不需要配置 OpenClaw 的任何信息。** Doctor 会自动搞定。
76
-
77
- ## 完整命令
78
-
79
- | 命令 | 说明 |
80
- |------|------|
81
- | **监控** | |
82
- | `watch` | 开始健康监控(前台) |
83
- | `watch -d` | 开始健康监控(后台) |
84
- | `watch -d --dashboard` | 后台监控 + Web 面板 |
85
- | `unwatch` | 停止监控 |
86
- | **网关** | |
87
- | `gateway start` | 启动 OpenClaw 网关 |
88
- | `gateway stop` | 停止网关 |
89
- | `gateway restart` | 重启网关 |
90
- | **信息** | |
91
- | `status` | 显示网关和通道健康状态 |
92
- | `status --json` | 机器可读的 JSON 输出 |
93
- | `doctor` | 运行完整诊断 |
94
- | `dashboard` | 启动 Web 管理面板 |
95
- | `logs` | 查看网关日志 |
96
- | `logs --error` | 只看错误日志 |
97
- | `logs --doctor` | 查看 Doctor 事件日志 |
98
-
99
- ## 配置
100
-
101
- 配置文件位于 `~/.openclaw-doctor/config.json`,首次运行时自动创建。只包含 Doctor 自身的偏好——无需配置 OpenClaw 的信息。
102
-
103
- ```json
104
- {
105
- "checkInterval": 30,
106
- "failThreshold": 3,
107
- "dashboardPort": 9090,
108
- "maxRestartsPerHour": 5,
109
- "openclawProfile": "default",
110
- "notify": {
111
- "webhook": {
112
- "enabled": false,
113
- "url": "",
114
- "bodyTemplate": "{\"msgtype\":\"text\",\"text\":{\"content\":\"{{message}}\"}}"
115
- },
116
- "system": {
117
- "enabled": true
118
- }
119
- }
120
- }
49
+ openclaw-cli status # 快速健康检查
50
+ openclaw-cli doctor # 完整诊断
121
51
  ```
122
52
 
123
- | 字段 | 说明 | 默认值 |
124
- |------|------|--------|
125
- | `checkInterval` | 健康检查间隔(秒) | `30` |
126
- | `failThreshold` | 连续失败几次后重启 | `3` |
127
- | `dashboardPort` | Web 面板端口 | `9090` |
128
- | `maxRestartsPerHour` | 每小时最多重启次数 | `5` |
129
- | `openclawProfile` | 监控的 OpenClaw 配置(`default`、`dev`...) | `default` |
130
- | `notify.webhook.url` | Webhook 通知地址 | -- |
131
- | `notify.system.enabled` | macOS 系统通知 | `true` |
132
-
133
- ## 通知系统
134
-
135
- Doctor 在整个生命周期都会通知你:
136
-
137
- | 事件 | 示例消息 |
138
- |------|----------|
139
- | 开始监控 | "Doctor 正在守护你的 OpenClaw 服务" |
140
- | 状态异常 | "服务异常(第 2/3 次检测)" |
141
- | 准备重启 | "正在重启网关..." |
142
- | 重启成功 | "网关已恢复上线" |
143
- | 重启失败 | "重启失败:[错误详情]" |
144
- | 重启受限 | "重启次数过多,需要人工介入" |
145
- | 自行恢复 | "服务自行恢复,无需重启" |
146
- | 停止监控 | "Doctor 已停止" |
147
-
148
- 支持渠道:**Webhook**(钉钉、飞书、Slack、企业微信等)+ **macOS 系统通知**。
149
-
150
- ## Skills 集成
151
-
152
- Doctor 作为独立守护进程运行,可被 OpenClaw 或其他工具调用:
53
+ ## 网关管理
153
54
 
154
55
  ```bash
155
- openclaw-doctor status --json # 机器可读输出
156
- openclaw-doctor watch -d # 幂等——重复调用安全
56
+ openclaw-cli gateway start
57
+ openclaw-cli gateway stop
58
+ openclaw-cli gateway restart
157
59
  ```
158
60
 
159
- 即使调用方崩溃,Doctor 继续运行。
61
+ ## 监控面板
160
62
 
161
- ## 架构
162
-
163
- ```
164
- +-----------------+
165
- | 通知系统 |
166
- | (Webhook/OS) |
167
- +--------^--------+
168
- |
169
- +-------------+ CLI +--------+--------+ RPC +-----------+
170
- | OpenClaw | --------> | | ---------> | OpenClaw |
171
- | / 脚本 | | openclaw-doctor | | 网关 |
172
- | / Skills | <-------- | (守护进程) | <--------- | :18789 |
173
- +-------------+ stdout +--------+--------+ health +-----------+
174
- |
175
- +--------v--------+
176
- | ~/.openclaw/logs |
177
- | (读取并分析) |
178
- +-----------------+
63
+ ```bash
64
+ openclaw-cli monitor # 启动 Web 面板(http://localhost:9090)
179
65
  ```
180
66
 
181
- ## 开发
67
+ ## 兼容别名
182
68
 
183
- ```bash
184
- git clone https://github.com/Sobranier/openclaw-cli.git
185
- cd openclaw-doctor
186
- npm install
69
+ `openclaw-doctor`、`hello-claw`、`aiclaw`、`pddclaw` 等别名包全部指向同一个 CLI 引擎。
187
70
 
188
- npm run dev -- status # 快速测试
189
- npm run dev -- watch # 前台监控
190
- npm run dev -- watch -d # 后台守护
191
- npm run dev -- unwatch # 停止守护
71
+ - 主包:https://www.npmjs.com/package/openclaw-cli
72
+ - 项目地址:https://github.com/Sobranier/openclaw-cli
192
73
 
193
- npm run build # 构建发布版本
194
- ```
74
+ ## 更多文档
195
75
 
196
- ## 路线图
197
-
198
- - [x] 通过 `openclaw health --json` 检查健康 + 自动重启(含频率限制)
199
- - [x] 自动探测 OpenClaw 配置(网关端口、通道、Agent、launchd)
200
- - [x] 后台守护模式(`watch -d` / `unwatch`)
201
- - [x] 网关管理(`gateway start/stop/restart`)
202
- - [x] 读取并展示 OpenClaw 网关日志
203
- - [x] Web 状态面板
204
- - [x] `status --json` 输出
205
- - [ ] 通知系统(Webhook + macOS)
206
- - [ ] `logs --tail`(实时跟踪)
207
- - [ ] `config` 命令(get/set)
208
- - [ ] 多服务监控
209
- - [ ] Linux systemd 支持
76
+ - 开发和发布流程:[CONTRIBUTING.md](./CONTRIBUTING.md)
77
+ - English README:[README.md](./README.md)
210
78
 
211
79
  ## 协议
212
80
 
package/dist/index.js CHANGED
@@ -1339,7 +1339,7 @@ var init_server = __esm({
1339
1339
  init_process_manager();
1340
1340
  init_workspace_scanner();
1341
1341
  init_cost_scanner();
1342
- _PKG_VER = true ? "0.6.1" : "0.2.1";
1342
+ _PKG_VER = true ? "0.7.0" : "0.2.1";
1343
1343
  pkgVersion = _PKG_VER;
1344
1344
  }
1345
1345
  });
@@ -1370,6 +1370,11 @@ var MEASUREMENT_ID = "G-B46J8RT804";
1370
1370
  var API_SECRET = "qkqms1nURj2S02Q3WqO7GQ";
1371
1371
  var ENDPOINT = `https://www.google-analytics.com/mp/collect?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`;
1372
1372
  var TELEMETRY_FILE = join5(APP_HOME, "telemetry.json");
1373
+ var SESSION_ID = randomUUID();
1374
+ var _version = true ? "0.7.0" : "0.0.0";
1375
+ function getVersion() {
1376
+ return _version;
1377
+ }
1373
1378
  function loadState() {
1374
1379
  if (existsSync4(TELEMETRY_FILE)) {
1375
1380
  try {
@@ -1436,6 +1441,11 @@ function printFirstRunNotice() {
1436
1441
  process.stderr.write(
1437
1442
  "\n \u{1F4CA} OpenClaw collects anonymous usage data to improve the product.\n To opt out: openclaw telemetry off (or set OPENCLAW_NO_TELEMETRY=1)\n\n"
1438
1443
  );
1444
+ track("app_first_run", {
1445
+ platform: "cli",
1446
+ version: getVersion(),
1447
+ os: process.platform
1448
+ });
1439
1449
  }
1440
1450
  async function track(eventName, opts) {
1441
1451
  if (isOptedOut()) return;
@@ -1448,14 +1458,18 @@ async function track(eventName, opts) {
1448
1458
  const params = {
1449
1459
  platform: opts.platform,
1450
1460
  engagement_time_msec: 1,
1461
+ session_id: SESSION_ID,
1462
+ app_version: opts.version ?? _version,
1463
+ node_version: process.version,
1464
+ os_type: opts.os ?? process.platform,
1465
+ arch: process.arch,
1451
1466
  ...opts.command !== void 0 && { command: opts.command },
1452
1467
  ...opts.success !== void 0 && { success: opts.success ? 1 : 0 },
1453
- ...opts.version !== void 0 && { app_version: opts.version },
1454
- ...opts.os !== void 0 && { os_type: opts.os },
1455
1468
  ...opts.extra
1456
1469
  };
1457
1470
  const payload = {
1458
1471
  client_id: state.client_id,
1472
+ user_id: state.client_id,
1459
1473
  non_personalized_ads: true,
1460
1474
  events: [
1461
1475
  {
@@ -1906,7 +1920,7 @@ init_process_manager();
1906
1920
  init_logger();
1907
1921
  import chalk7 from "chalk";
1908
1922
  import { writeFileSync as writeFileSync5, unlinkSync as unlinkSync2 } from "fs";
1909
- var _VER = true ? "0.6.1" : void 0;
1923
+ var _VER = true ? "0.7.0" : void 0;
1910
1924
  async function gatewayStart(options) {
1911
1925
  const config = loadConfig(options.config);
1912
1926
  initLogger();
@@ -2204,6 +2218,7 @@ async function remoteLogin(_options) {
2204
2218
  email = result.email;
2205
2219
  } catch (err) {
2206
2220
  console.log(chalk10.red(` ${String(err)}`));
2221
+ await trackCommand("remote login", false, getVersion());
2207
2222
  return;
2208
2223
  }
2209
2224
  console.log(chalk10.gray(" Registering this machine..."));
@@ -2239,8 +2254,10 @@ async function remoteLogin(_options) {
2239
2254
  console.log(
2240
2255
  chalk10.gray(" Remote monitoring ready. Run: openclaw-cli remote enable\n")
2241
2256
  );
2257
+ await trackCommand("remote login", true, getVersion());
2242
2258
  } catch (err) {
2243
2259
  console.log(chalk10.red(` Error: ${err}`));
2260
+ await trackCommand("remote login", false, getVersion());
2244
2261
  }
2245
2262
  }
2246
2263
  async function remoteEnable(_options) {
@@ -2249,19 +2266,23 @@ async function remoteEnable(_options) {
2249
2266
  console.log(
2250
2267
  chalk10.red(" \u2717 Not logged in. Run: openclaw-cli remote login")
2251
2268
  );
2269
+ await trackCommand("remote enable", false, getVersion());
2252
2270
  return;
2253
2271
  }
2254
2272
  config.enabled = true;
2255
2273
  saveRemoteConfig(config);
2256
2274
  console.log(chalk10.green(" Remote reporting enabled."));
2275
+ await trackCommand("remote enable", true, getVersion());
2257
2276
  }
2258
2277
  async function remoteDisable(_options) {
2259
2278
  const config = loadRemoteConfig();
2260
2279
  config.enabled = false;
2261
2280
  saveRemoteConfig(config);
2262
2281
  console.log(chalk10.yellow(" Remote reporting disabled."));
2282
+ await trackCommand("remote disable", true, getVersion());
2263
2283
  }
2264
2284
  async function remoteStatus(_options) {
2285
+ await trackCommand("remote status", true, getVersion());
2265
2286
  const config = loadRemoteConfig();
2266
2287
  console.log(chalk10.cyan.bold("\n Remote Monitoring Status\n"));
2267
2288
  console.log(
@@ -2283,7 +2304,7 @@ async function remoteStatus(_options) {
2283
2304
  }
2284
2305
 
2285
2306
  // src/index.ts
2286
- var _PKG_VER2 = true ? "0.6.1" : "0.2.1";
2307
+ var _PKG_VER2 = true ? "0.7.0" : "0.2.1";
2287
2308
  var version = _PKG_VER2;
2288
2309
  printFirstRunNotice();
2289
2310
  var program = new Command();
@@ -6342,7 +6342,7 @@ var init_server = __esm({
6342
6342
  init_process_manager();
6343
6343
  init_workspace_scanner();
6344
6344
  init_cost_scanner();
6345
- _PKG_VER = true ? "0.6.1" : "0.2.1";
6345
+ _PKG_VER = true ? "0.7.0" : "0.2.1";
6346
6346
  pkgVersion = _PKG_VER;
6347
6347
  }
6348
6348
  });
@@ -6391,6 +6391,11 @@ var MEASUREMENT_ID = "G-B46J8RT804";
6391
6391
  var API_SECRET = "qkqms1nURj2S02Q3WqO7GQ";
6392
6392
  var ENDPOINT = `https://www.google-analytics.com/mp/collect?measurement_id=${MEASUREMENT_ID}&api_secret=${API_SECRET}`;
6393
6393
  var TELEMETRY_FILE = (0, import_node_path5.join)(APP_HOME, "telemetry.json");
6394
+ var SESSION_ID = (0, import_node_crypto.randomUUID)();
6395
+ var _version = true ? "0.7.0" : "0.0.0";
6396
+ function getVersion() {
6397
+ return _version;
6398
+ }
6394
6399
  function loadState() {
6395
6400
  if ((0, import_node_fs4.existsSync)(TELEMETRY_FILE)) {
6396
6401
  try {
@@ -6457,6 +6462,11 @@ function printFirstRunNotice() {
6457
6462
  process.stderr.write(
6458
6463
  "\n \u{1F4CA} OpenClaw collects anonymous usage data to improve the product.\n To opt out: openclaw telemetry off (or set OPENCLAW_NO_TELEMETRY=1)\n\n"
6459
6464
  );
6465
+ track("app_first_run", {
6466
+ platform: "cli",
6467
+ version: getVersion(),
6468
+ os: process.platform
6469
+ });
6460
6470
  }
6461
6471
  async function track(eventName, opts) {
6462
6472
  if (isOptedOut()) return;
@@ -6469,14 +6479,18 @@ async function track(eventName, opts) {
6469
6479
  const params = {
6470
6480
  platform: opts.platform,
6471
6481
  engagement_time_msec: 1,
6482
+ session_id: SESSION_ID,
6483
+ app_version: opts.version ?? _version,
6484
+ node_version: process.version,
6485
+ os_type: opts.os ?? process.platform,
6486
+ arch: process.arch,
6472
6487
  ...opts.command !== void 0 && { command: opts.command },
6473
6488
  ...opts.success !== void 0 && { success: opts.success ? 1 : 0 },
6474
- ...opts.version !== void 0 && { app_version: opts.version },
6475
- ...opts.os !== void 0 && { os_type: opts.os },
6476
6489
  ...opts.extra
6477
6490
  };
6478
6491
  const payload = {
6479
6492
  client_id: state.client_id,
6493
+ user_id: state.client_id,
6480
6494
  non_personalized_ads: true,
6481
6495
  events: [
6482
6496
  {
@@ -6927,7 +6941,7 @@ init_config();
6927
6941
  init_openclaw();
6928
6942
  init_process_manager();
6929
6943
  init_logger();
6930
- var _VER = true ? "0.6.1" : void 0;
6944
+ var _VER = true ? "0.7.0" : void 0;
6931
6945
  async function gatewayStart(options) {
6932
6946
  const config = loadConfig(options.config);
6933
6947
  initLogger();
@@ -7225,6 +7239,7 @@ async function remoteLogin(_options) {
7225
7239
  email = result.email;
7226
7240
  } catch (err) {
7227
7241
  console.log(import_chalk10.default.red(` ${String(err)}`));
7242
+ await trackCommand("remote login", false, getVersion());
7228
7243
  return;
7229
7244
  }
7230
7245
  console.log(import_chalk10.default.gray(" Registering this machine..."));
@@ -7260,8 +7275,10 @@ async function remoteLogin(_options) {
7260
7275
  console.log(
7261
7276
  import_chalk10.default.gray(" Remote monitoring ready. Run: openclaw-cli remote enable\n")
7262
7277
  );
7278
+ await trackCommand("remote login", true, getVersion());
7263
7279
  } catch (err) {
7264
7280
  console.log(import_chalk10.default.red(` Error: ${err}`));
7281
+ await trackCommand("remote login", false, getVersion());
7265
7282
  }
7266
7283
  }
7267
7284
  async function remoteEnable(_options) {
@@ -7270,19 +7287,23 @@ async function remoteEnable(_options) {
7270
7287
  console.log(
7271
7288
  import_chalk10.default.red(" \u2717 Not logged in. Run: openclaw-cli remote login")
7272
7289
  );
7290
+ await trackCommand("remote enable", false, getVersion());
7273
7291
  return;
7274
7292
  }
7275
7293
  config.enabled = true;
7276
7294
  saveRemoteConfig(config);
7277
7295
  console.log(import_chalk10.default.green(" Remote reporting enabled."));
7296
+ await trackCommand("remote enable", true, getVersion());
7278
7297
  }
7279
7298
  async function remoteDisable(_options) {
7280
7299
  const config = loadRemoteConfig();
7281
7300
  config.enabled = false;
7282
7301
  saveRemoteConfig(config);
7283
7302
  console.log(import_chalk10.default.yellow(" Remote reporting disabled."));
7303
+ await trackCommand("remote disable", true, getVersion());
7284
7304
  }
7285
7305
  async function remoteStatus(_options) {
7306
+ await trackCommand("remote status", true, getVersion());
7286
7307
  const config = loadRemoteConfig();
7287
7308
  console.log(import_chalk10.default.cyan.bold("\n Remote Monitoring Status\n"));
7288
7309
  console.log(
@@ -7304,7 +7325,7 @@ async function remoteStatus(_options) {
7304
7325
  }
7305
7326
 
7306
7327
  // src/index.ts
7307
- var _PKG_VER2 = true ? "0.6.1" : "0.2.1";
7328
+ var _PKG_VER2 = true ? "0.7.0" : "0.2.1";
7308
7329
  var version = _PKG_VER2;
7309
7330
  printFirstRunNotice();
7310
7331
  var program2 = new Command();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-service",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "System service manager for OpenClaw — launchd integration for macOS. Alias of openclaw-cli.",
5
5
  "type": "module",
6
6
  "bin": {