evolclaw 2.5.1 → 2.5.3

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.
@@ -172,7 +172,7 @@ export class AUNChannel {
172
172
  }
173
173
  if (!gateway) {
174
174
  logger.error('[AUN] Cannot resolve gateway URL from AID');
175
- return;
175
+ throw new Error('Cannot resolve gateway URL from AID');
176
176
  }
177
177
  logger.info(`[AUN] Initializing: aid=${aidName}, gateway=${gateway}, aun_path=${aunPath}`);
178
178
  // Create client with FileSecretStore (AES-256-GCM)
@@ -252,7 +252,7 @@ export class AUNChannel {
252
252
  if (!accessToken) {
253
253
  logger.error(`[AUN] No accessToken fallback available, scheduling retry`);
254
254
  this.scheduleReconnect();
255
- return;
255
+ throw new Error('Authentication failed and no accessToken fallback available');
256
256
  }
257
257
  logger.warn(`[AUN] Using accessToken fallback`);
258
258
  }
@@ -282,7 +282,7 @@ export class AUNChannel {
282
282
  catch (e) {
283
283
  logger.error(`[AUN] Connection failed: ${e}`);
284
284
  this.scheduleReconnect();
285
- return;
285
+ throw e;
286
286
  }
287
287
  }
288
288
  async sendWelcomeMessage() {
@@ -1026,6 +1026,7 @@ export class AUNChannelPlugin {
1026
1026
  accessToken: inst.accessToken,
1027
1027
  flushDelay: inst.flushDelay,
1028
1028
  encryptionSeed: inst.encryptionSeed,
1029
+ owner: inst.owner,
1029
1030
  aunTrace: config.debug?.aunTrace,
1030
1031
  });
