baozang-activator 1.2.0 → 1.2.2

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.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.0`(或更高)
38
+ 应显示:`1.2.1`(或更高)
39
39
 
40
40
  ### 3) 重新执行激活(会刷新本地 auth.json)
41
41
  ```bash
@@ -201,7 +201,7 @@ requires_openai_auth = true
201
201
  - 配置完成后会自动:
202
202
  - 启动网关 `openclaw gateway start`
203
203
  - 校验安装结果(版本 + 网关状态)
204
- - 自动打开浏览器到网关 Dashboard(默认 `http://127.0.0.1:18789/`)
204
+ - 自动通过 `openclaw dashboard --no-open` 获取带 token 的 Dashboard 链接并打开浏览器(默认地址 `http://127.0.0.1:18789/`)
205
205
  - 提示后续操作(默认不需要关联社交账号)
206
206
  - 可预装常见 skills(默认开启):`xiaohongshu`、`zhihu`、`wechat-official`、`douyin-script`
207
207
 
@@ -221,11 +221,11 @@ npx baozang-activator -t openclaw sk-xxxx --openclaw-skip-skills
221
221
  OpenClaw 卸载命令示例:
222
222
 
223
223
  ```bash
224
- # 交互询问是否删除 workspace / config(state)
224
+ # 交互询问是否删除 workspace / config(state) / CLI 命令
225
225
  npx baozang-activator --openclaw-uninstall
226
226
 
227
227
  # 非交互指定删除策略
228
- npx baozang-activator --openclaw-uninstall --openclaw-remove-workspace --openclaw-remove-config
228
+ npx baozang-activator --openclaw-uninstall --openclaw-remove-workspace --openclaw-remove-config --openclaw-remove-cli
229
229
  ```
230
230
 
231
231
  卸载完成后会自动校验网关状态,并打开浏览器到卸载说明页面。
@@ -241,6 +241,7 @@ npx baozang-activator --openclaw-uninstall --openclaw-remove-workspace --opencla
241
241
  --openclaw-uninstall 卸载 OpenClaw
242
242
  --openclaw-remove-workspace 卸载时删除 workspace
243
243
  --openclaw-remove-config 卸载时删除 state/config
244
+ --openclaw-remove-cli 卸载时删除全局 openclaw CLI
244
245
  --skip-activation 跳过卡密激活与余额校验
245
246
  -h, --help 显示帮助信息
246
247
  -v, --version 显示版本号
package/bin/cli.js CHANGED
@@ -64,6 +64,7 @@ function parseArgs() {
64
64
  openclawUninstall: false,
65
65
  openclawRemoveWorkspace: false,
66
66
  openclawRemoveConfig: false,
67
+ openclawRemoveCli: false,
67
68
  openclawSkipSkills: false,
68
69
  };
69
70
 
