@voko/lite 0.3.1

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 (62) hide show
  1. package/package.json +32 -0
  2. package/scripts/build-native.js +72 -0
  3. package/src/bankHeadOffices.js +20543 -0
  4. package/src/channels/email.js +35 -0
  5. package/src/channels/feishu.js +31 -0
  6. package/src/channels/qq-email.js +30 -0
  7. package/src/channels/registry.js +279 -0
  8. package/src/channels/telegram.js +28 -0
  9. package/src/channels/voko-email.js +7 -0
  10. package/src/channels/wechat.js +35 -0
  11. package/src/cli.js +120 -0
  12. package/src/context.js +164 -0
  13. package/src/core/access-control-api.js +150 -0
  14. package/src/core/access-control.js +56 -0
  15. package/src/core/agent-registration.js +319 -0
  16. package/src/core/api-signature.js +33 -0
  17. package/src/core/audit.js +133 -0
  18. package/src/core/database.js +1409 -0
  19. package/src/core/did-auth.js +54 -0
  20. package/src/core/hermes-paths.js +57 -0
  21. package/src/core/invitation.js +49 -0
  22. package/src/core/lite-bus.js +16 -0
  23. package/src/core/llm-client.js +1032 -0
  24. package/src/core/messenger.js +456 -0
  25. package/src/core/notifier.js +99 -0
  26. package/src/core/offline-sync.js +150 -0
  27. package/src/core/payment.js +285 -0
  28. package/src/core/publish-agent.js +166 -0
  29. package/src/core/register-capabilities.js +119 -0
  30. package/src/core/search-capabilities.js +136 -0
  31. package/src/core/send-message.js +85 -0
  32. package/src/core/set-agent-status.js +65 -0
  33. package/src/core/update-agent-profile.js +102 -0
  34. package/src/core/worker-manager.js +332 -0
  35. package/src/endpoints.json +21 -0
  36. package/src/index.js +712 -0
  37. package/src/mcp/CLAUDE_TEST.md +82 -0
  38. package/src/mcp/FULL_TEST.md +139 -0
  39. package/src/mcp/TEST.md +124 -0
  40. package/src/mcp/TEST_STEPS.md +75 -0
  41. package/src/mcp/server.js +612 -0
  42. package/src/mcp/tools.js +1367 -0
  43. package/src/mcp/transport/http.js +95 -0
  44. package/src/mcp/transport/stdio.js +20 -0
  45. package/src/preload.js +27 -0
  46. package/src/server/agent-email-api.js +120 -0
  47. package/src/server/agent-manager.js +580 -0
  48. package/src/server/email-handler.js +329 -0
  49. package/src/server/feishu-handler.js +249 -0
  50. package/src/server/hermes-api-client.js +166 -0
  51. package/src/server/hermes-discovery.js +80 -0
  52. package/src/server/hermes-handler.js +287 -0
  53. package/src/server/openclaw-handler-cli.js +131 -0
  54. package/src/server/openclaw-websocket-handler.js +1290 -0
  55. package/src/server/oss.js +186 -0
  56. package/src/server/owner-intervention-notifier.js +320 -0
  57. package/src/server/release-page.html +204 -0
  58. package/src/server/telegram-handler.js +208 -0
  59. package/src/server/voko-email-handler.js +68 -0
  60. package/src/server/wechat-handler.js +439 -0
  61. package/src/workers/agent-worker.js +378 -0
  62. package/src/workers/message-content.js +51 -0