1031
1032
  const adapter = {
@@ -11,7 +11,7 @@ import path from 'path';
11
11
  import os from 'os';
12
12
  import crypto from 'crypto';
13
13
  import { createRequire } from 'module';
14
- import { execFile } from 'child_process';
14
+ import { execFile, execFileSync } from 'child_process';
15
15
  import { promisify } from 'util';
16
16
  import { resolvePaths } from '../paths.js';
17
17
  import { normalizeChannelInstances } from '../config.js';
@@ -19,8 +19,9 @@ import { selectInstance } from './init.js';
19
19
  import { isWindows } from './cross-platform.js';
20
20
  const execFileAsync = promisify(execFile);
21
21
  export async function npmInstallGlobal(pkg) {
22
+ const npmCmd = isWindows ? 'npm.cmd' : 'npm';
22
23
  try {
23
- await execFileAsync('npm', ['install', '-g', pkg], { timeout: 180000 });
24
+ await execFileAsync(npmCmd, ['install', '-g', pkg], { timeout: 180000 });
24
25
  }
25
26
  catch (e) {
26
27
  if (e.stderr?.includes('EACCES') || e.message?.includes('EACCES')) {
@@ -576,6 +577,7 @@ function compareVersion(a, min) {
576
577
  return parts[2] >= min[2];
577
578
  }
578
579
  export function resolveAunCoreSdkPkg() {
580
+ // Strategy 1: createRequire (works when evolclaw and SDK share the same node_modules)
579
581
  try {
580
582
  const esmRequire = createRequire(import.meta.url);
581
583
  const entry = esmRequire.resolve(AUN_CORE_SDK_PKG);
@@ -592,14 +594,25 @@ export function resolveAunCoreSdkPkg() {
592
594
  }
593
595
  dir = path.dirname(dir);
594
596
  }
595
- return null;
596
597
  }
597
- const data = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
598
- return { version: data.version, path: pkgPath };
598
+ else {
599
+ const data = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
600
+ return { version: data.version, path: pkgPath };
601
+ }
599
602
  }
600
- catch {
601
- return null;
603
+ catch { /* fall through to strategy 2 */ }
604
+ // Strategy 2: npm root -g fallback (handles Windows / path mismatch)
605
+ try {
606
+ 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');
609
+ if (fs.existsSync(pkgPath)) {
610
+ const data = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
611
+ return { version: data.version, path: pkgPath };
612
+ }
602
613
  }
614
+ catch { /* not found */ }
615
+ return null;
603
616
  }
604
617
  export async function checkAunEnvironment(rl) {
605
618
  console.log('\n🔍 AUN 环境检查...\n');
@@ -699,6 +712,23 @@ export async function setupAunAid(rl, _config) {
699
712
  client._gatewayUrl = `wss://gateway.${domain}:${port}/aun`;
700
713
  const result = await client.auth.createAid({ aid });
701
714
  console.log(` ✓ AID ${result.aid} 创建成功`);
715
+ // 下载 CA 根证书(如果本地不存在)
716
+ const caDir = path.join(aunPath, 'CA', 'root');
717
+ const caCertPath = path.join(caDir, 'root.crt');
718
+ if (!fs.existsSync(caCertPath)) {
719
+ try {
720
+ 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`);
723
+ if (resp.ok) {
724
+ fs.writeFileSync(caCertPath, await resp.text());
725
+ console.log(' ✓ CA 根证书已下载');
726
+ }
727
+ }
728
+ catch (e) {
729
+ console.warn(` ⚠ CA 根证书下载失败: ${e},可稍后手动下载`);
730
+ }
731
+ }
702
732
  // Collect agent.md info and publish
703
733
  const typeInput = (await ask(rl, ' Agent 类型 human/ai [ai]: ')).trim().toLowerCase();
704
734
  const agentType = typeInput === 'human' ? 'human' : 'ai';
@@ -401,6 +401,9 @@ export async function cmdInit(options) {
401
401
  fs.mkdirSync(defaultPath, { recursive: true });
402
402
  config.projects.defaultPath = defaultPath;
403
403
  config.projects.list = { [path.basename(defaultPath)]: defaultPath };
404
+ if (options.channel === 'aun' && !options.aunAid) {
405
+ throw new Error('--aun-aid is required for AUN channel (e.g. --aun-aid mybot.agentid.pub)');
406
+ }
404
407
  if (options.channel === 'aun' && options.aunAid) {
405
408
  // 自动安装 AUN SDK
406
409
  const { resolveAunCoreSdkPkg, npmInstallGlobal } = await import('./init-channel.js');
@@ -417,6 +420,22 @@ export async function cmdInit(options) {
417
420
  const domain = options.aunAid.split('.').slice(1).join('.');
418
421
  client._gatewayUrl = `wss://gateway.${domain}:443/aun`;
419
422
  await client.auth.createAid({ aid: options.aunAid });
423
+ // 下载 CA 根证书(如果本地不存在)
424
+ const caDir = path.join(aunPath, 'CA', 'root');
425
+ const caCertPath = path.join(caDir, 'root.crt');
426
+ if (!fs.existsSync(caCertPath)) {
427
+ try {
428
+ fs.mkdirSync(caDir, { recursive: true });
429
+ const resp = await fetch(`https://gateway.${domain}/pki/chain`);
430
+ if (resp.ok) {
431
+ fs.writeFileSync(caCertPath, await resp.text());
432
+ console.log('✓ CA 根证书已下载');
433
+ }
434
+ }
435
+ catch (e) {
436
+ console.warn(`⚠ CA 根证书下载失败: ${e},可稍后手动下载`);
437
+ }
438
+ }
420
439
  // 写入初始 agent.md(initialized: false)
421
440
  const agentName = options.aunAid.split('.')[0];
422
441
  const agentMd = `---\naid: "${options.aunAid}"\nname: "${agentName}"\ntype: "ai"\nversion: "1.0.0"\ndescription: ""\ntags:\n - evolclaw\ninitialized: false\n---\n`;
@@ -0,0 +1,148 @@
1
+ # EvolClaw AUN 通道安装指南
2
+
3
+ EvolClaw 是一个开源的 AI Agent 网关,将 Claude/Codex 等 AI 后端连接到 AUN(AgentUnion.Network)消息通道。
4
+
5
+ - **npm**: https://www.npmjs.com/package/evolclaw
6
+ - **GitHub**: https://github.com/eLeanwang/evolclaw
7
+ - **AUN**: https://agentunion.network
8
+
9
+ ---
10
+
11
+ ## 前置条件
12
+
13
+ - Node.js >= 18,npm >= 8
14
+ - 一个 AUN Agent ID(AID)——标识你的 Agent
15
+ - 一个 Owner AID——接收欢迎消息和管理权限
16
+
17
+ ---
18
+
19
+ ## 安装步骤
20
+
21
+ ### 步骤 1:检查环境
22
+
23
+ ```bash
24
+ node --version # 需要 >= 18
25
+ npm --version # 需要 >= 8
26
+ ```
27
+
28
+ 版本不满足请先升级:https://nodejs.org
29
+
30
+ ### 步骤 2:安装 EvolClaw
31
+
32
+ ```bash
33
+ npm install -g evolclaw
34
+ evolclaw --version
35
+ ```
36
+
37
+ 遇到权限错误(EACCES):
38
+
39
+ ```bash
40
+ # 方案 A
41
+ sudo npm install -g evolclaw
42
+
43
+ # 方案 B(推荐,无需 sudo)
44
+ npm config set prefix ~/.npm-global
45
+ export PATH=~/.npm-global/bin:$PATH
46
+ npm install -g evolclaw
47
+ ```
48
+
49
+ ### 步骤 3:准备配置信息
50
+
51
+ | 参数 | 说明 | 示例 |
52
+ |------|------|------|
53
+ | `--aun-aid` | **必填**,你的 AUN Agent ID | `mybot.agentid.pub` |
54
+ | `--aun-owner` | **必填**,Owner 的 AUN ID | `alice.agentid.pub` |
55
+ | `--default-path` | 默认项目路径(可选,默认当前目录) | `/home/user/myproject` |
56
+
57
+ 如果用户在触发安装时已提供 Owner AID(例如消息中包含"将 xxx 添加为 Owner ID"),直接使用该值,否则询问用户。
58
+
59
+ ### 步骤 4:非交互式初始化
60
+
61
+ ```bash
62
+ evolclaw init --non-interactive \
63
+ --default-path "$PWD" \
64
+ --channel aun \
65
+ --aun-aid <AID> \
66
+ --aun-owner <Owner AID>
67
+ ```
68
+
69
+ 此命令自动完成:
70
+ 1. 创建配置文件 `~/.evolclaw/data/evolclaw.json`
71
+ 2. 安装 `@eleans/aun-core-sdk`
72
+ 3. 创建 AID 密钥对(如本地不存在)
73
+ 4. 下载 CA 根证书到 `~/.aun/CA/root/root.crt`
74
+ 5. 写入初始 `agent.md`(`initialized: false`)
75
+ 6. 写入配置(含 owner 字段)
76
+
77
+ ### 步骤 5:启动前验证
78
+
79
+ 读取配置文件确认关键字段:
80
+
81
+ ```bash
82
+ cat ~/.evolclaw/data/evolclaw.json
83
+ ```
84
+
85
+ 检查:
86
+ - `channels.aun.aid` — 你的 AID
87
+ - `channels.aun.owner` — Owner AID
88
+ - `projects.defaultPath` — 项目路径(目录需存在)
89
+ - `channels.defaultChannel` — 应为 `"aun"`
90
+
91
+ 如发现缺失或异常,向用户说明并提供修复方案。
92
+
93
+ ### 步骤 6:启动服务
94
+
95
+ ```bash
96
+ evolclaw start
97
+ ```
98
+
99
+ ### 步骤 7:验证运行状态
100
+
101
+ ```bash
102
+ evolclaw status
103
+ tail -n 30 ~/.evolclaw/logs/evolclaw.log
104
+ ```
105
+
106
+ 日志中应出现:`[AUN] Connected as @<aid>`
107
+
108
+ 如未出现或有错误,读取完整日志分析原因并提供修复建议。
109
+
110
+ ---
111
+
112
+ ## 首次连接自动行为
113
+
114
+ EvolClaw 首次连接 AUN 网络时自动:
115
+
116
+ 1. 检测 `~/.aun/AIDs/<aid>/agent.md` 中的 `initialized` 字段
117
+ 2. 若为 `false`,生成完整 agent.md 并发布到 AUN 网络
118
+ 3. 向 Owner 发送欢迎消息
119
+
120
+ 无需手动触发,连接成功后自动完成。
121
+
122
+ ---
123
+
124
+ ## 安装完成
125
+
126
+ ```
127
+ ✅ EvolClaw 安装完成!
128
+
129
+ 服务已启动并连接到 AUN 网络。
130
+ 首次连接后你将在 AUN 客户端收到欢迎消息。
131
+ 使用 /bind <项目路径> 绑定工作目录即可开始。
132
+ ```
133
+
134
+ ---
135
+
136
+ ## 常见问题
137
+
138
+ **Q: AID 已存在怎么办?**
139
+ `evolclaw init --non-interactive` 会检测本地密钥,已存在则跳过创建。
140
+
141
+ **Q: 启动失败怎么办?**
142
+ 查看 `~/.evolclaw/logs/evolclaw.log` 或运行 `evolclaw diagnose`。
143
+
144
+ **Q: 如何重启/查看日志?**
145
+ ```bash
146
+ evolclaw restart
147
+ evolclaw logs
148
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evolclaw",
3
- "version": "2.5.1",
3
+ "version": "2.5.3",
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",
@@ -11,7 +11,7 @@
11
11
  "dist/",
12
12
  "!dist/experimental/",
13
13
  "data/evolclaw.sample.json",
14
- "evolclaw-install.md"
14
+ "evolclaw-install-aun.md"
15
15
  ],
16
16
  "scripts": {
17
17
  "dev": "tsx watch src/index.ts",
@@ -1,54 +0,0 @@
1
- 请引导我完成 EvolClaw 的安装和配置。EvolClaw 是一个轻量级 AI Agent 网关,连接 Claude/Codex 到飞书、微信等 IM 通道。
2
-
3
- **重要提示**:安装完成后,首次在 IM 渠道(飞书/微信)中与 EvolClaw 交互的用户将自动成为 owner,拥有完整管理权限。
4
-
5
- 按以下步骤执行:
6
-
7
- ## 第 1 步:环境检查
8
-
9
- 运行 `node --version` 和 `npm --version`,确认 Node.js >= 18、npm >= 8。
10
- 如果不符合要求,提示用户先升级 Node.js(https://nodejs.org)后停止。
11
-
12
- ## 第 2 步:确认安装
13
-
14
- 使用 AskUserQuestion 询问:
15
- - 问题:是否立即安装 EvolClaw?
16
- - 选项 A:立即安装
17
- - 选项 B:仅显示命令,我稍后手动执行
18
-
19
- 如果选择 B,输出 `npm install -g evolclaw` 后结束。
20
-
21
- ## 第 3 步:执行安装
22
-
23
- 运行 `npm install -g evolclaw`,然后 `evolclaw --version` 验证。
24
-
25
- 如果失败且是权限问题,提示:
26
- ```
27
- sudo npm install -g evolclaw
28
- # 或配置 npm prefix(推荐):
29
- npm config set prefix ~/.npm-global && export PATH=~/.npm-global/bin:$PATH
30
- npm install -g evolclaw
31
- ```
32
-
33
- ## 第 4 步:初始化配置
34
-
35
- 运行 `evolclaw init`。
36
-
37
- 提示用户:EvolClaw 自动继承 Claude Code CLI 的 API Key,无需重复配置。
38
-
39
- ## 第 5 步:配置消息渠道
40
-
41
- 使用 AskUserQuestion(multiSelect: true)询问需要配置哪些渠道:
42
- - 飞书:运行 `evolclaw init feishu`(扫码登录)
43
- - 微信:运行 `evolclaw init wechat`(扫码登录)
44
- - 暂不配置:跳过
45
-
46
- ## 第 6 步:启动并验证
47
-
48
- 运行 `evolclaw start`,再运行 `evolclaw status` 确认状态为 Running。
49
-
50
- 安装完成后告知用户:
51
- - 在飞书/微信中发消息验证连接
52
- - 发送 `/help` 查看所有命令
53
- - 发送 `/bind <项目路径>` 绑定项目目录
54
- - 常用命令:`evolclaw stop/restart/logs`