@@ -87,6 +88,8 @@ function parseArgs() {
87
88
  result.openclawRemoveWorkspace = true;
88
89
  } else if (arg === '--openclaw-remove-config' || arg === '--openclaw-remove-state') {
89
90
  result.openclawRemoveConfig = true;
91
+ } else if (arg === '--openclaw-remove-cli') {
92
+ result.openclawRemoveCli = true;
90
93
  } else if (arg === '--openclaw-skip-skills') {
91
94
  result.openclawSkipSkills = true;
92
95
  } else if (arg === '--openclaw') {
@@ -119,6 +122,7 @@ ${chalk.yellow('选项:')}
119
122
  --openclaw-uninstall 卸载 OpenClaw(默认仅卸载网关服务)
120
123
  --openclaw-remove-workspace 卸载时删除工作区(workspace)
121
124
  --openclaw-remove-config 卸载时删除配置/状态文件(state)
125
+ --openclaw-remove-cli 卸载时删除全局 openclaw CLI 命令
122
126
  --openclaw-skip-skills 安装 OpenClaw 时跳过预装 skills
123
127
  --openclaw 等价于 -t openclaw
124
128
  -h, --help 显示帮助信息
@@ -138,7 +142,7 @@ ${chalk.yellow('示例:')}
138
142
  npx baozang-activator -y sk-ant-xxx 跳过确认直接配置
139
143
  npx baozang-activator -t codex sk-xxx 强制配置为 Codex
140
144
  npx baozang-activator -t openclaw sk-xxx 一键安装并配置 OpenClaw 网关
141
- npx baozang-activator --openclaw-uninstall --openclaw-remove-workspace --openclaw-remove-config
145
+ npx baozang-activator --openclaw-uninstall --openclaw-remove-workspace --openclaw-remove-config --openclaw-remove-cli
142
146
  `);
143
147
  }
144
148
 
@@ -280,11 +284,16 @@ async function doConfig(type, apiKey, config) {
280
284
 
281
285
  console.log('');
282
286
  console.log(chalk.yellow('打开网关控制台(Dashboard):'));
283
- console.log(chalk.cyan(` ${result.dashboardUrl || 'http://127.0.0.1:18789/'}`));
287
+ const dashboardDisplayUrl = result.dashboardUrl || 'http://127.0.0.1:18789/';
288
+ const dashboardOpenUrl = result.dashboardOpenUrl || dashboardDisplayUrl;
289
+ console.log(chalk.cyan(` ${dashboardDisplayUrl}`));
290
+ if (result.dashboardTokenized) {
291
+ console.log(chalk.gray(' (已自动携带 gateway token 打开浏览器)'));
292
+ }
284
293
 
285
- const opened = openBrowser(result.dashboardUrl || 'http://127.0.0.1:18789/');
294
+ const opened = openBrowser(dashboardOpenUrl);
286
295
  if (!opened) {
287
- console.log(chalk.gray(' (无法自动打开浏览器,请手动复制以上地址到浏览器)'));
296
+ console.log(chalk.gray(' (无法自动打开浏览器,请运行 openclaw dashboard 或 openclaw dashboard --no-open 获取带 token 链接)'));
288
297
  }
289
298
 
290
299
  console.log('');
@@ -505,6 +514,7 @@ async function main() {
505
514
 
506
515
  let removeWorkspace = args.openclawRemoveWorkspace;
507
516
  let removeConfig = args.openclawRemoveConfig;
517
+ let removeCli = args.openclawRemoveCli;
508
518
 
509
519
  if (isInteractive() && !args.yes) {
510
520
  if (!args.openclawRemoveWorkspace) {
@@ -525,19 +535,31 @@ async function main() {
525
535
  }]);
526
536
  removeConfig = !!answer.removeConfig;
527
537
  }
538
+ if (!args.openclawRemoveCli) {
539
+ const answer = await inquirer.prompt([{
540
+ type: 'confirm',
541
+ name: 'removeCli',
542
+ message: '卸载 OpenClaw 时是否删除全局 CLI 命令(openclaw)?',
543
+ default: true,
544
+ }]);
545
+ removeCli = !!answer.removeCli;
546
+ }
528
547
  }
529
548
 
530
549
  log.info('正在卸载 OpenClaw...');
531
550
  const uninstalled = uninstallOpenClaw({
532
551
  removeWorkspace,
533
552
  removeState: removeConfig,
553
+ removeCli,
534
554
  });
535
555
  if (!uninstalled.ok) {
536
556
  log.error(uninstalled.message || '卸载失败');
537
557
  process.exit(1);
538
558
  }
539
559
 
540
- const verified = verifyOpenClawUninstalled();
560
+ const verified = verifyOpenClawUninstalled({
561
+ expectCommandRemoved: removeCli,
562
+ });
541
563
  if (!verified.ok) {
542
564
  log.error(`卸载后校验失败: ${verified.text || '网关仍在运行'}`);
543
565
  process.exit(1);
@@ -649,6 +649,7 @@ function configureOpenClaw(apiKey, config) {
649
649
  restartGateway,
650
650
  getGatewayStatusText,
651
651
  installBuiltinSkills,
652
+ getDashboardUrl,
652
653
  getDefaultDashboardUrl,
653
654
  } = require('./openclaw');
654
655
 
@@ -711,6 +712,9 @@ function configureOpenClaw(apiKey, config) {
711
712
  }
712
713
 
713
714
  const gatewayStatus = getGatewayStatusText();
715
+ const dashboard = getDashboardUrl({ includeToken: true });
716
+ const dashboardUrl = getDefaultDashboardUrl();
717
+ const dashboardOpenUrl = sanitizeValue((dashboard && dashboard.url) || '') || dashboardUrl;
714
718
 
715
719
  return {
716
720
  installed: install.installed,
@@ -721,7 +725,9 @@ function configureOpenClaw(apiKey, config) {
721
725
  modelId,
722
726
  primaryModel,
723
727
  configFile,
724
- dashboardUrl: getDefaultDashboardUrl(),
728
+ dashboardUrl,
729
+ dashboardOpenUrl,
730
+ dashboardTokenized: !!(dashboard && dashboard.tokenized),
725
731
  gatewayStatus: gatewayStatus.text,
726
732
  skillsDir: skillMeta ? skillMeta.dir : '',
727
733
  installedSkills: skillMeta ? skillMeta.skills : [],
package/lib/index.js CHANGED
@@ -24,9 +24,11 @@ const {
24
24
  restartGateway,
25
25
  getGatewayStatusText,
26
26
  installBuiltinSkills,
27
+ uninstallOpenClawCli,
27
28
  uninstallOpenClaw,
28
29
  openBrowser,
29
30
  getDefaultDashboardUrl,
31
+ getDashboardUrl,
30
32
  } = require('./openclaw');
31
33
 
32
34
  module.exports = {
@@ -55,7 +57,9 @@ module.exports = {
55
57
  restartGateway,
56
58
  getGatewayStatusText,
57
59
  installBuiltinSkills,
60
+ uninstallOpenClawCli,
58
61
  uninstallOpenClaw,
59
62
  openBrowser,
60
63
  getDefaultDashboardUrl,
64
+ getDashboardUrl,
61
65
  };
package/lib/openclaw.js CHANGED
@@ -28,6 +28,10 @@ function getNpmCommand() {
28
28
  return IS_WINDOWS ? 'npm.cmd' : 'npm';
29
29
  }
30
30
 
31
+ function getYarnCommand() {
32
+ return IS_WINDOWS ? 'yarn.cmd' : 'yarn';
33
+ }
34
+
31
35
  function getNpmGlobalBin() {
32
36
  try {
33
37
  const result = spawnSync(getNpmCommand(), ['prefix', '-g'], {
@@ -148,6 +152,49 @@ function getDefaultDashboardUrl() {
148
152
  return 'http://127.0.0.1:18789/';
149
153
  }
150
154
 
155
+ function extractFirstUrl(text) {
156
+ const matched = String(text || '').match(/https?:\/\/[^\s"'<>]+/i);
157
+ if (!matched) {
158
+ return '';
159
+ }
160
+ return sanitizeText(matched[0]).replace(/[),.;]+$/, '');
161
+ }
162
+
163
+ function getDashboardUrl(options = {}) {
164
+ const includeToken = (options && options.includeToken) !== false;
165
+ const fallback = getDefaultDashboardUrl();
166
+ if (!includeToken) {
167
+ return {
168
+ ok: true,
169
+ url: fallback,
170
+ tokenized: false,
171
+ source: 'default',
172
+ error: '',
173
+ };
174
+ }
175
+
176
+ const result = openclaw(['dashboard', '--no-open'], { stdio: ['ignore', 'pipe', 'pipe'] });
177
+ const combined = `${result.stdout || ''}\n${result.stderr || ''}`;
178
+ const url = extractFirstUrl(combined);
179
+ if (url) {
180
+ return {
181
+ ok: true,
182
+ url,
183
+ tokenized: url.includes('#token='),
184
+ source: 'openclaw-dashboard',
185
+ error: '',
186
+ };
187
+ }
188
+
189
+ return {
190
+ ok: false,
191
+ url: fallback,
192
+ tokenized: false,
193
+ source: 'default',
194
+ error: sanitizeText(combined || '无法获取 Dashboard 地址'),
195
+ };
196
+ }
197
+
151
198
  function openclaw(args, options = {}) {
152
199
  const resolved = resolveOpenClawCommand();
153
200
  const env = resolved.env ? resolved.env : process.env;
@@ -552,7 +599,8 @@ function verifyOpenClawReady() {
552
599
  };
553
600
  }
554
601
 
555
- function verifyOpenClawUninstalled() {
602
+ function verifyOpenClawUninstalled(options = {}) {
603
+ const expectCommandRemoved = !!(options && options.expectCommandRemoved);
556
604
  const resolved = resolveOpenClawCommand();
557
605
  const hasCommand = commandExists('openclaw') || (!!resolved.cmd && fs.existsSync(resolved.cmd));
558
606
  if (!hasCommand) {
@@ -563,6 +611,14 @@ function verifyOpenClawUninstalled() {
563
611
  };
564
612
  }
565
613
 
614
+ if (expectCommandRemoved) {
615
+ return {
616
+ ok: false,
617
+ status: 'command-still-present',
618
+ text: 'openclaw 命令仍存在(请执行 npm uninstall -g openclaw)',
619
+ };
620
+ }
621
+
566
622
  const status = getGatewayStatusText();
567
623
  const running = parseGatewayRunning(status.text);
568
624
  if (!running) {
@@ -617,9 +673,68 @@ function installBuiltinSkills(options = {}) {
617
673
  };
618
674
  }
619
675
 
676
+ function uninstallOpenClawCli() {
677
+ const attempts = [];
678
+ const maybeCommands = [];
679
+
680
+ if (commandExists(getNpmCommand()) || commandExists('npm')) {
681
+ maybeCommands.push({
682
+ cmd: getNpmCommand(),
683
+ args: ['uninstall', '-g', 'openclaw'],
684
+ name: 'npm',
685
+ });
686
+ }
687
+ if (commandExists('pnpm')) {
688
+ maybeCommands.push({
689
+ cmd: 'pnpm',
690
+ args: ['remove', '-g', 'openclaw'],
691
+ name: 'pnpm',
692
+ });
693
+ }
694
+ if (commandExists(getYarnCommand()) || commandExists('yarn')) {
695
+ maybeCommands.push({
696
+ cmd: getYarnCommand(),
697
+ args: ['global', 'remove', 'openclaw'],
698
+ name: 'yarn',
699
+ });
700
+ }
701
+
702
+ for (const item of maybeCommands) {
703
+ const result = runCommand(item.cmd, item.args, { stdio: 'inherit' });
704
+ attempts.push(`${item.name}:${result.status}`);
705
+ const resolved = resolveOpenClawCommand();
706
+ const stillExists = commandExists('openclaw') || (!!resolved.cmd && fs.existsSync(resolved.cmd));
707
+ if (!stillExists) {
708
+ return {
709
+ ok: true,
710
+ attempts,
711
+ message: '',
712
+ };
713
+ }
714
+ }
715
+
716
+ const resolved = resolveOpenClawCommand();
717
+ const stillExists = commandExists('openclaw') || (!!resolved.cmd && fs.existsSync(resolved.cmd));
718
+ if (!stillExists) {
719
+ return {
720
+ ok: true,
721
+ attempts,
722
+ message: '',
723
+ };
724
+ }
725
+ return {
726
+ ok: false,
727
+ attempts,
728
+ message: attempts.length > 0
729
+ ? `已尝试卸载 CLI(${attempts.join(', ')}),但 openclaw 命令仍存在`
730
+ : '未检测到可用包管理器,无法自动卸载 openclaw CLI',
731
+ };
732
+ }
733
+
620
734
  function uninstallOpenClaw(params) {
621
735
  const removeWorkspace = !!(params && params.removeWorkspace);
622
736
  const removeState = !!(params && params.removeState);
737
+ const removeCli = !!(params && params.removeCli);
623
738
 
624
739
  if (!commandExists('openclaw') && !fs.existsSync(resolveOpenClawCommand().cmd)) {
625
740
  return { ok: false, message: '未找到 openclaw 命令,无法执行卸载' };
@@ -637,6 +752,17 @@ function uninstallOpenClaw(params) {
637
752
  if (result.status !== 0) {
638
753
  return { ok: false, message: `OpenClaw 卸载失败(exit ${result.status})` };
639
754
  }
755
+
756
+ if (removeCli) {
757
+ const cli = uninstallOpenClawCli();
758
+ if (!cli.ok) {
759
+ return {
760
+ ok: false,
761
+ message: cli.message || 'OpenClaw CLI 卸载失败',
762
+ };
763
+ }
764
+ }
765
+
640
766
  return { ok: true, message: '' };
641
767
  }
642
768
 
@@ -648,6 +774,7 @@ module.exports = {
648
774
  configureBaozangProvider,
649
775
  getOpenClawConfigFile,
650
776
  validateOpenClawConfig,
777
+ uninstallOpenClawCli,
651
778
  onboardOpenClaw,
652
779
  startGateway,
653
780
  restartGateway,
@@ -656,5 +783,6 @@ module.exports = {
656
783
  uninstallOpenClaw,
657
784
  openBrowser,
658
785
  getDefaultDashboardUrl,
786
+ getDashboardUrl,
659
787
  HOME,
660
788
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baozang-activator",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "API 激活工具 (生产环境 - baozangaizhongzhuan.net)",
5
5
  "main": "lib/index.js",
6
6
  "bin": {