evolclaw 3.1.4 → 3.1.5

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.
Files changed (85) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/agents/claude-runner.js +348 -156
  3. package/dist/agents/kit-renderer.js +176 -21
  4. package/dist/aun/aid/agentmd.js +68 -103
  5. package/dist/aun/aid/client.js +1 -29
  6. package/dist/aun/aid/identity.js +105 -64
  7. package/dist/aun/aid/index.js +2 -1
  8. package/dist/aun/aid/store.js +74 -0
  9. package/dist/aun/msg/p2p.js +26 -2
  10. package/dist/aun/rpc/connection.js +23 -30
  11. package/dist/channels/aun.js +77 -88
  12. package/dist/channels/dingtalk.js +1 -0
  13. package/dist/channels/feishu.js +270 -190
  14. package/dist/channels/qqbot.js +1 -0
  15. package/dist/channels/wechat.js +1 -0
  16. package/dist/channels/wecom.js +1 -0
  17. package/dist/cli/agent.js +11 -5
  18. package/dist/cli/bench.js +40 -23
  19. package/dist/cli/index.js +170 -44
  20. package/dist/cli/init-channel.js +5 -1
  21. package/dist/cli/model.js +324 -0
  22. package/dist/cli/net-check.js +133 -50
  23. package/dist/cli/watch-msg.js +7 -7
  24. package/dist/cli/watch-web/debug-log.js +18 -0
  25. package/dist/cli/watch-web/server.js +306 -0
  26. package/dist/cli/watch-web/sources/aid.js +63 -0
  27. package/dist/cli/watch-web/sources/msg.js +70 -0
  28. package/dist/cli/watch-web/sources/session.js +638 -0
  29. package/dist/cli/watch-web/sources/types.js +10 -0
  30. package/dist/cli/watch-web/static/app.js +546 -0
  31. package/dist/cli/watch-web/static/index.html +54 -0
  32. package/dist/cli/watch-web/static/style.css +247 -0
  33. package/dist/core/channel-loader.js +7 -4
  34. package/dist/core/command-handler.js +81 -86
  35. package/dist/core/evolagent-registry.js +1 -1
  36. package/dist/core/evolagent.js +4 -4
  37. package/dist/core/interaction-router.js +59 -0
  38. package/dist/core/message/message-bridge.js +6 -6
  39. package/dist/core/message/message-log.js +2 -2
  40. package/dist/core/message/message-processor.js +86 -101
  41. package/dist/core/message/stream-idle-monitor.js +21 -0
  42. package/dist/core/model/model-catalog.js +215 -0
  43. package/dist/core/model/model-scope.js +250 -0
  44. package/dist/core/relation/peer-identity.js +40 -49
  45. package/dist/core/relation/peer-key.js +16 -0
  46. package/dist/core/session/session-fs-store.js +34 -55
  47. package/dist/core/session/session-key.js +24 -0
  48. package/dist/core/session/session-manager.js +308 -251
  49. package/dist/core/session/session-mapper.js +9 -4
  50. package/dist/core/trigger/manager.js +3 -3
  51. package/dist/core/trigger/scheduler.js +2 -1
  52. package/dist/index.js +6 -2
  53. package/dist/ipc.js +22 -0
  54. package/kits/docs/GUIDE.md +2 -2
  55. package/kits/docs/INDEX.md +11 -7
  56. package/kits/docs/channels/aun.md +56 -17
  57. package/kits/docs/channels/feishu.md +41 -12
  58. package/kits/docs/context-assembly.md +181 -0
  59. package/kits/docs/evolclaw/agent.md +49 -0
  60. package/kits/docs/evolclaw/aid.md +49 -0
  61. package/kits/docs/evolclaw/ctl.md +46 -0
  62. package/kits/docs/evolclaw/group.md +82 -0
  63. package/kits/docs/evolclaw/msg.md +86 -0
  64. package/kits/docs/evolclaw/rpc.md +35 -0
  65. package/kits/docs/evolclaw/storage.md +49 -0
  66. package/kits/docs/venues/aun-group.md +10 -0
  67. package/kits/docs/venues/aun-private.md +10 -0
  68. package/kits/docs/venues/client-desktop.md +10 -0
  69. package/kits/docs/venues/client-mobile.md +10 -0
  70. package/kits/docs/venues/feishu-group.md +13 -0
  71. package/kits/docs/venues/feishu-private.md +9 -0
  72. package/kits/docs/venues/group.md +11 -0
  73. package/kits/docs/venues/private.md +10 -0
  74. package/kits/eck_manifest.json +72 -36
  75. package/kits/rules/01-overview.md +20 -10
  76. package/kits/rules/06-channel.md +30 -27
  77. package/kits/templates/system-fragments/session.md +10 -3
  78. package/kits/templates/system-fragments/venue.md +9 -0
  79. package/package.json +11 -6
  80. package/dist/aun/aid/lifecycle-log.js +0 -33
  81. package/dist/utils/aid-lifecycle-log.js +0 -33
  82. package/kits/docs/evolclaw/AGENT_CMD.md +0 -31
  83. package/kits/docs/evolclaw/MSG_GROUP.md +0 -30
  84. package/kits/docs/evolclaw/MSG_PRIVATE.md +0 -72
  85. package/kits/docs/evolclaw/tools.md +0 -25
