@lingyao037/openclaw-lingyao-cli 0.9.2 → 0.9.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/cli.mjs +97 -7
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -80,6 +80,7 @@ class LingyaoInstaller {
|
|
|
80
80
|
this.channelId = 'lingyao';
|
|
81
81
|
this.gatewayId = null;
|
|
82
82
|
this.gatewayToken = null;
|
|
83
|
+
this.openclawCommand = null;
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
setOpenClawPath(path) {
|
|
@@ -111,7 +112,7 @@ class LingyaoInstaller {
|
|
|
111
112
|
try {
|
|
112
113
|
const result = spawnSync(command, args, {
|
|
113
114
|
stdio: 'inherit',
|
|
114
|
-
shell:
|
|
115
|
+
shell: false,
|
|
115
116
|
...options
|
|
116
117
|
});
|
|
117
118
|
return {
|
|
@@ -171,14 +172,39 @@ class LingyaoInstaller {
|
|
|
171
172
|
return [];
|
|
172
173
|
}
|
|
173
174
|
|
|
175
|
+
isNpxEphemeralOpenClawPath(commandPath) {
|
|
176
|
+
if (!commandPath || typeof commandPath !== 'string') return false;
|
|
177
|
+
const normalized = commandPath.replace(/\\/g, '/');
|
|
178
|
+
return normalized.includes('/.npm/_npx/') && normalized.includes('/node_modules/.bin/openclaw');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
resolveOpenClawCommandPath() {
|
|
182
|
+
const commandPaths = this.getCommandPathCandidates();
|
|
183
|
+
if (commandPaths.length === 0) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const nonEphemeral = commandPaths.filter((path) => !this.isNpxEphemeralOpenClawPath(path));
|
|
188
|
+
if (nonEphemeral.length > 0) {
|
|
189
|
+
return nonEphemeral[0];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return commandPaths[0];
|
|
193
|
+
}
|
|
194
|
+
|
|
174
195
|
// 检查 OpenClaw 是否安装
|
|
175
196
|
checkOpenClaw() {
|
|
176
197
|
this.log('\n═══════════════════════════════════════════════════', CYAN);
|
|
177
198
|
this.log(' 灵爻 (Lingyao) Plugin 安装器', CYAN);
|
|
178
199
|
this.log('═══════════════════════════════════════════════════\n', CYAN);
|
|
179
200
|
|
|
201
|
+
this.openclawCommand = this.resolveOpenClawCommandPath() || 'openclaw';
|
|
202
|
+
if (this.openclawCommand !== 'openclaw') {
|
|
203
|
+
this.info(`使用 openclaw 命令: ${this.openclawCommand}`);
|
|
204
|
+
}
|
|
205
|
+
|
|
180
206
|
// 检查 OpenClaw 命令
|
|
181
|
-
const result = this.exec(
|
|
207
|
+
const result = this.exec(this.openclawCommand, ['--version'], { stdio: 'pipe' });
|
|
182
208
|
|
|
183
209
|
if (result.success) {
|
|
184
210
|
this.success('OpenClaw 已安装');
|
|
@@ -391,7 +417,11 @@ class LingyaoInstaller {
|
|
|
391
417
|
restartGateway() {
|
|
392
418
|
this.log('\n正在重启 OpenClaw Gateway...\n');
|
|
393
419
|
|
|
394
|
-
const
|
|
420
|
+
const command = this.openclawCommand || this.resolveOpenClawCommandPath() || 'openclaw';
|
|
421
|
+
if (command !== 'openclaw') {
|
|
422
|
+
this.info(`重启时使用命令: ${command}`);
|
|
423
|
+
}
|
|
424
|
+
const result = this.exec(command, ['gateway', 'restart']);
|
|
395
425
|
|
|
396
426
|
if (result.success) {
|
|
397
427
|
this.success('Gateway 重启成功');
|
|
@@ -448,7 +478,52 @@ class LingyaoInstaller {
|
|
|
448
478
|
}
|
|
449
479
|
|
|
450
480
|
// HTTP helpers
|
|
481
|
+
hasProxyEnv() {
|
|
482
|
+
return Boolean(
|
|
483
|
+
process.env.HTTPS_PROXY ||
|
|
484
|
+
process.env.https_proxy ||
|
|
485
|
+
process.env.HTTP_PROXY ||
|
|
486
|
+
process.env.http_proxy ||
|
|
487
|
+
process.env.ALL_PROXY ||
|
|
488
|
+
process.env.all_proxy
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
curlJson(method, path, body = null) {
|
|
493
|
+
return new Promise((resolve, reject) => {
|
|
494
|
+
const url = `${LINGYAO_API}${path}`;
|
|
495
|
+
const args = ['-sS', '-X', method, url, '-H', 'Content-Type: application/json'];
|
|
496
|
+
if (this.gatewayToken) {
|
|
497
|
+
args.push('-H', `Authorization: Bearer ${this.gatewayToken}`);
|
|
498
|
+
}
|
|
499
|
+
if (body !== null) {
|
|
500
|
+
args.push('-d', JSON.stringify(body));
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
const child = spawn('curl', args, { stdio: ['ignore', 'pipe', 'pipe'], shell: false });
|
|
504
|
+
let stdout = '';
|
|
505
|
+
let stderr = '';
|
|
506
|
+
child.stdout.on('data', (chunk) => { stdout += chunk.toString(); });
|
|
507
|
+
child.stderr.on('data', (chunk) => { stderr += chunk.toString(); });
|
|
508
|
+
child.on('error', (error) => reject(error));
|
|
509
|
+
child.on('close', (code) => {
|
|
510
|
+
if (code !== 0) {
|
|
511
|
+
reject(new Error(stderr.trim() || `curl exited with code ${code}`));
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
try {
|
|
515
|
+
resolve(JSON.parse(stdout));
|
|
516
|
+
} catch {
|
|
517
|
+
reject(new Error(`Invalid JSON: ${stdout}`));
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
|
|
451
523
|
httpsPost(path, body) {
|
|
524
|
+
if (this.hasProxyEnv()) {
|
|
525
|
+
return this.curlJson('POST', path, body);
|
|
526
|
+
}
|
|
452
527
|
return new Promise((resolve, reject) => {
|
|
453
528
|
const data = JSON.stringify(body);
|
|
454
529
|
const url = `${LINGYAO_API}${path}`;
|
|
@@ -456,7 +531,7 @@ class LingyaoInstaller {
|
|
|
456
531
|
if (this.gatewayToken) {
|
|
457
532
|
headers['Authorization'] = `Bearer ${this.gatewayToken}`;
|
|
458
533
|
}
|
|
459
|
-
const req = https.request(url, { method: 'POST', headers }, (res) => {
|
|
534
|
+
const req = https.request(url, { method: 'POST', headers, timeout: 10000 }, (res) => {
|
|
460
535
|
let chunk = '';
|
|
461
536
|
res.on('data', (c) => chunk += c);
|
|
462
537
|
res.on('end', () => {
|
|
@@ -464,6 +539,9 @@ class LingyaoInstaller {
|
|
|
464
539
|
catch { reject(new Error(`Invalid JSON: ${chunk}`)); }
|
|
465
540
|
});
|
|
466
541
|
});
|
|
542
|
+
req.on('timeout', () => {
|
|
543
|
+
req.destroy(new Error('Request timeout while connecting to lingyao.live'));
|
|
544
|
+
});
|
|
467
545
|
req.on('error', reject);
|
|
468
546
|
req.write(data);
|
|
469
547
|
req.end();
|
|
@@ -471,16 +549,23 @@ class LingyaoInstaller {
|
|
|
471
549
|
}
|
|
472
550
|
|
|
473
551
|
httpsGet(path) {
|
|
552
|
+
if (this.hasProxyEnv()) {
|
|
553
|
+
return this.curlJson('GET', path, null);
|
|
554
|
+
}
|
|
474
555
|
return new Promise((resolve, reject) => {
|
|
475
556
|
const url = `${LINGYAO_API}${path}`;
|
|
476
|
-
https.get(url, (res) => {
|
|
557
|
+
const req = https.get(url, { timeout: 10000 }, (res) => {
|
|
477
558
|
let chunk = '';
|
|
478
559
|
res.on('data', (c) => chunk += c);
|
|
479
560
|
res.on('end', () => {
|
|
480
561
|
try { resolve(JSON.parse(chunk)); }
|
|
481
562
|
catch { reject(new Error(`Invalid JSON: ${chunk}`)); }
|
|
482
563
|
});
|
|
483
|
-
})
|
|
564
|
+
});
|
|
565
|
+
req.on('timeout', () => {
|
|
566
|
+
req.destroy(new Error('Request timeout while connecting to lingyao.live'));
|
|
567
|
+
});
|
|
568
|
+
req.on('error', reject);
|
|
484
569
|
});
|
|
485
570
|
}
|
|
486
571
|
|
|
@@ -585,6 +670,10 @@ class LingyaoInstaller {
|
|
|
585
670
|
|
|
586
671
|
} catch (error) {
|
|
587
672
|
this.error(`配对失败: ${error.message}`);
|
|
673
|
+
this.warn('网络诊断建议:');
|
|
674
|
+
this.log(' 1) curl -I https://api.lingyao.live/lyoc/health');
|
|
675
|
+
this.log(' 2) nslookup api.lingyao.live');
|
|
676
|
+
this.log(' 3) 如在公司网络/代理环境,请检查 TLS 拦截或防火墙策略');
|
|
588
677
|
return false;
|
|
589
678
|
}
|
|
590
679
|
}
|
|
@@ -720,7 +809,8 @@ class LingyaoInstaller {
|
|
|
720
809
|
|
|
721
810
|
// 重启网关
|
|
722
811
|
this.log('\n重启 OpenClaw Gateway...');
|
|
723
|
-
this.
|
|
812
|
+
const command = this.openclawCommand || this.resolveOpenClawCommandPath() || 'openclaw';
|
|
813
|
+
this.exec(command, ['gateway', 'restart']);
|
|
724
814
|
|
|
725
815
|
this.success('\n✓ 卸载完成!\n');
|
|
726
816
|
return true;
|
package/package.json
CHANGED