baozang-activator 1.2.2 → 1.2.4
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/OPENCLAW.md +183 -0
- package/README.md +4 -1
- package/lib/openclaw.js +83 -16
- package/package.json +1 -1
package/OPENCLAW.md
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# OpenClaw 使用说明(baozang-activator)
|
|
2
|
+
|
|
3
|
+
本文档专门说明 `baozang-activator` 对 OpenClaw 的安装、配置、验证、卸载与常见问题处理。
|
|
4
|
+
|
|
5
|
+
## 1) 快速开始(推荐)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 一键安装 + 配置 OpenClaw(生产环境)
|
|
9
|
+
npx -y baozang-activator@latest -t openclaw <你的key或卡密>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
执行后会自动完成:
|
|
13
|
+
- 安装 OpenClaw(调用官方安装脚本)
|
|
14
|
+
- 配置 provider / key / model(`gpt5.4`)
|
|
15
|
+
- 启动网关并校验状态
|
|
16
|
+
- 打开浏览器(自动使用带 token 的 Dashboard 链接)
|
|
17
|
+
- 预装常见 skills(默认开启)
|
|
18
|
+
|
|
19
|
+
## 2) 平台安装脚本(官方)
|
|
20
|
+
|
|
21
|
+
`baozang-activator` 内部按平台调用官方安装方式:
|
|
22
|
+
|
|
23
|
+
### macOS / Linux
|
|
24
|
+
```bash
|
|
25
|
+
curl -fsSL https://openclaw.ai/install.sh | bash
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Windows CMD
|
|
29
|
+
```cmd
|
|
30
|
+
curl -fsSL https://openclaw.ai/install.cmd -o install.cmd && install.cmd && del install.cmd
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Windows PowerShell
|
|
34
|
+
```powershell
|
|
35
|
+
iwr -useb https://openclaw.ai/install.ps1 | iex
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 3) 配置写入规则(重点)
|
|
39
|
+
|
|
40
|
+
默认接入参数:
|
|
41
|
+
- provider: `https://www.baozangaizhongzhuan.net/`
|
|
42
|
+
- OpenAI 兼容 endpoint: `https://www.baozangaizhongzhuan.net/v1`
|
|
43
|
+
- model: `gpt5.4`
|
|
44
|
+
|
|
45
|
+
配置时会通过 `openclaw config set` 修改 OpenClaw 配置,关键字段:
|
|
46
|
+
- `models.providers.baozang`
|
|
47
|
+
- `agents.defaults.model.primary = "baozang/gpt5.4"`
|
|
48
|
+
- `gateway.mode = "local"`
|
|
49
|
+
|
|
50
|
+
配置完成后执行:
|
|
51
|
+
- `openclaw config validate --json`
|
|
52
|
+
- `openclaw gateway start`(必要时安装/重启网关服务)
|
|
53
|
+
|
|
54
|
+
查看当前配置文件路径:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
openclaw config file
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 4) Dashboard token 与浏览器跳转
|
|
61
|
+
|
|
62
|
+
新版本会优先执行:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
openclaw dashboard --no-open
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
并从输出中提取带 `#token=...` 的 URL 去打开浏览器,避免出现:
|
|
69
|
+
|
|
70
|
+
`unauthorized: gateway token missing`
|
|
71
|
+
|
|
72
|
+
如果你手动打开浏览器,建议使用:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
openclaw dashboard
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
或
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
openclaw dashboard --no-open
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
复制输出的完整 URL(带 `#token=`)访问。
|
|
85
|
+
|
|
86
|
+
## 5) 预装 skills(默认)
|
|
87
|
+
|
|
88
|
+
默认会预装:
|
|
89
|
+
- `xiaohongshu`
|
|
90
|
+
- `zhihu`
|
|
91
|
+
- `wechat-official`
|
|
92
|
+
- `douyin-script`
|
|
93
|
+
|
|
94
|
+
如需跳过预装:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx -y baozang-activator@latest -t openclaw <key> --openclaw-skip-skills
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 6) 干净卸载(含 CLI 命令)
|
|
101
|
+
|
|
102
|
+
### 交互式(会询问)
|
|
103
|
+
```bash
|
|
104
|
+
npx -y baozang-activator@latest --openclaw-uninstall
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 非交互一条命令
|
|
108
|
+
```bash
|
|
109
|
+
npx -y baozang-activator@latest --openclaw-uninstall -y --openclaw-remove-workspace --openclaw-remove-config --openclaw-remove-cli
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
说明:
|
|
113
|
+
- `--openclaw-remove-workspace`:删除工作区
|
|
114
|
+
- `--openclaw-remove-config`:删除配置/状态
|
|
115
|
+
- `--openclaw-remove-cli`:删除全局 `openclaw` 命令
|
|
116
|
+
|
|
117
|
+
卸载后会自动校验:
|
|
118
|
+
- 若要求删除 CLI,则校验 `openclaw` 命令已不存在
|
|
119
|
+
- 否则校验网关已停止
|
|
120
|
+
|
|
121
|
+
## 7) 常见问题
|
|
122
|
+
|
|
123
|
+
### Q1: `baozang-activator:未找到命令`
|
|
124
|
+
你执行了 `npm install baozang-activator-test@x.y.z`(本地安装),不会创建全局命令。
|
|
125
|
+
请改用:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npx -y baozang-activator@latest --help
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
或全局安装:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm i -g baozang-activator@latest
|
|
135
|
+
baozang-activator --help
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Q2: 卸载后为什么 `openclaw` 还能用?
|
|
139
|
+
通常是机器上有多个安装来源(如 npm / pnpm / yarn / 其他路径)。先定位:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
which -a openclaw
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Windows:
|
|
146
|
+
|
|
147
|
+
```powershell
|
|
148
|
+
where openclaw
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
逐个路径清理后再验证。
|
|
152
|
+
|
|
153
|
+
### Q3: 安装后提示 PATH 缺失
|
|
154
|
+
如果提示 npm 全局 bin 不在 PATH,重开终端后仍不生效时,请把对应路径加入 shell 配置(如 `~/.bashrc` / `~/.zshrc`),再 `source` 生效。
|
|
155
|
+
|
|
156
|
+
### Q4: macOS 显示 `LaunchAgent (not loaded)`,但日志里有 `RPC probe: ok`
|
|
157
|
+
这是 OpenClaw 在 macOS 上的常见状态之一。只要状态输出里同时出现:
|
|
158
|
+
|
|
159
|
+
```text
|
|
160
|
+
RPC probe: ok
|
|
161
|
+
Listening: 127.0.0.1:18789
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
就说明网关实际已经可用。`baozang-activator` `1.2.4` 起会按探活结果判定成功,不再因为 `launchctl` 的未加载提示直接报错。
|
|
165
|
+
|
|
166
|
+
### Q5: Windows 卸载报 `exit null`
|
|
167
|
+
这是 Windows 下 `.cmd` shim 调用方式导致的子进程状态异常。`baozang-activator` `1.2.4` 起会通过显式 `cmd.exe` 调用 `openclaw`,避免这个问题。
|
|
168
|
+
|
|
169
|
+
## 8) 验证清单
|
|
170
|
+
|
|
171
|
+
安装后建议至少执行一次:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
openclaw --version
|
|
175
|
+
openclaw gateway status
|
|
176
|
+
openclaw dashboard --no-open
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
卸载后建议验证:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
command -v openclaw || echo "openclaw removed"
|
|
183
|
+
```
|
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ npm i -g baozang-activator@latest
|
|
|
35
35
|
```bash
|
|
36
36
|
baozang-activator -v
|
|
37
37
|
```
|
|
38
|
-
应显示:`1.2.
|
|
38
|
+
应显示:`1.2.4`(或更高)
|
|
39
39
|
|
|
40
40
|
### 3) 重新执行激活(会刷新本地 auth.json)
|
|
41
41
|
```bash
|
|
@@ -230,6 +230,9 @@ npx baozang-activator --openclaw-uninstall --openclaw-remove-workspace --opencla
|
|
|
230
230
|
|
|
231
231
|
卸载完成后会自动校验网关状态,并打开浏览器到卸载说明页面。
|
|
232
232
|
|
|
233
|
+
OpenClaw 详细说明与常见问题:
|
|
234
|
+
- `./OPENCLAW.md`
|
|
235
|
+
|
|
233
236
|
## 命令行选项
|
|
234
237
|
|
|
235
238
|
```
|
package/lib/openclaw.js
CHANGED
|
@@ -24,6 +24,30 @@ function commandExists(command) {
|
|
|
24
24
|
return result.status === 0;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
function getCommandPath(command) {
|
|
28
|
+
const checker = IS_WINDOWS ? 'where' : 'which';
|
|
29
|
+
const result = spawnSync(checker, [command], {
|
|
30
|
+
encoding: 'utf8',
|
|
31
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
32
|
+
});
|
|
33
|
+
if (result.status !== 0) {
|
|
34
|
+
return '';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const lines = String(result.stdout || '')
|
|
38
|
+
.split(/\r?\n/)
|
|
39
|
+
.map((line) => sanitizeText(line))
|
|
40
|
+
.filter(Boolean);
|
|
41
|
+
|
|
42
|
+
for (const line of lines) {
|
|
43
|
+
if (!IS_WINDOWS || /\.cmd$|\.bat$|\.exe$/i.test(line) || fs.existsSync(line)) {
|
|
44
|
+
return line;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return lines[0] || '';
|
|
49
|
+
}
|
|
50
|
+
|
|
27
51
|
function getNpmCommand() {
|
|
28
52
|
return IS_WINDOWS ? 'npm.cmd' : 'npm';
|
|
29
53
|
}
|
|
@@ -52,9 +76,10 @@ function getNpmGlobalBin() {
|
|
|
52
76
|
}
|
|
53
77
|
|
|
54
78
|
function resolveOpenClawCommand() {
|
|
55
|
-
|
|
79
|
+
const existingPath = getCommandPath('openclaw');
|
|
80
|
+
if (existingPath) {
|
|
56
81
|
return {
|
|
57
|
-
cmd:
|
|
82
|
+
cmd: existingPath,
|
|
58
83
|
env: null,
|
|
59
84
|
};
|
|
60
85
|
}
|
|
@@ -111,6 +136,17 @@ function runShell(commandString, options = {}) {
|
|
|
111
136
|
return runCommand(bash, ['-lc', commandString], options);
|
|
112
137
|
}
|
|
113
138
|
|
|
139
|
+
function quoteWindowsArg(value) {
|
|
140
|
+
const text = String(value || '');
|
|
141
|
+
if (!text) {
|
|
142
|
+
return '""';
|
|
143
|
+
}
|
|
144
|
+
if (!/[\s"&()^<>|]/.test(text)) {
|
|
145
|
+
return text;
|
|
146
|
+
}
|
|
147
|
+
return `"${text.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\+)$/g, '$1$1')}"`;
|
|
148
|
+
}
|
|
149
|
+
|
|
114
150
|
function ensureDir(dirPath) {
|
|
115
151
|
if (!fs.existsSync(dirPath)) {
|
|
116
152
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
@@ -198,6 +234,15 @@ function getDashboardUrl(options = {}) {
|
|
|
198
234
|
function openclaw(args, options = {}) {
|
|
199
235
|
const resolved = resolveOpenClawCommand();
|
|
200
236
|
const env = resolved.env ? resolved.env : process.env;
|
|
237
|
+
if (IS_WINDOWS) {
|
|
238
|
+
const commandLine = [resolved.cmd, ...(args || [])]
|
|
239
|
+
.map((part) => quoteWindowsArg(part))
|
|
240
|
+
.join(' ');
|
|
241
|
+
return runCommand('cmd.exe', ['/d', '/s', '/c', commandLine], {
|
|
242
|
+
env,
|
|
243
|
+
...options,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
201
246
|
return runCommand(resolved.cmd, args, {
|
|
202
247
|
env,
|
|
203
248
|
...options,
|
|
@@ -490,23 +535,18 @@ function startGateway() {
|
|
|
490
535
|
}
|
|
491
536
|
|
|
492
537
|
let status = getGatewayStatusText();
|
|
493
|
-
if (
|
|
538
|
+
if (parseGatewayRunning(status.text)) {
|
|
494
539
|
return { ok: true, message: '' };
|
|
495
540
|
}
|
|
496
541
|
|
|
497
542
|
const startText = sanitizeText(`${startResult.stdout}\n${startResult.stderr}`);
|
|
498
|
-
if (
|
|
499
|
-
startResult.status === 0 &&
|
|
500
|
-
(startText.includes('Gateway service disabled') || sanitizeText(status.text).includes('disabled'))
|
|
501
|
-
) {
|
|
543
|
+
if (startResult.status === 0 && (gatewayServiceNeedsInstall(startText) || gatewayServiceNeedsInstall(status.text))) {
|
|
502
544
|
const installResult = openclaw(['gateway', 'install'], { stdio: 'inherit' });
|
|
503
545
|
if (installResult.status === 0) {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
return { ok: true, message: '' };
|
|
509
|
-
}
|
|
546
|
+
openclaw(['gateway', 'start'], { stdio: 'inherit' });
|
|
547
|
+
status = getGatewayStatusText();
|
|
548
|
+
if (parseGatewayRunning(status.text)) {
|
|
549
|
+
return { ok: true, message: '' };
|
|
510
550
|
}
|
|
511
551
|
}
|
|
512
552
|
}
|
|
@@ -523,7 +563,7 @@ function startGateway() {
|
|
|
523
563
|
child.unref();
|
|
524
564
|
sleepMs(2000);
|
|
525
565
|
status = getGatewayStatusText();
|
|
526
|
-
if (
|
|
566
|
+
if (parseGatewayRunning(status.text)) {
|
|
527
567
|
return { ok: true, message: '' };
|
|
528
568
|
}
|
|
529
569
|
} catch (error) {
|
|
@@ -564,6 +604,9 @@ function parseGatewayRunning(statusText) {
|
|
|
564
604
|
if (!text) {
|
|
565
605
|
return false;
|
|
566
606
|
}
|
|
607
|
+
if (text.includes('rpc probe: ok') || text.includes('listening: 127.0.0.1:') || text.includes('listening: localhost:')) {
|
|
608
|
+
return true;
|
|
609
|
+
}
|
|
567
610
|
if (text.includes('not running') || text.includes('stopped') || text.includes('未运行') || text.includes('已停止')) {
|
|
568
611
|
return false;
|
|
569
612
|
}
|
|
@@ -578,14 +621,30 @@ function parseGatewayStopped(statusText) {
|
|
|
578
621
|
if (!text) {
|
|
579
622
|
return false;
|
|
580
623
|
}
|
|
624
|
+
if (text.includes('rpc probe: ok') || text.includes('listening: 127.0.0.1:') || text.includes('listening: localhost:')) {
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
581
627
|
return text.includes('not running') || text.includes('stopped') || text.includes('未运行') || text.includes('已停止');
|
|
582
628
|
}
|
|
583
629
|
|
|
630
|
+
function gatewayServiceNeedsInstall(statusText) {
|
|
631
|
+
const text = sanitizeText(statusText).toLowerCase();
|
|
632
|
+
if (!text) {
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
635
|
+
return text.includes('service disabled')
|
|
636
|
+
|| text.includes('gateway service disabled')
|
|
637
|
+
|| text.includes('service not loaded')
|
|
638
|
+
|| text.includes('gateway service not loaded')
|
|
639
|
+
|| text.includes('launchagent (not loaded)')
|
|
640
|
+
|| text.includes('could not find service');
|
|
641
|
+
}
|
|
642
|
+
|
|
584
643
|
function verifyOpenClawReady() {
|
|
585
644
|
const status = getGatewayStatusText();
|
|
586
645
|
const running = parseGatewayRunning(status.text);
|
|
587
646
|
const stopped = parseGatewayStopped(status.text);
|
|
588
|
-
if (status.ok &&
|
|
647
|
+
if (running || (status.ok && !stopped)) {
|
|
589
648
|
return {
|
|
590
649
|
ok: true,
|
|
591
650
|
status: 'gateway-running',
|
|
@@ -750,7 +809,8 @@ function uninstallOpenClaw(params) {
|
|
|
750
809
|
|
|
751
810
|
const result = openclaw(args, { stdio: 'inherit' });
|
|
752
811
|
if (result.status !== 0) {
|
|
753
|
-
|
|
812
|
+
const suffix = result.error && result.error.message ? `: ${result.error.message}` : '';
|
|
813
|
+
return { ok: false, message: `OpenClaw 卸载失败(exit ${String(result.status)})${suffix}` };
|
|
754
814
|
}
|
|
755
815
|
|
|
756
816
|
if (removeCli) {
|
|
@@ -784,5 +844,12 @@ module.exports = {
|
|
|
784
844
|
openBrowser,
|
|
785
845
|
getDefaultDashboardUrl,
|
|
786
846
|
getDashboardUrl,
|
|
847
|
+
__internal: {
|
|
848
|
+
getCommandPath,
|
|
849
|
+
quoteWindowsArg,
|
|
850
|
+
parseGatewayRunning,
|
|
851
|
+
parseGatewayStopped,
|
|
852
|
+
gatewayServiceNeedsInstall,
|
|
853
|
+
},
|
|
787
854
|
HOME,
|
|
788
855
|
};
|