@@ -1,7 +1,8 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import crypto from 'crypto';
4
- import { getAunClient, createAunClient, downloadCaRoot } from './client.js';
4
+ import { getAidStore, loadAid, loadClient, AidLoadError, SLOT } from './store.js';
5
+ import { downloadCaRoot } from './client.js';
5
6
  import { resolvePaths, agentMdPath, aunPath as defaultAunPath } from '../../paths.js';
6
7
  // ==================== Validation ====================
7
8
  export function isValidAid(name) {
@@ -94,41 +95,39 @@ export function aidList(aunPath) {
94
95
  */
95
96
  export async function verifySignAbility(aid, opts) {
96
97
  const aunPath = opts?.aunPath ?? defaultAunPath();
97
- let ownClient = null;
98
+ let ownStore = null;
98
99
  try {
99
- let client = opts?.client;
100
- if (!client) {
101
- client = await createAunClient({ aunPath });
102
- ownClient = client;
100
+ let store = opts?.store;
101
+ if (!store) {
102
+ store = await getAidStore({ slotId: SLOT.cli, aunPath });
103
+ ownStore = store;
103
104
  }
104
- const probe = `# probe\naid: "${aid}"\n`;
105
- let signed;
105
+ // 加载本地 AID 值对象(含私钥),sign + verify 全本地完成
106
+ let aidObj;
106
107
  try {
107
- signed = await client.auth.signAgentMd(probe, { aid });
108
+ aidObj = loadAid(store, aid);
108
109
  }
109
110
  catch (e) {
110
- return { ok: false, reason: `sign failed: ${String(e?.message || e).slice(0, 120)}` };
111
+ const code = e instanceof AidLoadError ? e.code : 'LOAD_FAILED';
112
+ return { ok: false, reason: `load failed: ${code} ${String(e?.message || e).slice(0, 100)}` };
111
113
  }
112
- const certPath = path.join(aunPath, 'AIDs', aid, 'public', 'cert.pem');
113
- const certPem = fs.existsSync(certPath) ? fs.readFileSync(certPath, 'utf-8') : '';
114
- if (!certPem)
115
- return { ok: false, reason: 'cert.pem missing' };
116
- let result;
117
- try {
118
- result = await client.auth.verifyAgentMd(signed, { aid, certPem });
114
+ const probe = `# probe\naid: "${aid}"\n`;
115
+ const signRes = aidObj.signAgentMd(probe);
116
+ if (!signRes.ok) {
117
+ return { ok: false, reason: `sign failed: ${String(signRes.error?.message || signRes.error?.code).slice(0, 120)}` };
119
118
  }
120
- catch (e) {
121
- return { ok: false, reason: `verify threw: ${String(e?.message || e).slice(0, 120)}` };
119
+ const verifyRes = aidObj.verifyAgentMd(signRes.data.signed);
120
+ if (!verifyRes.ok) {
121
+ return { ok: false, reason: `verify threw: ${String(verifyRes.error?.message || verifyRes.error?.code).slice(0, 120)}` };
122
122
  }
123
- const verified = result?.status === 'verified' || result?.verified === true;
124
- if (verified)
123
+ if (verifyRes.data.status === 'verified')
125
124
  return { ok: true };
126
- return { ok: false, reason: `verify failed: ${result?.status ?? 'unknown'}${result?.reason ? ' — ' + result.reason : ''}` };
125
+ return { ok: false, reason: `verify failed: ${verifyRes.data.status ?? 'unknown'}${verifyRes.data.reason ? ' — ' + verifyRes.data.reason : ''}` };
127
126
  }
128
127
  finally {
129
- if (ownClient) {
128
+ if (ownStore) {
130
129
  try {
131
- await ownClient.close();
130
+ ownStore.close();
132
131
  }
133
132
  catch { /* ignore */ }
134
133
  }
@@ -141,7 +140,7 @@ export async function verifySignAbility(aid, opts) {
141
140
  export async function aidListVerified(aunPath) {
142
141
  const list = aidList(aunPath);
143
142
  const root = aunPath ?? defaultAunPath();
144
- const client = await createAunClient({ aunPath: root });
143
+ const store = await getAidStore({ slotId: SLOT.cli, aunPath: root });
145
144
  try {
146
145
  for (const a of list) {
147
146
  // canSign=false 的 AID 不必跑实测,结论已经明确
@@ -161,7 +160,7 @@ export async function aidListVerified(aunPath) {
161
160
  });
162
161
  continue;
163
162
  }
164
- const r = await verifySignAbility(a.aid, { aunPath: root, client });
163
+ const r = await verifySignAbility(a.aid, { aunPath: root, store });
165
164
  a.signVerified = r.ok;
166
165
  if (!r.ok)
167
166
  a.signError = r.reason;
@@ -173,7 +172,7 @@ export async function aidListVerified(aunPath) {
173
172
  }
174
173
  finally {
175
174
  try {
176
- await client.close();
175
+ store.close();
177
176
  }
178
177
  catch { /* ignore */ }
179
178
  }
@@ -182,43 +181,79 @@ export async function aidListVerified(aunPath) {
182
181
  export async function aidCreate(aid, opts) {
183
182
  const aunPath = opts?.aunPath ?? defaultAunPath();
184
183
  const aidDir = path.join(aunPath, 'AIDs', aid);
185
- if (fs.existsSync(aidDir) && fs.existsSync(path.join(aidDir, 'private'))) {
186
- const client = await getAunClient(aid, { aunPath });
187
- return { aid, alreadyExisted: true, gateway: '', client };
188
- }
189
- const { GatewayDiscovery } = await import('@agentunion/fastaun');
190
- let client = await createAunClient({ aunPath });
191
- try {
192
- const result = await client.auth.createAid({ aid });
193
- const gateway = result.gateway || '';
194
- const caDownloaded = await downloadCaRoot(aunPath, gateway);
195
- const caCertPath = path.join(aunPath, 'CA', 'root', 'root.crt');
196
- if (caDownloaded && fs.existsSync(caCertPath)) {
184
+ const hasPrivateKey = fs.existsSync(path.join(aidDir, 'private'));
185
+ // 如果私钥已存在,先验证签名能力
186
+ if (hasPrivateKey) {
187
+ const verifyResult = await verifySignAbility(aid, { aunPath });
188
+ if (verifyResult.ok) {
189
+ // 身份有效:加载并认证,返回已认证的 client
190
+ const store = await getAidStore({ slotId: SLOT.cli, aunPath });
197
191
  try {
198
- await client.close();
192
+ const client = await loadClient(store, aid);
193
+ const auth = await client.authenticate();
194
+ return { aid, alreadyExisted: true, gateway: String(auth?.gateway ?? ''), client, store };
199
195
  }
200
- catch { /* ignore */ }
201
- client = await createAunClient({ aunPath });
202
- await client.auth.createAid({ aid });
203
- }
204
- let gatewayUrl = gateway;
205
- if (!gatewayUrl) {
206
- try {
207
- const discovery = new GatewayDiscovery({});
208
- gatewayUrl = await discovery.discover(`https://${aid}/.well-known/aun-gateway`);
196
+ catch (e) {
197
+ store.close();
198
+ throw e;
209
199
  }
210
- catch { /* fall through */ }
211
200
  }
212
- if (gatewayUrl) {
213
- client._gatewayUrl = gatewayUrl;
201
+ // 签名验证失败
202
+ if (!opts?.force) {
203
+ const error = new Error(`AID ${aid} 已存在但身份无效(${verifyResult.reason || '签名验证失败'})。\n` +
204
+ `使用 --force 参数尝试恢复或重新注册。`);
205
+ error.code = 'AID_INVALID';
206
+ error.reason = verifyResult.reason;
207
+ throw error;
208
+ }
209
+ // --force:先尝试 authenticate 恢复证书
210
+ const recoverStore = await getAidStore({ slotId: SLOT.cli, aunPath });
211
+ try {
212
+ const recoverClient = await loadClient(recoverStore, aid);
213
+ const auth = await recoverClient.authenticate();
214
+ return { aid, alreadyExisted: true, gateway: String(auth?.gateway ?? ''), client: recoverClient, store: recoverStore };
215
+ }
216
+ catch {
217
+ recoverStore.close();
218
+ fs.rmSync(aidDir, { recursive: true, force: true });
214
219
  }
215
- return { aid, alreadyExisted: false, gateway: gatewayUrl, client };
216
220
  }
217
- catch (e) {
221
+ // 新注册流程:AIDStore.register → downloadCaRoot → load → authenticate
222
+ const store = await getAidStore({ slotId: SLOT.cli, aunPath });
223
+ try {
224
+ const regResult = await store.register(aid);
225
+ if (!regResult.ok) {
226
+ const e = new Error(regResult.error.message);
227
+ e.code = regResult.error.code;
228
+ throw e;
229
+ }
230
+ // 注册成功后下载 CA 根证书(如果还没有)
231
+ // 从 AID well-known 发现 gateway 用于 CA 下载
232
+ let gatewayUrl = '';
218
233
  try {
219
- await client.close();
234
+ const { GatewayDiscovery } = await import('@agentunion/fastaun');
235
+ const discovery = new GatewayDiscovery({});
236
+ gatewayUrl = await discovery.discover(`https://${aid}/.well-known/aun-gateway`);
220
237
  }
221
- catch { /* ignore */ }
238
+ catch { /* fall through */ }
239
+ if (gatewayUrl) {
240
+ await downloadCaRoot(aunPath, gatewayUrl);
241
+ }
242
+ // 重建 store(CA 可能刚下载,需要 rootCaPath 生效)
243
+ store.close();
244
+ const store2 = await getAidStore({ slotId: SLOT.cli, aunPath });
245
+ try {
246
+ const client = await loadClient(store2, aid);
247
+ await client.authenticate();
248
+ return { aid, alreadyExisted: false, gateway: gatewayUrl, client, store: store2 };
249
+ }
250
+ catch (e) {
251
+ store2.close();
252
+ throw e;
253
+ }
254
+ }
255
+ catch (e) {
256
+ store.close();
222
257
  throw e;
223
258
  }
224
259
  }
@@ -263,11 +298,11 @@ export async function aidShow(aid, opts) {
263
298
  let agentMdSignatureReason;
264
299
  let signVerified = null;
265
300
  let signError;
266
- // 先做一次签名自检(共享 client,避免重复起 SDK)
267
- const client = await createAunClient({ aunPath });
301
+ // 先做一次签名自检(共享 store,避免重复起 SDK)
302
+ const store = await getAidStore({ slotId: SLOT.cli, aunPath });
268
303
  try {
269
304
  if (hasPrivateKey && certPem && !certExpired && keyMatchesCert !== false) {
270
- const r = await verifySignAbility(aid, { aunPath, client });
305
+ const r = await verifySignAbility(aid, { aunPath, store });
271
306
  signVerified = r.ok;
272
307
  if (!r.ok)
273
308
  signError = r.reason;
@@ -290,16 +325,22 @@ export async function aidShow(aid, opts) {
290
325
  agentMdSignature = 'unsigned';
291
326
  }
292
327
  else {
293
- const result = await client.auth.verifyAgentMd(content, { aid, ...(certPem ? { certPem } : {}) });
294
- if (result.status === 'verified' || result.verified) {
328
+ // 用本地 AID 值对象验签(含本地 cert 公钥)
329
+ const aidObj = loadAid(store, aid);
330
+ const result = aidObj.verifyAgentMd(content);
331
+ if (!result.ok) {
332
+ agentMdSignature = 'unknown';
333
+ agentMdSignatureReason = String(result.error?.message || result.error?.code).slice(0, 100);
334
+ }
335
+ else if (result.data.status === 'verified') {
295
336
  agentMdSignature = 'verified';
296
337
  }
297
- else if (result.status === 'unsigned') {
338
+ else if (result.data.status === 'unsigned') {
298
339
  agentMdSignature = 'unsigned';
299
340
  }
300
341
  else {
301
342
  agentMdSignature = 'invalid';
302
- agentMdSignatureReason = result.reason;
343
+ agentMdSignatureReason = result.data.reason;
303
344
  }
304
345
  }
305
346
  }
@@ -311,7 +352,7 @@ export async function aidShow(aid, opts) {
311
352
  }
312
353
  finally {
313
354
  try {
314
- await client.close();
355
+ store.close();
315
356
  }
316
357
  catch { }
317
358
  }
@@ -1,3 +1,4 @@
1
1
  export { isValidAid, aidList, aidListVerified, aidCreate, aidShow, aidDelete, aidLookup, verifySignAbility, probePkiRecoverability, appendAidLifecycle, readAidLifecycle } from './identity.js';
2
2
  export { buildInitialAgentMd, agentmdGet, agentmdPut, agentmdSync } from './agentmd.js';
3
- export { MIN_AUN_CORE_SDK, AUN_CORE_SDK_PKG, isAunSdkVersionOk, resolveAunCoreSdkPkg, ensureAunSdk, isAunSdkReady, downloadCaRoot, getAunClient, suppressSdkLogs, } from './client.js';
3
+ export { MIN_AUN_CORE_SDK, AUN_CORE_SDK_PKG, isAunSdkVersionOk, resolveAunCoreSdkPkg, ensureAunSdk, isAunSdkReady, downloadCaRoot, suppressSdkLogs, } from './client.js';
4
+ export { getAidStore, loadClient, loadAid, AidLoadError, SLOT } from './store.js';
@@ -0,0 +1,74 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ /**
4
+ * Slot 命名约定(基于 fastaun 0.4.3 隔离键语义)。
5
+ *
6
+ * slotIsolationKey 取第一个分隔符(空格/'/'/':')之前的部分作为隔离键,
7
+ * 隔离键相同 = 共享消费通道(token / seq 游标 / 消息过滤)。
8
+ *
9
+ * 'evolclaw daemon' → 隔离键 'evolclaw' ┐
10
+ * 'evolclaw cli' → 隔离键 'evolclaw' ├ 共享 evolclaw 消费通道
11
+ * 'evolclaw netcheck' → 隔离键 'evolclaw' ┘
12
+ * 'evolclaw-bench' → 隔离键 'evolclaw-bench'(连字符非分隔符)→ 独立通道
13
+ *
14
+ * 设计意图:
15
+ * - daemon 长连接 + cli 短连接共存于 evolclaw 通道(1 长 + N 短,短连接不踢长连接)
16
+ * - netcheck 长连接抢 evolclaw 长连接位 → 踢掉 daemon(用于踢人/extra_info 测试)
17
+ * - bench 各并发单元用 evolclaw-bench-<N>,各自独立隔离键,互不干扰
18
+ */
19
+ export const SLOT = {
20
+ daemon: 'evolclaw daemon',
21
+ cli: 'evolclaw cli',
22
+ bench: 'evolclaw-bench',
23
+ netcheck: 'evolclaw netcheck',
24
+ };
25
+ /** 加载身份失败时抛出,携带 SDK 的错误码与消息。 */
26
+ export class AidLoadError extends Error {
27
+ code;
28
+ constructor(code, message) {
29
+ super(message);
30
+ this.name = 'AidLoadError';
31
+ this.code = code;
32
+ }
33
+ }
34
+ /**
35
+ * 统一构造 AIDStore。
36
+ *
37
+ * 接管旧 createAunClient 的职责:注入 encryptionSeed、rootCaPath、debug、slotId。
38
+ * deviceId 不传 —— 由 SDK 从 {aunPath}/.device_id 读取或生成(同机共享)。
39
+ */
40
+ export async function getAidStore(opts) {
41
+ const { aunPath: defaultAunPath } = await import('../../paths.js');
42
+ const { loadProcessConfig } = await import('../../config-store.js');
43
+ const { AIDStore } = await import('@agentunion/fastaun');
44
+ const aunPath = opts.aunPath ?? defaultAunPath();
45
+ const encryptionSeed = loadProcessConfig().aun?.encryptionSeed
46
+ ?? process.env.AUN_ENCRYPTION_SEED
47
+ ?? 'evol';
48
+ const caCertPath = path.join(aunPath, 'CA', 'root', 'root.crt');
49
+ const storeOpts = {
50
+ aunPath,
51
+ encryptionSeed,
52
+ slotId: opts.slotId,
53
+ debug: opts.debug ?? false,
54
+ };
55
+ if (fs.existsSync(caCertPath))
56
+ storeOpts.rootCaPath = caCertPath;
57
+ return new AIDStore(storeOpts);
58
+ }
59
+ /**
60
+ * 从 store 加载本地身份并构造已就绪的 AUNClient(尚未连接)。
61
+ *
62
+ * load 失败(证书缺失/过期/链断裂/私钥不匹配等)抛 AidLoadError,携带 SDK 错误码。
63
+ */
64
+ export async function loadClient(store, aid) {
65
+ const { AUNClient } = await import('@agentunion/fastaun');
66
+ return new AUNClient(loadAid(store, aid));
67
+ }
68
+ /** 加载本地 AID 值对象(用于离线签名/验签,无需连接)。load 失败抛 AidLoadError。 */
69
+ export function loadAid(store, aid) {
70
+ const r = store.load(aid);
71
+ if (!r.ok)
72
+ throw new AidLoadError(r.error.code, r.error.message);
73
+ return r.data.aid;
74
+ }
@@ -1,5 +1,6 @@
1
1
  import path from 'path';
2
2
  import { createShortConnection } from '../rpc/index.js';
3
+ import { getAidStore, SLOT } from '../aid/store.js';
3
4
  import { uploadFileAndBuildPayload } from './upload.js';
4
5
  import { appendMessageLog, buildOutboundEntry } from '../../core/message/message-log.js';
5
6
  import { chatDirPath } from '../../core/session/session-fs-store.js';
@@ -7,11 +8,21 @@ import { resolvePaths } from '../../paths.js';
7
8
  export async function msgSend(args) {
8
9
  const conn = await createShortConnection(args.from, { aunPath: args.aunPath, slotId: args.slotId });
9
10
  try {
10
- // 1. 解析对端身份(30天缓存)
11
+ // 1. 解析对端身份(30天缓存)。身份解析走 HTTP+PKI(store),与发消息的短连接无关。
11
12
  const { agentsDir } = resolvePaths();
12
13
  const selfAgentDir = path.join(agentsDir, args.from);
13
14
  const { PeerIdentityCache } = await import('../../core/relation/peer-identity.js');
14
- const peerIdentity = await PeerIdentityCache.resolve('aun', args.to, selfAgentDir, conn, false);
15
+ const idStore = await getAidStore({ slotId: args.slotId ?? SLOT.cli, aunPath: args.aunPath });
16
+ let peerIdentity;
17
+ try {
18
+ peerIdentity = await PeerIdentityCache.resolve('aun', args.to, selfAgentDir, idStore, false);
19
+ }
20
+ finally {
21
+ try {
22
+ idStore.close();
23
+ }
24
+ catch { /* ignore */ }
25
+ }
15
26
  // 2. 决定 chatmode(遵循来源1-3)
16
27
  // 私聊:非 human 对端 → proactive,human 对端 → interactive
17
28
  const chatmode = peerIdentity.isAgent ? 'proactive' : 'interactive';
@@ -81,6 +92,19 @@ export async function msgSend(args) {
81
92
  msgType: 'text',
82
93
  source,
83
94
  }));
95
+ // 通知 daemon 更新 stats(如果 daemon 在运行)
96
+ try {
97
+ const { ipcQuery } = await import('../../ipc.js');
98
+ await ipcQuery(resolvePaths().socket, {
99
+ type: 'aun-aid-stats-record-outbound',
100
+ aid: args.from,
101
+ toPeer: args.to,
102
+ text: textContent,
103
+ encrypt: args.encrypt === true,
104
+ chatmode,
105
+ }, 1000);
106
+ }
107
+ catch { /* daemon 不在或 IPC 失败都忽略 */ }
84
108
  }
85
109
  catch { }
86
110
  }
@@ -1,32 +1,25 @@
1
- import { aunPath as defaultAunPath } from '../../paths.js';
2
- import { createAunClient } from '../aid/client.js';
3
- import { loadProcessConfig } from '../../config-store.js';
1
+ import { getAidStore, loadClient, SLOT } from '../aid/store.js';
4
2
  export async function createShortConnection(aid, opts) {
5
- const aunPath = opts?.aunPath ?? defaultAunPath();
6
- const slotId = opts?.slotId ?? '';
7
- const encryptionSeed = loadProcessConfig().aun?.encryptionSeed
8
- || process.env.AUN_ENCRYPTION_SEED
9
- || 'evol';
10
- const client = await createAunClient({ aunPath, encryptionSeed });
11
- await client.auth.createAid({ aid });
12
- const authResult = await client.auth.authenticate({ aid });
13
- const accessToken = authResult?.access_token ?? client._access_token;
14
- const gateway = client._gatewayUrl ?? authResult?.gateway;
15
- await client.connect({
16
- access_token: accessToken,
17
- gateway,
18
- slot_id: slotId,
19
- connection_kind: 'short',
20
- }, { auto_reconnect: false });
21
- return {
22
- async call(method, params) {
23
- return client.call(method, params);
24
- },
25
- async close() {
26
- try {
27
- await client.close();
28
- }
29
- catch { /* ignore */ }
30
- },
31
- };
3
+ const store = await getAidStore({ slotId: opts?.slotId ?? SLOT.cli, aunPath: opts?.aunPath });
4
+ try {
5
+ const client = await loadClient(store, aid);
6
+ await client.connect({ connection_kind: 'short', short_ttl_ms: 30000, auto_reconnect: false });
7
+ return {
8
+ async call(method, params) {
9
+ return client.call(method, params);
10
+ },
11
+ async close() {
12
+ try {
13
+ await client.close();
14
+ }
15
+ finally {
16
+ store.close();
17
+ }
18
+ },
19
+ };
20
+ }
21
+ catch (e) {
22
+ store.close();
23
+ throw e;
24
+ }
32
25
  }