evolclaw 2.5.3 → 2.5.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.
@@ -10,7 +10,7 @@ import readline from 'readline';
10
10
  import path from 'path';
11
11
  import os from 'os';
12
12
  import crypto from 'crypto';
13
- import { createRequire } from 'module';
13
+ import { fileURLToPath } from 'url';
14
14
  import { execFile, execFileSync } from 'child_process';
15
15
  import { promisify } from 'util';
16
16
  import { resolvePaths } from '../paths.js';
@@ -20,8 +20,9 @@ import { isWindows } from './cross-platform.js';
20
20
  const execFileAsync = promisify(execFile);
21
21
  export async function npmInstallGlobal(pkg) {
22
22
  const npmCmd = isWindows ? 'npm.cmd' : 'npm';
23
+ const execOpts = { timeout: 180000, shell: isWindows };
23
24
  try {
24
- await execFileAsync(npmCmd, ['install', '-g', pkg], { timeout: 180000 });
25
+ await execFileAsync(npmCmd, ['install', '-g', pkg], execOpts);
25
26
  }
26
27
  catch (e) {
27
28
  if (e.stderr?.includes('EACCES') || e.message?.includes('EACCES')) {
@@ -577,35 +578,31 @@ function compareVersion(a, min) {
577
578
  return parts[2] >= min[2];
578
579
  }
579
580
  export function resolveAunCoreSdkPkg() {
580
- // Strategy 1: createRequire (works when evolclaw and SDK share the same node_modules)
581
+ const pkgName = AUN_CORE_SDK_PKG;
582
+ // Strategy 1: walk up node_modules from this file (no require.resolve — avoids ESM exports issues)
581
583
  try {
582
- const esmRequire = createRequire(import.meta.url);
583
- const entry = esmRequire.resolve(AUN_CORE_SDK_PKG);
584
- const pkgPath = path.join(path.dirname(entry), 'package.json');
585
- if (!fs.existsSync(pkgPath)) {
586
- // 向上回溯查找 package.json
587
- let dir = path.dirname(entry);
588
- for (let i = 0; i < 5; i++) {
589
- const candidate = path.join(dir, 'package.json');
590
- if (fs.existsSync(candidate)) {
591
- const data = JSON.parse(fs.readFileSync(candidate, 'utf-8'));
592
- if (data.name === AUN_CORE_SDK_PKG)
593
- return { version: data.version, path: candidate };
594
- }
595
- dir = path.dirname(dir);
584
+ let dir = path.dirname(fileURLToPath(import.meta.url));
585
+ while (true) {
586
+ const candidate = path.join(dir, 'node_modules', pkgName, 'package.json');
587
+ if (fs.existsSync(candidate)) {
588
+ const data = JSON.parse(fs.readFileSync(candidate, 'utf-8'));
589
+ if (data.name === pkgName)
590
+ return { version: data.version, path: candidate };
596
591
  }
597
- }
598
- else {
599
- const data = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
600
- return { version: data.version, path: pkgPath };
592
+ const parent = path.dirname(dir);
593
+ if (parent === dir)
594
+ break;
595
+ dir = parent;
601
596
  }
602
597
  }
603
- catch { /* fall through to strategy 2 */ }
604
- // Strategy 2: npm root -g fallback (handles Windows / path mismatch)
598
+ catch { /* fall through */ }
599
+ // Strategy 2: npm root -g fallback (globally installed SDK)
605
600
  try {
606
601
  const npmCmd = isWindows ? 'npm.cmd' : 'npm';
607
- const globalRoot = execFileSync(npmCmd, ['root', '-g'], { encoding: 'utf-8', timeout: 10000 }).trim();
608
- const pkgPath = path.join(globalRoot, AUN_CORE_SDK_PKG, 'package.json');
602
+ const globalRoot = execFileSync(npmCmd, ['root', '-g'], {
603
+ encoding: 'utf-8', timeout: 10000, shell: isWindows,
604
+ }).trim();
605
+ const pkgPath = path.join(globalRoot, pkgName, 'package.json');
609
606
  if (fs.existsSync(pkgPath)) {
610
607
  const data = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
611
608
  return { version: data.version, path: pkgPath };
@@ -706,23 +703,30 @@ export async function setupAunAid(rl, _config) {
706
703
  try {
707
704
  const { AUNClient } = await import('@eleans/aun-core-sdk');
708
705
  const client = new AUNClient({ aun_path: aunPath });
709
- // Set gateway URL from AID domain + port
710
- const domain = aid.split('.').slice(1).join('.');
711
- const port = gatewayPort || 443;
712
- client._gatewayUrl = `wss://gateway.${domain}:${port}/aun`;
706
+ // 如果用户指定了自定义端口,手动设置 gateway URL;否则让 SDK 自动发现
707
+ if (gatewayPort) {
708
+ const domain = aid.split('.').slice(1).join('.');
709
+ client._gatewayUrl = `wss://gateway.${domain}:${gatewayPort}/aun`;
710
+ }
713
711
  const result = await client.auth.createAid({ aid });
714
712
  console.log(` ✓ AID ${result.aid} 创建成功`);
715
- // 下载 CA 根证书(如果本地不存在)
713
+ // 下载 CA 根证书(如果本地不存在),从 SDK 返回的实际网关 URL 派生
716
714
  const caDir = path.join(aunPath, 'CA', 'root');
717
715
  const caCertPath = path.join(caDir, 'root.crt');
718
- if (!fs.existsSync(caCertPath)) {
716
+ if (!fs.existsSync(caCertPath) && result.gateway) {
719
717
  try {
720
718
  fs.mkdirSync(caDir, { recursive: true });
721
- // Derive HTTPS URL from gateway WebSocket URL (same as SDK's _gatewayHttpUrl)
722
- const resp = await fetch(`https://gateway.${domain}:${port}/pki/chain`);
719
+ const gwHttp = result.gateway.replace(/^wss?:/, 'https:').replace(/\/aun$/, '');
720
+ const resp = await fetch(`${gwHttp}/pki/chain`, { redirect: 'follow' });
723
721
  if (resp.ok) {
724
- fs.writeFileSync(caCertPath, await resp.text());
725
- console.log(' CA 根证书已下载');
722
+ const body = await resp.text();
723
+ if (body.includes('BEGIN CERTIFICATE')) {
724
+ fs.writeFileSync(caCertPath, body);
725
+ console.log(' ✓ CA 根证书已下载');
726
+ }
727
+ else {
728
+ console.warn(' ⚠ CA 根证书响应内容无效,跳过写入');
729
+ }
726
730
  }
727
731
  }
728
732
  catch (e) {
@@ -417,19 +417,25 @@ export async function cmdInit(options) {
417
417
  if (!fs.existsSync(path.join(aidDir, 'private'))) {
418
418
  const { AUNClient } = await import('@eleans/aun-core-sdk');
419
419
  const client = new AUNClient({ aun_path: aunPath });
420
- const domain = options.aunAid.split('.').slice(1).join('.');
421
- client._gatewayUrl = `wss://gateway.${domain}:443/aun`;
422
- await client.auth.createAid({ aid: options.aunAid });
423
- // 下载 CA 根证书(如果本地不存在)
420
+ // SDK 通过 well-known 自动发现网关
421
+ const result = await client.auth.createAid({ aid: options.aunAid });
422
+ // 下载 CA 根证书(如果本地不存在),从 SDK 返回的实际网关 URL 派生
424
423
  const caDir = path.join(aunPath, 'CA', 'root');
425
424
  const caCertPath = path.join(caDir, 'root.crt');
426
- if (!fs.existsSync(caCertPath)) {
425
+ if (!fs.existsSync(caCertPath) && result.gateway) {
427
426
  try {
428
427
  fs.mkdirSync(caDir, { recursive: true });
429
- const resp = await fetch(`https://gateway.${domain}/pki/chain`);
428
+ const gwHttp = result.gateway.replace(/^wss?:/, 'https:').replace(/\/aun$/, '');
429
+ const resp = await fetch(`${gwHttp}/pki/chain`, { redirect: 'follow' });
430
430
  if (resp.ok) {
431
- fs.writeFileSync(caCertPath, await resp.text());
432
- console.log(' CA 根证书已下载');
431
+ const body = await resp.text();
432
+ if (body.includes('BEGIN CERTIFICATE')) {
433
+ fs.writeFileSync(caCertPath, body);
434
+ console.log('✓ CA 根证书已下载');
435
+ }
436
+ else {
437
+ console.warn('⚠ CA 根证书响应内容无效,跳过写入');
438
+ }
433
439
  }
434
440
  }
435
441
  catch (e) {
@@ -50,11 +50,13 @@ npm install -g evolclaw
50
50
 
51
51
  | 参数 | 说明 | 示例 |
52
52
  |------|------|------|
53
- | `--aun-aid` | **必填**,你的 AUN Agent ID | `mybot.agentid.pub` |
54
- | `--aun-owner` | **必填**,Owner 的 AUN ID | `alice.agentid.pub` |
53
+ | `--aun-aid` | **必填**,Agent 自身的 AID,作为 bot 在 AUN 网络上的独立身份 | `mybot.agentid.pub` |
54
+ | `--aun-owner` | **必填**,Owner 的 AID,用于接收欢迎消息和管理权限 | `alice.agentid.pub` |
55
55
  | `--default-path` | 默认项目路径(可选,默认当前目录) | `/home/user/myproject` |
56
56
 
57
- 如果用户在触发安装时已提供 Owner AID(例如消息中包含"将 xxx 添加为 Owner ID"),直接使用该值,否则询问用户。
57
+ **注意**:`--aun-aid` `--aun-owner` 必须是不同的 AID。Agent 需要独立身份,不能与 Owner 相同。
58
+
59
+ 如果用户在触发安装时已提供 Owner AID(例如消息中包含"将 xxx 添加为 Owner ID"),直接使用该值,否则询问用户。Agent AID 必须单独询问用户,不能默认使用 Owner AID。
58
60
 
59
61
  ### 步骤 4:非交互式初始化
60
62
 
@@ -146,3 +148,13 @@ EvolClaw 首次连接 AUN 网络时自动:
146
148
  evolclaw restart
147
149
  evolclaw logs
148
150
  ```
151
+
152
+ **Q: Windows 上 npm install 报 spawn EINVAL?**
153
+ Node.js 24+ 的安全变更(CVE-2024-27980)导致此错误。升级到 evolclaw >= 2.5.4 即可解决。
154
+ 临时方案:先手动运行 `npm install -g @eleans/aun-core-sdk`,再执行 init。
155
+
156
+ **Q: 如何清理损坏的 AID 重新注册?**
157
+ ```bash
158
+ rm -rf ~/.aun/AIDs/<aid>
159
+ evolclaw init --non-interactive --channel aun --aun-aid <aid> --aun-owner <owner>
160
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evolclaw",
3
- "version": "2.5.3",
3
+ "version": "2.5.4",
4
4
  "description": "Lightweight AI Agent gateway connecting Claude Agent SDK to messaging channels (Feishu, ACP) with multi-project session management",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",