@@ -0,0 +1,54 @@
1
+ /**
2
+ * DID 认证通用工具
3
+ *
4
+ * 提供 Ed25519 私钥提取和 DID 请求签名,供主进程 IPC、MCP 工具等共享。
5
+ */
6
+
7
+ const { signAsync } = require('@noble/ed25519');
8
+
9
+ // 将 PEM / base64 / hex 格式 Ed25519 私钥解析为 raw 32 字节
10
+ function extractEd25519PrivateKey(pem) {
11
+ const cleaned = pem
12
+ .replace(/-----BEGIN [\w\s]+ KEY-----/g, '')
13
+ .replace(/-----END [\w\s]+ KEY-----/g, '')
14
+ .replace(/\s/g, '');
15
+ const bytes = Buffer.from(cleaned, 'base64');
16
+
17
+ // 如果刚好 32 字节,直接使用
18
+ if (bytes.length === 32) return new Uint8Array(bytes);
19
+
20
+ // 如果末尾有 32 字节(PKCS#8 DER),取末尾 32 字节
21
+ if (bytes.length > 32) {
22
+ const slice = bytes.slice(-32);
23
+ if (slice.length === 32) return new Uint8Array(slice);
24
+ }
25
+
26
+ // 兜底:尝试 hex 解码
27
+ if (cleaned.length === 64 && /^[0-9a-f]+$/i.test(cleaned)) {
28
+ return new Uint8Array(Buffer.from(cleaned, 'hex'));
29
+ }
30
+
31
+ console.warn('[extractEd25519PrivateKey] unexpected key length:', bytes.length, 'trying first 32 bytes');
32
+ return new Uint8Array(bytes.slice(0, 32));
33
+ }
34
+
35
+ /**
36
+ * DID 请求签名工具函数
37
+ * @param {string} did - Agent DID(did:wba:...)
38
+ * @param {string} privateKey - PEM 格式 Ed25519 私钥
39
+ * @param {object} businessFields - 除 did/nonce/timestamp/signature 外的业务字段
40
+ * @returns {object} { did, nonce, timestamp, signature }
41
+ */
42
+ async function signDidRequest(did, privateKey, businessFields) {
43
+ const nonce = Math.random().toString(36).substring(2, 15) + Date.now().toString(36);
44
+ const timestamp = Math.floor(Date.now() / 1000);
45
+ const sortedKeys = Object.keys(businessFields).sort();
46
+ const bodyPayload = JSON.stringify(businessFields, sortedKeys);
47
+ const toSign = did + '\n' + nonce + '\n' + timestamp + '\n' + bodyPayload;
48
+ const rawKey = extractEd25519PrivateKey(privateKey);
49
+ const sigBytes = await signAsync(new TextEncoder().encode(toSign), rawKey);
50
+ const signature = Buffer.from(sigBytes).toString('base64');
51
+ return { did, nonce, timestamp, signature };
52
+ }
53
+
54
+ module.exports = { extractEd25519PrivateKey, signDidRequest };
@@ -0,0 +1,57 @@
1
+ const fs = require('fs');
2
+ const os = require('os');
3
+ const path = require('path');
4
+
5
+ /**
6
+ * Hermes 根目录候选路径(按优先级)
7
+ * Windows: %LOCALAPPDATA%\hermes(默认安装) → ~/.hermes
8
+ * 其他平台: ~/.hermes
9
+ */
10
+ function getHermesDirCandidates() {
11
+ const candidates = [];
12
+ if (process.platform === 'win32') {
13
+ const localAppData = process.env.LOCALAPPDATA;
14
+ if (localAppData) candidates.push(path.join(localAppData, 'hermes'));
15
+ }
16
+ candidates.push(path.join(os.homedir(), '.hermes'));
17
+ return candidates;
18
+ }
19
+
20
+ /** 返回第一个存在的 Hermes 根目录,均不存在则 null */
21
+ function findHermesDir() {
22
+ for (const dir of getHermesDirCandidates()) {
23
+ if (fs.existsSync(dir)) return dir;
24
+ }
25
+ return null;
26
+ }
27
+
28
+ /** Hermes 根目录:优先用已存在的,否则用默认候选(写入场景) */
29
+ function getHermesDir() {
30
+ return findHermesDir() || getHermesDirCandidates()[0];
31
+ }
32
+
33
+ function getHermesProfilesDir() {
34
+ return path.join(getHermesDir(), 'profiles');
35
+ }
36
+
37
+ function getHermesProfilePath(profileName, ...segments) {
38
+ return path.join(getHermesProfilesDir(), profileName, ...segments);
39
+ }
40
+
41
+ function getHermesEnvPath() {
42
+ return path.join(getHermesDir(), '.env');
43
+ }
44
+
45
+ function getHermesConfigPath() {
46
+ return path.join(getHermesDir(), 'config.yaml');
47
+ }
48
+
49
+ module.exports = {
50
+ getHermesDirCandidates,
51
+ findHermesDir,
52
+ getHermesDir,
53
+ getHermesProfilesDir,
54
+ getHermesProfilePath,
55
+ getHermesEnvPath,
56
+ getHermesConfigPath,
57
+ };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 邀请好友 — 提示词构建器
3
+ * 一处修改,多处生效
4
+ */
5
+
6
+ /**
7
+ * 生成邀请提示词(好友将这段文案发给自己的 Agent 即可)
8
+ * @param {Object} opts
9
+ * @param {string} opts.myName — 邀请者 Agent 名称
10
+ * @param {string} opts.ownerEmail — 邀请者邮箱
11
+ * @param {string} opts.version — VOKO 版本号
12
+ * @param {string} opts.guideUrl — 使用指南 URL
13
+ * @param {string} opts.downloadUrl — 下载链接
14
+ * @param {string} opts.friendEmail — 好友邮箱(用于搜索 Agent)
15
+ * @param {string} opts.inviteCode — 6 位邀请码
16
+ * @returns {string}
17
+ */
18
+ function buildInvitationPrompt({ myName, ownerEmail, version, guideUrl, downloadUrl, friendEmail, inviteCode }) {
19
+ return `**邀请者:** ${myName}(${ownerEmail})
20
+ **VOKO 版本:** ${version}
21
+ **系统自动处理:** 好友发来的消息包含对应邀请码时,**自动通过并加入白名单**,无需人工处理。
22
+
23
+ ### 好友操作步骤
24
+ 1. 📖 阅读指南:${guideUrl}
25
+ 2. ⬇️ 下载安装:${downloadUrl}
26
+ 3. 🔧 注册配置 Agent
27
+ 4. 🔍 搜索你的 Agent(邮箱:${friendEmail})
28
+ 5. 💬 发送消息格式:\`好友申请,「邀请码:${inviteCode}」\``;
29
+ }
30
+
31
+ /**
32
+ * 生成邮件标题
33
+ * @param {string} myName — 邀请方 Agent 名称
34
+ * @returns {string}
35
+ */
36
+ function buildEmailSubject(myName) {
37
+ return `你的好友 ${myName} 邀请你使用 VOKO智能体IM通信软件`;
38
+ }
39
+
40
+ /**
41
+ * 生成邮件内容(主题 + 提示词)
42
+ * @param {Object} opts
43
+ * @returns {string}
44
+ */
45
+ function buildEmailContent(opts) {
46
+ return `主题:${buildEmailSubject(opts.myName || '')}\n\n${buildInvitationPrompt(opts)}`;
47
+ }
48
+
49
+ module.exports = { buildInvitationPrompt, buildEmailSubject, buildEmailContent };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * lite-bus.js — 事件总线
3
+ *
4
+ * 替代 mainWindow.webContents.send(),解耦业务逻辑与 Electron UI。
5
+ * 业务代码 emit 事件 → Desktop 订阅并转发给渲染进程。
6
+ * Lite 模式下无订阅者,事件静默丢弃。
7
+ *
8
+ * 用法:
9
+ * const bus = require('./lite-bus');
10
+ * bus.emit('agent-wukongim:message', { ... });
11
+ */
12
+
13
+ const EventEmitter = require('events');
14
+ const bus = new EventEmitter();
15
+ bus.setMaxListeners(100);
16
+ module.exports = bus;