openclawsetup 1.0.5 → 1.0.7
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/bin/cli.mjs +296 -70
- package/package.json +1 -1
package/bin/cli.mjs
CHANGED
|
@@ -18,10 +18,11 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import { execSync, spawn } from 'child_process';
|
|
21
|
-
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
21
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, rmSync } from 'fs';
|
|
22
22
|
import { homedir, platform } from 'os';
|
|
23
23
|
import { join } from 'path';
|
|
24
24
|
import { randomBytes } from 'crypto';
|
|
25
|
+
import { createInterface } from 'readline';
|
|
25
26
|
|
|
26
27
|
// 解析命令行参数
|
|
27
28
|
function parseArgs() {
|
|
@@ -167,32 +168,187 @@ function checkNodeVersion() {
|
|
|
167
168
|
return true;
|
|
168
169
|
}
|
|
169
170
|
|
|
171
|
+
// 交互式提示用户选择
|
|
172
|
+
function promptChoice(question, choices) {
|
|
173
|
+
return new Promise((resolve) => {
|
|
174
|
+
const rl = createInterface({
|
|
175
|
+
input: process.stdin,
|
|
176
|
+
output: process.stdout,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
console.log(colors.cyan(`\n${question}`));
|
|
180
|
+
choices.forEach((choice, i) => {
|
|
181
|
+
console.log(` ${colors.yellow(i + 1)}. ${choice.label}`);
|
|
182
|
+
});
|
|
183
|
+
console.log(` ${colors.yellow(0)}. 退出`);
|
|
184
|
+
|
|
185
|
+
rl.question(colors.cyan('\n请输入选项编号: '), (answer) => {
|
|
186
|
+
rl.close();
|
|
187
|
+
const num = parseInt(answer, 10);
|
|
188
|
+
if (num === 0 || isNaN(num) || num > choices.length) {
|
|
189
|
+
resolve(null);
|
|
190
|
+
} else {
|
|
191
|
+
resolve(choices[num - 1].value);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// 检查并更新 OpenClaw
|
|
198
|
+
async function checkAndUpdate(cliName) {
|
|
199
|
+
console.log(colors.cyan('\n检查更新中...'));
|
|
200
|
+
|
|
201
|
+
// 获取当前版本
|
|
202
|
+
const currentResult = safeExec(`${cliName} --version`);
|
|
203
|
+
const currentVersion = currentResult.ok ? currentResult.output : '未知';
|
|
204
|
+
console.log(` 当前版本: ${colors.yellow(currentVersion)}`);
|
|
205
|
+
|
|
206
|
+
// 更新到最新版本
|
|
207
|
+
log.info('正在更新到最新版本...');
|
|
208
|
+
const updateResult = await execWithProgress(
|
|
209
|
+
`npm install -g ${cliName}@latest`,
|
|
210
|
+
`正在更新 ${cliName}...`,
|
|
211
|
+
{ timeout: 300000 }
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
if (updateResult.ok) {
|
|
215
|
+
const newResult = safeExec(`${cliName} --version`);
|
|
216
|
+
const newVersion = newResult.ok ? newResult.output : '未知';
|
|
217
|
+
if (newVersion !== currentVersion) {
|
|
218
|
+
log.success(`更新完成: ${currentVersion} → ${newVersion}`);
|
|
219
|
+
} else {
|
|
220
|
+
log.success(`已是最新版本: ${newVersion}`);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// 重启 Gateway
|
|
224
|
+
console.log(colors.cyan('\n重启 Gateway 服务...'));
|
|
225
|
+
const restartResult = safeExec(`${cliName} gateway restart`);
|
|
226
|
+
if (restartResult.ok) {
|
|
227
|
+
log.success('Gateway 已重启');
|
|
228
|
+
} else {
|
|
229
|
+
log.warn('Gateway 重启失败,请手动重启: ' + cliName + ' gateway restart');
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
log.error('更新失败: ' + (updateResult.error || '未知错误'));
|
|
233
|
+
log.hint('可以手动更新: npm install -g ' + cliName + '@latest');
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// 卸载并重新安装
|
|
238
|
+
async function uninstallAndReinstall(existing, options) {
|
|
239
|
+
console.log(colors.cyan('\n开始卸载...'));
|
|
240
|
+
|
|
241
|
+
// 停止服务
|
|
242
|
+
log.info('停止 Gateway 服务...');
|
|
243
|
+
safeExec(`${existing.name} gateway stop`);
|
|
244
|
+
|
|
245
|
+
// 卸载 npm 包
|
|
246
|
+
log.info('卸载 npm 包...');
|
|
247
|
+
const uninstallResult = await execWithProgress(
|
|
248
|
+
`npm uninstall -g ${existing.name}`,
|
|
249
|
+
`正在卸载 ${existing.name}...`,
|
|
250
|
+
{ timeout: 60000 }
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
if (uninstallResult.ok) {
|
|
254
|
+
log.success('npm 包已卸载');
|
|
255
|
+
} else {
|
|
256
|
+
log.warn('npm 卸载可能未完成: ' + (uninstallResult.error || ''));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// 删除配置目录
|
|
260
|
+
if (existing.configDir && existsSync(existing.configDir)) {
|
|
261
|
+
log.info('删除配置目录...');
|
|
262
|
+
try {
|
|
263
|
+
rmSync(existing.configDir, { recursive: true, force: true });
|
|
264
|
+
log.success('配置目录已删除');
|
|
265
|
+
} catch (e) {
|
|
266
|
+
log.warn('配置目录删除失败: ' + e.message);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// 删除服务持久化配置
|
|
271
|
+
const os = platform();
|
|
272
|
+
if (os === 'darwin') {
|
|
273
|
+
const plistPath = join(homedir(), 'Library', 'LaunchAgents', 'com.openclaw.gateway.plist');
|
|
274
|
+
if (existsSync(plistPath)) {
|
|
275
|
+
safeExec('launchctl unload ' + plistPath);
|
|
276
|
+
try {
|
|
277
|
+
rmSync(plistPath);
|
|
278
|
+
log.success('macOS 服务配置已删除');
|
|
279
|
+
} catch (e) {}
|
|
280
|
+
}
|
|
281
|
+
} else if (os === 'linux') {
|
|
282
|
+
safeExec('systemctl --user stop openclaw');
|
|
283
|
+
safeExec('systemctl --user disable openclaw');
|
|
284
|
+
const servicePath = join(homedir(), '.config', 'systemd', 'user', 'openclaw.service');
|
|
285
|
+
if (existsSync(servicePath)) {
|
|
286
|
+
try {
|
|
287
|
+
rmSync(servicePath);
|
|
288
|
+
log.success('Linux 服务配置已删除');
|
|
289
|
+
} catch (e) {}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
console.log(colors.green('\n✓ 卸载完成,开始重新安装...\n'));
|
|
294
|
+
|
|
295
|
+
// 重新安装
|
|
296
|
+
const cliName = await installOpenClaw();
|
|
297
|
+
const config = createConfig(options);
|
|
298
|
+
|
|
299
|
+
if (!options.skipDaemon) {
|
|
300
|
+
setupDaemon(cliName);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!options.skipStart) {
|
|
304
|
+
startService(cliName);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return { cliName, config };
|
|
308
|
+
}
|
|
309
|
+
|
|
170
310
|
// 检测现有安装
|
|
171
311
|
function detectExistingInstall() {
|
|
172
312
|
const home = homedir();
|
|
173
313
|
const openclawDir = join(home, '.openclaw');
|
|
174
314
|
const clawdbotDir = join(home, '.clawdbot');
|
|
175
315
|
|
|
316
|
+
let result = { installed: false };
|
|
317
|
+
|
|
176
318
|
if (existsSync(openclawDir) || existsSync(clawdbotDir)) {
|
|
177
|
-
|
|
319
|
+
result = {
|
|
178
320
|
installed: true,
|
|
179
321
|
configDir: existsSync(openclawDir) ? openclawDir : clawdbotDir,
|
|
180
322
|
name: existsSync(openclawDir) ? 'openclaw' : 'clawdbot',
|
|
181
323
|
};
|
|
324
|
+
} else {
|
|
325
|
+
// 检查命令是否存在
|
|
326
|
+
const openclawResult = safeExec('openclaw --version');
|
|
327
|
+
if (openclawResult.ok) {
|
|
328
|
+
result = { installed: true, name: 'openclaw', version: openclawResult.output, configDir: openclawDir };
|
|
329
|
+
} else {
|
|
330
|
+
const clawdbotResult = safeExec('clawdbot --version');
|
|
331
|
+
if (clawdbotResult.ok) {
|
|
332
|
+
result = { installed: true, name: 'clawdbot', version: clawdbotResult.output, configDir: clawdbotDir };
|
|
333
|
+
}
|
|
334
|
+
}
|
|
182
335
|
}
|
|
183
336
|
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
337
|
+
// 如果已安装,尝试读取配置获取 token 和 port
|
|
338
|
+
if (result.installed && result.configDir) {
|
|
339
|
+
const configPath = join(result.configDir, result.name === 'openclaw' ? 'openclaw.json' : 'clawdbot.json');
|
|
340
|
+
if (existsSync(configPath)) {
|
|
341
|
+
try {
|
|
342
|
+
const config = JSON.parse(readFileSync(configPath, 'utf8'));
|
|
343
|
+
result.token = config.gateway?.auth?.token;
|
|
344
|
+
result.port = config.gateway?.port || 18789;
|
|
345
|
+
} catch (e) {
|
|
346
|
+
// 忽略解析错误
|
|
347
|
+
}
|
|
348
|
+
}
|
|
193
349
|
}
|
|
194
350
|
|
|
195
|
-
return
|
|
351
|
+
return result;
|
|
196
352
|
}
|
|
197
353
|
|
|
198
354
|
// 带进度动画的命令执行
|
|
@@ -519,6 +675,57 @@ function startService(cliName) {
|
|
|
519
675
|
return false;
|
|
520
676
|
}
|
|
521
677
|
|
|
678
|
+
// 显示安装完成信息
|
|
679
|
+
function showCompletionInfo(cliName, config, isVPS) {
|
|
680
|
+
console.log(colors.bold(colors.green('\n========================================')));
|
|
681
|
+
console.log(colors.bold(colors.green('✅ OpenClaw 安装完成!')));
|
|
682
|
+
console.log(colors.bold(colors.green('========================================')));
|
|
683
|
+
|
|
684
|
+
console.log(colors.cyan('\n配置信息:'));
|
|
685
|
+
console.log(` 配置目录: ${colors.yellow(config.configDir)}`);
|
|
686
|
+
console.log(` Gateway 端口: ${colors.yellow(config.port)}`);
|
|
687
|
+
console.log(` Gateway Token: ${colors.yellow(config.token)}`);
|
|
688
|
+
|
|
689
|
+
// 根据环境显示不同的访问说明
|
|
690
|
+
if (isVPS) {
|
|
691
|
+
console.log(colors.cyan('\n📡 Dashboard 访问 (云服务器):'));
|
|
692
|
+
console.log(colors.gray(' Gateway 默认绑定 127.0.0.1,外部无法直接访问(安全设计)'));
|
|
693
|
+
console.log('');
|
|
694
|
+
console.log(colors.yellow(' 方式一:SSH 隧道(推荐,安全)'));
|
|
695
|
+
console.log(colors.gray(' 在本地电脑执行以下命令,保持终端窗口打开:'));
|
|
696
|
+
console.log(` ssh -N -L ${config.port}:127.0.0.1:${config.port} root@<服务器IP>`);
|
|
697
|
+
console.log(colors.gray(' 然后在本地浏览器访问:'));
|
|
698
|
+
console.log(` ${colors.green(`http://127.0.0.1:${config.port}/?token=${config.token}`)}`);
|
|
699
|
+
console.log('');
|
|
700
|
+
console.log(colors.yellow(' 方式二:直接暴露端口(不推荐,有安全风险)'));
|
|
701
|
+
console.log(colors.gray(' 1. 修改配置文件 ~/.openclaw/openclaw.json'));
|
|
702
|
+
console.log(colors.gray(' 将 "bind": "loopback" 改为 "bind": "all"'));
|
|
703
|
+
console.log(colors.gray(' 2. 在云服务器控制台开放端口 ' + config.port));
|
|
704
|
+
console.log(colors.gray(' - 腾讯云:安全组 → 入站规则 → 添加 TCP ' + config.port));
|
|
705
|
+
console.log(colors.gray(' - 阿里云:安全组 → 配置规则 → 添加 TCP ' + config.port));
|
|
706
|
+
console.log(colors.gray(' 3. 重启 Gateway:' + cliName + ' gateway restart'));
|
|
707
|
+
console.log(colors.gray(' 4. 访问:http://<服务器IP>:' + config.port + '/?token=...'));
|
|
708
|
+
} else {
|
|
709
|
+
console.log(colors.cyan('\nDashboard 访问:'));
|
|
710
|
+
console.log(` ${colors.yellow(`http://127.0.0.1:${config.port}/?token=${config.token}`)}`);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
console.log(colors.cyan('\n下一步 - 配置 AI 模型:'));
|
|
714
|
+
console.log(` ${colors.yellow('npx openclawapi@latest preset-claude')}`);
|
|
715
|
+
|
|
716
|
+
console.log(colors.cyan('\n常用命令:'));
|
|
717
|
+
console.log(` 查看状态: ${colors.yellow(`${cliName} status`)}`);
|
|
718
|
+
console.log(` 查看日志: ${colors.yellow(`${cliName} gateway logs`)}`);
|
|
719
|
+
console.log(` 重启服务: ${colors.yellow(`${cliName} gateway restart`)}`);
|
|
720
|
+
console.log(` 诊断问题: ${colors.yellow(`${cliName} doctor`)}`);
|
|
721
|
+
|
|
722
|
+
console.log(colors.cyan('\n配置聊天渠道:'));
|
|
723
|
+
console.log(` Discord: ${colors.yellow('npx openclawdc')}`);
|
|
724
|
+
console.log(` 飞书: ${colors.yellow('npx openclawfs')}`);
|
|
725
|
+
|
|
726
|
+
console.log('');
|
|
727
|
+
}
|
|
728
|
+
|
|
522
729
|
// 检测是否在云服务器/VPS 上运行
|
|
523
730
|
function detectVPS() {
|
|
524
731
|
// 检查常见的云服务器特征
|
|
@@ -550,18 +757,85 @@ async function main() {
|
|
|
550
757
|
// 检测现有安装
|
|
551
758
|
const existing = detectExistingInstall();
|
|
552
759
|
if (existing.installed) {
|
|
553
|
-
console.log(colors.
|
|
760
|
+
console.log(colors.bold(colors.green('\n========================================')));
|
|
761
|
+
console.log(colors.bold(colors.green('✅ OpenClaw 已安装')));
|
|
762
|
+
console.log(colors.bold(colors.green('========================================')));
|
|
763
|
+
|
|
554
764
|
if (existing.configDir) {
|
|
555
|
-
log.
|
|
765
|
+
console.log(colors.cyan('\n配置信息:'));
|
|
766
|
+
console.log(` 配置目录: ${colors.yellow(existing.configDir)}`);
|
|
556
767
|
}
|
|
557
768
|
if (existing.version) {
|
|
558
|
-
log
|
|
769
|
+
console.log(` 版本: ${colors.yellow(existing.version)}`);
|
|
770
|
+
}
|
|
771
|
+
if (existing.port) {
|
|
772
|
+
console.log(` Gateway 端口: ${colors.yellow(existing.port)}`);
|
|
773
|
+
}
|
|
774
|
+
if (existing.token) {
|
|
775
|
+
console.log(` Gateway Token: ${colors.yellow(existing.token)}`);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// 检测是否在 VPS 上
|
|
779
|
+
const isVPS = detectVPS();
|
|
780
|
+
const port = existing.port || 18789;
|
|
781
|
+
const token = existing.token || '<你的token>';
|
|
782
|
+
|
|
783
|
+
// 显示访问说明
|
|
784
|
+
if (isVPS) {
|
|
785
|
+
console.log(colors.cyan('\n📡 Dashboard 访问 (云服务器):'));
|
|
786
|
+
console.log(colors.gray(' Gateway 默认绑定 127.0.0.1,外部无法直接访问(安全设计)'));
|
|
787
|
+
console.log('');
|
|
788
|
+
console.log(colors.yellow(' 方式一:SSH 隧道(推荐,安全)'));
|
|
789
|
+
console.log(colors.gray(' 在本地电脑执行以下命令,保持终端窗口打开:'));
|
|
790
|
+
console.log(` ssh -N -L ${port}:127.0.0.1:${port} root@<服务器IP>`);
|
|
791
|
+
console.log(colors.gray(' 然后在本地浏览器访问:'));
|
|
792
|
+
console.log(` ${colors.green(`http://127.0.0.1:${port}/?token=${token}`)}`);
|
|
793
|
+
console.log('');
|
|
794
|
+
console.log(colors.yellow(' 方式二:直接暴露端口(不推荐,有安全风险)'));
|
|
795
|
+
console.log(colors.gray(' 1. 修改配置文件 ~/.openclaw/openclaw.json'));
|
|
796
|
+
console.log(colors.gray(' 将 "bind": "loopback" 改为 "bind": "all"'));
|
|
797
|
+
console.log(colors.gray(' 2. 在云服务器控制台开放端口 ' + port));
|
|
798
|
+
console.log(colors.gray(' - 腾讯云:安全组 → 入站规则 → 添加 TCP ' + port));
|
|
799
|
+
console.log(colors.gray(' - 阿里云:安全组 → 配置规则 → 添加 TCP ' + port));
|
|
800
|
+
console.log(colors.gray(' 3. 重启 Gateway:' + existing.name + ' gateway restart'));
|
|
801
|
+
console.log(colors.gray(' 4. 访问:http://<服务器IP>:' + port + '/?token=...'));
|
|
802
|
+
} else {
|
|
803
|
+
console.log(colors.cyan('\nDashboard 访问:'));
|
|
804
|
+
console.log(` ${colors.yellow(`http://127.0.0.1:${port}/?token=${token}`)}`);
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
console.log(colors.cyan('\n常用命令:'));
|
|
808
|
+
console.log(` 查看状态: ${colors.yellow(`${existing.name} status`)}`);
|
|
809
|
+
console.log(` 查看日志: ${colors.yellow(`${existing.name} gateway logs`)}`);
|
|
810
|
+
console.log(` 重启服务: ${colors.yellow(`${existing.name} gateway restart`)}`);
|
|
811
|
+
console.log(` 诊断问题: ${colors.yellow(`${existing.name} doctor`)}`);
|
|
812
|
+
|
|
813
|
+
console.log(colors.cyan('\n配置 AI 模型:'));
|
|
814
|
+
console.log(` ${colors.yellow('npx openclawapi@latest preset-claude')}`);
|
|
815
|
+
|
|
816
|
+
console.log(colors.cyan('\n配置聊天渠道:'));
|
|
817
|
+
console.log(` Discord: ${colors.yellow('npx openclawdc')}`);
|
|
818
|
+
console.log(` 飞书: ${colors.yellow('npx openclawfs')}`);
|
|
819
|
+
|
|
820
|
+
// 显示选项
|
|
821
|
+
const choice = await promptChoice('请选择操作:', [
|
|
822
|
+
{ label: '检查并更新 OpenClaw', value: 'update' },
|
|
823
|
+
{ label: '卸载后重新安装(会清除配置)', value: 'reinstall' },
|
|
824
|
+
]);
|
|
825
|
+
|
|
826
|
+
if (choice === 'update') {
|
|
827
|
+
await checkAndUpdate(existing.name);
|
|
828
|
+
console.log('');
|
|
829
|
+
process.exit(0);
|
|
830
|
+
} else if (choice === 'reinstall') {
|
|
831
|
+
const result = await uninstallAndReinstall(existing, options);
|
|
832
|
+
// 显示安装完成信息
|
|
833
|
+
showCompletionInfo(result.cliName, result.config, isVPS);
|
|
834
|
+
process.exit(0);
|
|
835
|
+
} else {
|
|
836
|
+
console.log(colors.gray('\n已退出'));
|
|
837
|
+
process.exit(0);
|
|
559
838
|
}
|
|
560
|
-
console.log(colors.cyan('\n如需重新安装,请先卸载:'));
|
|
561
|
-
console.log(` npm uninstall -g ${existing.name}`);
|
|
562
|
-
console.log(` rm -rf ~/.openclaw ~/.clawdbot`);
|
|
563
|
-
console.log('');
|
|
564
|
-
process.exit(0);
|
|
565
839
|
}
|
|
566
840
|
|
|
567
841
|
// 安装 CLI
|
|
@@ -584,57 +858,9 @@ async function main() {
|
|
|
584
858
|
log.info('跳过服务启动 (--skip-start)');
|
|
585
859
|
}
|
|
586
860
|
|
|
587
|
-
// 检测是否在 VPS
|
|
861
|
+
// 检测是否在 VPS 上并显示完成信息
|
|
588
862
|
const isVPS = detectVPS();
|
|
589
|
-
|
|
590
|
-
// 完成
|
|
591
|
-
console.log(colors.bold(colors.green('\n========================================')));
|
|
592
|
-
console.log(colors.bold(colors.green('✅ OpenClaw 安装完成!')));
|
|
593
|
-
console.log(colors.bold(colors.green('========================================')));
|
|
594
|
-
|
|
595
|
-
console.log(colors.cyan('\n配置信息:'));
|
|
596
|
-
console.log(` 配置目录: ${colors.yellow(config.configDir)}`);
|
|
597
|
-
console.log(` Gateway 端口: ${colors.yellow(config.port)}`);
|
|
598
|
-
console.log(` Gateway Token: ${colors.yellow(config.token)}`);
|
|
599
|
-
|
|
600
|
-
// 根据环境显示不同的访问说明
|
|
601
|
-
if (isVPS) {
|
|
602
|
-
console.log(colors.cyan('\n📡 Dashboard 访问 (云服务器):'));
|
|
603
|
-
console.log(colors.gray(' Gateway 默认绑定 127.0.0.1,外部无法直接访问(安全设计)'));
|
|
604
|
-
console.log('');
|
|
605
|
-
console.log(colors.yellow(' 方式一:SSH 隧道(推荐,安全)'));
|
|
606
|
-
console.log(colors.gray(' 在本地电脑执行以下命令,保持终端窗口打开:'));
|
|
607
|
-
console.log(` ssh -N -L ${config.port}:127.0.0.1:${config.port} root@<服务器IP>`);
|
|
608
|
-
console.log(colors.gray(' 然后在本地浏览器访问:'));
|
|
609
|
-
console.log(` ${colors.green(`http://127.0.0.1:${config.port}/?token=${config.token}`)}`);
|
|
610
|
-
console.log('');
|
|
611
|
-
console.log(colors.yellow(' 方式二:直接暴露端口(不推荐,有安全风险)'));
|
|
612
|
-
console.log(colors.gray(' 1. 修改配置文件 ~/.openclaw/openclaw.json'));
|
|
613
|
-
console.log(colors.gray(' 将 "bind": "loopback" 改为 "bind": "all"'));
|
|
614
|
-
console.log(colors.gray(' 2. 在云服务器控制台开放端口 ' + config.port));
|
|
615
|
-
console.log(colors.gray(' - 腾讯云:安全组 → 入站规则 → 添加 TCP ' + config.port));
|
|
616
|
-
console.log(colors.gray(' - 阿里云:安全组 → 配置规则 → 添加 TCP ' + config.port));
|
|
617
|
-
console.log(colors.gray(' 3. 重启 Gateway:' + cliName + ' gateway restart'));
|
|
618
|
-
console.log(colors.gray(' 4. 访问:http://<服务器IP>:' + config.port + '/?token=...'));
|
|
619
|
-
} else {
|
|
620
|
-
console.log(colors.cyan('\nDashboard 访问:'));
|
|
621
|
-
console.log(` ${colors.yellow(`http://127.0.0.1:${config.port}/?token=${config.token}`)}`);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
console.log(colors.cyan('\n下一步 - 配置 AI 模型:'));
|
|
625
|
-
console.log(` ${colors.yellow('npx openclawapi@latest preset-claude')}`);
|
|
626
|
-
|
|
627
|
-
console.log(colors.cyan('\n常用命令:'));
|
|
628
|
-
console.log(` 查看状态: ${colors.yellow(`${cliName} status`)}`);
|
|
629
|
-
console.log(` 查看日志: ${colors.yellow(`${cliName} gateway logs`)}`);
|
|
630
|
-
console.log(` 重启服务: ${colors.yellow(`${cliName} gateway restart`)}`);
|
|
631
|
-
console.log(` 诊断问题: ${colors.yellow(`${cliName} doctor`)}`);
|
|
632
|
-
|
|
633
|
-
console.log(colors.cyan('\n配置聊天渠道:'));
|
|
634
|
-
console.log(` Discord: ${colors.yellow('npx openclawdc')}`);
|
|
635
|
-
console.log(` 飞书: ${colors.yellow('npx openclawfs')}`);
|
|
636
|
-
|
|
637
|
-
console.log('');
|
|
863
|
+
showCompletionInfo(cliName, config, isVPS);
|
|
638
864
|
}
|
|
639
865
|
|
|
640
866
|
main().catch((e) => {
|