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 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.1`(或更高)
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
- if (commandExists('openclaw')) {
79
+ const existingPath = getCommandPath('openclaw');
80
+ if (existingPath) {
56
81
  return {
57
- cmd: 'openclaw',
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 (status.ok && parseGatewayRunning(status.text)) {
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
- const retry = openclaw(['gateway', 'start'], { stdio: 'inherit' });
505
- if (retry.status === 0) {
506
- status = getGatewayStatusText();
507
- if (status.ok && parseGatewayRunning(status.text)) {
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 (status.ok && parseGatewayRunning(status.text)) {
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 && (running || !stopped)) {
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
- return { ok: false, message: `OpenClaw 卸载失败(exit ${result.status})` };
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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baozang-activator",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "API 激活工具 (生产环境 - baozangaizhongzhuan.net)",
5
5
  "main": "lib/index.js",
6
6
  "bin": {