corivo 0.10.0-mvp
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/README.md +65 -0
- package/README.short.md +49 -0
- package/dist/cli/commands/doctor.d.ts +7 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +80 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/init.d.ts +10 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +111 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/query.d.ts +13 -0
- package/dist/cli/commands/query.d.ts.map +1 -0
- package/dist/cli/commands/query.js +105 -0
- package/dist/cli/commands/query.js.map +1 -0
- package/dist/cli/commands/recover.d.ts +7 -0
- package/dist/cli/commands/recover.d.ts.map +1 -0
- package/dist/cli/commands/recover.js +116 -0
- package/dist/cli/commands/recover.js.map +1 -0
- package/dist/cli/commands/save.d.ts +14 -0
- package/dist/cli/commands/save.d.ts.map +1 -0
- package/dist/cli/commands/save.js +62 -0
- package/dist/cli/commands/save.js.map +1 -0
- package/dist/cli/commands/start.d.ts +11 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +203 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +7 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +96 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +7 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +40 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +89 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/password.d.ts +15 -0
- package/dist/cli/utils/password.d.ts.map +1 -0
- package/dist/cli/utils/password.js +66 -0
- package/dist/cli/utils/password.js.map +1 -0
- package/dist/crypto/keys.d.ts +81 -0
- package/dist/crypto/keys.d.ts.map +1 -0
- package/dist/crypto/keys.js +415 -0
- package/dist/crypto/keys.js.map +1 -0
- package/dist/engine/heartbeat.d.ts +83 -0
- package/dist/engine/heartbeat.d.ts.map +1 -0
- package/dist/engine/heartbeat.js +394 -0
- package/dist/engine/heartbeat.js.map +1 -0
- package/dist/engine/rules/index.d.ts +48 -0
- package/dist/engine/rules/index.d.ts.map +1 -0
- package/dist/engine/rules/index.js +50 -0
- package/dist/engine/rules/index.js.map +1 -0
- package/dist/engine/rules/tech-choice.d.ts +42 -0
- package/dist/engine/rules/tech-choice.d.ts.map +1 -0
- package/dist/engine/rules/tech-choice.js +186 -0
- package/dist/engine/rules/tech-choice.js.map +1 -0
- package/dist/engine/rules.d.ts +6 -0
- package/dist/engine/rules.d.ts.map +1 -0
- package/dist/engine/rules.js +6 -0
- package/dist/engine/rules.js.map +1 -0
- package/dist/errors/index.d.ts +103 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +172 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/ingestors/claude-code.d.ts +22 -0
- package/dist/ingestors/claude-code.d.ts.map +1 -0
- package/dist/ingestors/claude-code.js +96 -0
- package/dist/ingestors/claude-code.js.map +1 -0
- package/dist/models/block.d.ts +138 -0
- package/dist/models/block.d.ts.map +1 -0
- package/dist/models/block.js +115 -0
- package/dist/models/block.js.map +1 -0
- package/dist/models/index.d.ts +6 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +6 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/pattern.d.ts +47 -0
- package/dist/models/pattern.d.ts.map +1 -0
- package/dist/models/pattern.js +31 -0
- package/dist/models/pattern.js.map +1 -0
- package/dist/push/context.d.ts +64 -0
- package/dist/push/context.d.ts.map +1 -0
- package/dist/push/context.js +146 -0
- package/dist/push/context.js.map +1 -0
- package/dist/storage/database.d.ts +249 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +676 -0
- package/dist/storage/database.js.map +1 -0
- package/eslint.config.js +24 -0
- package/package.json +45 -0
- package/tsconfig.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Corivo 设计文档
|
|
2
|
+
|
|
3
|
+
> Agent-first 收集无感,更新自动,用心推送。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 产品定位
|
|
8
|
+
|
|
9
|
+
> **Corivo 是一个为你服务、记录你点点滴滴、最懂你的赛博伙伴,你是它的全部。**
|
|
10
|
+
|
|
11
|
+
Corivo 是一个融入用户已有工作流的赛博**伙伴**。它不是一个独立的 App,而是寄生在 Claude Code、Cursor、飞书等工具中的后台服务——自动从用户的 AI 对话和消息中采集信息,持续整理和更新,在合适的时机以 `[corivo]` 的名义主动提醒用户。
|
|
12
|
+
|
|
13
|
+
用户不需要下载新软件、学习新界面、改变任何习惯。安装一个 CLI,跑一次 `corivo init`,记忆层就开始工作了。
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 版本
|
|
18
|
+
|
|
19
|
+
| 版本 | 状态 | 说明 |
|
|
20
|
+
| ----------------- | ----- | ----------------- |
|
|
21
|
+
| [v0.10](./v0.10/) | ✅ 当前 | 团队协作、混合模式提取、信任状态机 |
|
|
22
|
+
| [v0.5](./v0.5/) | 📜 历史 | 预测性 AI、工具调用 |
|
|
23
|
+
| [v0.2](./v0.2/) | 📜 历史 | 初始版本 |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## v0.10 概览
|
|
28
|
+
|
|
29
|
+
**21 篇设计文档**,涵盖:
|
|
30
|
+
|
|
31
|
+
- **核心设计**(01-14):Block 数据模型、生命周期、存储、接入、采集、心跳、推送、预测、Aha Moment、风险、工具调用、团队版、API、可视化
|
|
32
|
+
- **工程文档**(15-18):边界情况、测试、性能、安全
|
|
33
|
+
- **补充文档**(19-21):信任状态机、CRDT 实现、规则引擎贡献机制
|
|
34
|
+
|
|
35
|
+
### v0.10 新增
|
|
36
|
+
|
|
37
|
+
- **混合模式提取**:规则引擎 80% + LLM 20%,平衡成本与准确性
|
|
38
|
+
- **信任状态机**:4 级权限 × 4 种降级原因,完整恢复路径
|
|
39
|
+
- **团队协作**:命名空间、CRDT 同步(Yjs)、权限模型
|
|
40
|
+
- **密钥管理**:16 词恢复短语、设备授权/撤销
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 快速开始
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# 阅读 v0.10 设计文档
|
|
48
|
+
cd v0.10
|
|
49
|
+
open README.md
|
|
50
|
+
|
|
51
|
+
# 从核心设计开始
|
|
52
|
+
open 01-block.md # Block 数据模型
|
|
53
|
+
open 02-memory-lifecycle.md # 记忆生命周期
|
|
54
|
+
open 03-storage.md # 存储与同步
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 文档导航
|
|
60
|
+
|
|
61
|
+
[进入 v0.10 设计文档 →](./v0.10/README.md)
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
**最后更新**:2026-03-18
|
package/README.short.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Corivo
|
|
2
|
+
|
|
3
|
+
你的赛博伙伴 —— 记忆存储与智能推送
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g .
|
|
9
|
+
# 或
|
|
10
|
+
npm install
|
|
11
|
+
npx corivo --help
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 初始化
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
corivo init
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 使用
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# 保存信息
|
|
24
|
+
corivo save --content "选择使用 PostgreSQL" --annotation "决策 · project · corivo"
|
|
25
|
+
|
|
26
|
+
# 查询信息
|
|
27
|
+
corivo query "数据库"
|
|
28
|
+
|
|
29
|
+
# 查看状态
|
|
30
|
+
corivo status
|
|
31
|
+
|
|
32
|
+
# 启动心跳守护进程
|
|
33
|
+
corivo start
|
|
34
|
+
|
|
35
|
+
# 停止心跳
|
|
36
|
+
corivo stop
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 开发
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install
|
|
43
|
+
npm run build
|
|
44
|
+
npm test
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## License
|
|
48
|
+
|
|
49
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAyEnD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 命令 - doctor
|
|
3
|
+
*
|
|
4
|
+
* 健康检查
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { CorivoDatabase, getDefaultDatabasePath, getConfigDir } from '../../storage/database.js';
|
|
9
|
+
import { KeyManager } from '../../crypto/keys.js';
|
|
10
|
+
import { readPassword } from '../utils/password.js';
|
|
11
|
+
export async function doctorCommand() {
|
|
12
|
+
console.log('\n正在运行 Corivo 健康检查...\n');
|
|
13
|
+
const configDir = getConfigDir();
|
|
14
|
+
const configPath = path.join(configDir, 'config.json');
|
|
15
|
+
let config;
|
|
16
|
+
try {
|
|
17
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
18
|
+
config = JSON.parse(content);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
console.log('❌ 配置文件不存在');
|
|
22
|
+
console.log(' 请先运行: corivo init');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
console.log('✅ 配置文件正常');
|
|
26
|
+
// 检查数据库
|
|
27
|
+
const dbPath = getDefaultDatabasePath();
|
|
28
|
+
let dbExists = false;
|
|
29
|
+
try {
|
|
30
|
+
await fs.access(dbPath);
|
|
31
|
+
dbExists = true;
|
|
32
|
+
}
|
|
33
|
+
catch { }
|
|
34
|
+
if (dbExists) {
|
|
35
|
+
console.log('✅ 数据库文件存在');
|
|
36
|
+
// 尝试打开数据库
|
|
37
|
+
try {
|
|
38
|
+
const password = await readPassword('请输入主密码以验证数据库: ');
|
|
39
|
+
const salt = Buffer.from(config.salt, 'base64');
|
|
40
|
+
const masterKey = KeyManager.deriveMasterKey(password, salt);
|
|
41
|
+
const encryptedDbKey = config.encrypted_db_key;
|
|
42
|
+
const dbKey = KeyManager.decryptDatabaseKey(encryptedDbKey, masterKey);
|
|
43
|
+
const db = CorivoDatabase.getInstance({ path: dbPath, key: dbKey });
|
|
44
|
+
const health = db.checkHealth();
|
|
45
|
+
if (health.ok) {
|
|
46
|
+
console.log('✅ 数据库完整性检查通过');
|
|
47
|
+
const stats = db.getStats();
|
|
48
|
+
console.log(` 存储了 ${stats.total} 个 block`);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
console.log('❌ 数据库完整性检查失败');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error instanceof Error) {
|
|
56
|
+
console.log(`❌ 数据库打开失败: ${error.message}`);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
console.log('❌ 数据库打开失败');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.log('⚠️ 数据库文件不存在');
|
|
65
|
+
console.log(' 将在第一次使用时自动创建');
|
|
66
|
+
}
|
|
67
|
+
// 检查守护进程
|
|
68
|
+
const pidPath = path.join(configDir, 'heartbeat.pid');
|
|
69
|
+
try {
|
|
70
|
+
const pidStr = await fs.readFile(pidPath, 'utf-8');
|
|
71
|
+
const pid = parseInt(pidStr);
|
|
72
|
+
process.kill(pid, 0);
|
|
73
|
+
console.log(`✅ 心跳守护进程运行中 (PID: ${pid})`);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
console.log('⚪ 心跳守护进程未运行');
|
|
77
|
+
}
|
|
78
|
+
console.log('\n健康检查完成');
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyGjD"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 命令 - init
|
|
3
|
+
*
|
|
4
|
+
* 初始化 Corivo,设置密码并创建数据库
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import fsSync from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { KeyManager } from '../../crypto/keys.js';
|
|
10
|
+
import { CorivoDatabase, getDefaultDatabasePath, getConfigDir } from '../../storage/database.js';
|
|
11
|
+
import { FileSystemError } from '../../errors/index.js';
|
|
12
|
+
import { readPassword } from '../utils/password.js';
|
|
13
|
+
/**
|
|
14
|
+
* 退出并清理
|
|
15
|
+
*/
|
|
16
|
+
function exit(code = 0) {
|
|
17
|
+
process.exit(code);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 初始化命令
|
|
21
|
+
*/
|
|
22
|
+
export async function initCommand() {
|
|
23
|
+
console.log('\n═══════════════════════════════════════════════════════');
|
|
24
|
+
console.log(' 欢迎使用 Corivo — 你的赛博伙伴');
|
|
25
|
+
console.log('═══════════════════════════════════════════════════════\n');
|
|
26
|
+
// 检查是否已初始化
|
|
27
|
+
const dbPath = getDefaultDatabasePath();
|
|
28
|
+
try {
|
|
29
|
+
if (fsSync.existsSync(dbPath)) {
|
|
30
|
+
console.log(`⚠️ 检测到 Corivo 已存在于: ${dbPath}`);
|
|
31
|
+
console.log('如果需要重新初始化,请先删除现有数据库:');
|
|
32
|
+
console.log(` rm ${dbPath}`);
|
|
33
|
+
exit(1);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch { }
|
|
37
|
+
// 创建配置目录
|
|
38
|
+
const configDir = getConfigDir();
|
|
39
|
+
try {
|
|
40
|
+
await fs.mkdir(configDir, { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
throw new FileSystemError(`无法创建配置目录: ${configDir}`, { cause: error });
|
|
44
|
+
}
|
|
45
|
+
// 输入密码
|
|
46
|
+
console.log('请设置主密码(用于加密数据库)\n');
|
|
47
|
+
console.log('⚠️ 密码要求:至少 8 位,包含字母和数字\n');
|
|
48
|
+
const password1 = await readPassword('输入密码: ');
|
|
49
|
+
if (!password1) {
|
|
50
|
+
console.log('❌ 密码不能为空');
|
|
51
|
+
exit(1);
|
|
52
|
+
}
|
|
53
|
+
if (!KeyManager.validatePasswordStrength(password1)) {
|
|
54
|
+
console.log('❌ 密码强度不足:至少 8 位,包含字母和数字');
|
|
55
|
+
exit(1);
|
|
56
|
+
}
|
|
57
|
+
const password2 = await readPassword('确认密码: ');
|
|
58
|
+
if (password1 !== password2) {
|
|
59
|
+
console.log('❌ 两次输入的密码不一致');
|
|
60
|
+
exit(1);
|
|
61
|
+
}
|
|
62
|
+
// 生成密钥
|
|
63
|
+
console.log('\n正在生成密钥...');
|
|
64
|
+
const salt = KeyManager.generateSalt();
|
|
65
|
+
const masterKey = KeyManager.deriveMasterKey(password1, salt);
|
|
66
|
+
const dbKey = KeyManager.generateDatabaseKey();
|
|
67
|
+
const encryptedDbKey = KeyManager.encryptDatabaseKey(dbKey, masterKey);
|
|
68
|
+
const recoveryKey = KeyManager.generateRecoveryKey(masterKey);
|
|
69
|
+
// 创建数据库
|
|
70
|
+
console.log('正在创建加密数据库...');
|
|
71
|
+
const db = CorivoDatabase.getInstance({ path: dbPath, key: dbKey });
|
|
72
|
+
// 验证数据库
|
|
73
|
+
const health = db.checkHealth();
|
|
74
|
+
if (!health.ok) {
|
|
75
|
+
console.log('❌ 数据库创建失败');
|
|
76
|
+
exit(1);
|
|
77
|
+
}
|
|
78
|
+
// 保存配置
|
|
79
|
+
const configPath = path.join(configDir, 'config.json');
|
|
80
|
+
const config = {
|
|
81
|
+
version: '0.10.0-mvp',
|
|
82
|
+
created_at: new Date().toISOString(),
|
|
83
|
+
salt: salt.toString('base64'),
|
|
84
|
+
encrypted_db_key: encryptedDbKey,
|
|
85
|
+
};
|
|
86
|
+
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
87
|
+
// 显示恢复密钥
|
|
88
|
+
console.log('\n═══════════════════════════════════════════════════════');
|
|
89
|
+
console.log(' ⚠️ 重要:请妥善保管恢复密钥 ⚠️');
|
|
90
|
+
console.log('═══════════════════════════════════════════════════════\n');
|
|
91
|
+
console.log('您的恢复密钥(24 个单词,BIP39 标准,请手抄保存):\n');
|
|
92
|
+
const recoveryWords = recoveryKey.split(' ');
|
|
93
|
+
console.log(` ${recoveryWords.slice(0, 6).join(' ')}`);
|
|
94
|
+
console.log(` ${recoveryWords.slice(6, 12).join(' ')}`);
|
|
95
|
+
console.log(` ${recoveryWords.slice(12, 18).join(' ')}`);
|
|
96
|
+
console.log(` ${recoveryWords.slice(18, 24).join(' ')}`);
|
|
97
|
+
console.log('\n⚠️ 重要提示:');
|
|
98
|
+
console.log(' 1. 请将这 24 个单词手抄在纸上,存放在安全的地方');
|
|
99
|
+
console.log(' 2. 不要拍照、截图或存储在任何联网设备上');
|
|
100
|
+
console.log(' 3. 任何人获得此密钥都可以访问您的 Corivo 数据');
|
|
101
|
+
console.log(' 4. Corivo 团队也无法帮您恢复此密钥\n');
|
|
102
|
+
await readPassword('\n按回车键确认已手抄恢复密钥...');
|
|
103
|
+
console.log('\n初始化完成!\n');
|
|
104
|
+
// 下一步提示
|
|
105
|
+
console.log('下一步:');
|
|
106
|
+
console.log(' corivo save --content "..." --annotation "性质 · 领域 · 标签"');
|
|
107
|
+
console.log(' corivo query "..."');
|
|
108
|
+
console.log(' corivo status');
|
|
109
|
+
exit(0);
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;GAEG;AACH,SAAS,IAAI,CAAC,IAAI,GAAG,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;IAEzE,WAAW;IACX,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;IACxC,IAAI,CAAC;QACH,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAC;YAC9B,IAAI,CAAC,CAAC,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,SAAS;IACT,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,eAAe,CAAC,aAAa,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,OAAO;IACP,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAEzC,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,IAAI,CAAC,CAAC,CAAC,CAAC;IACV,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,wBAAwB,CAAC,SAAS,CAAC,EAAE,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,IAAI,CAAC,CAAC,CAAC,CAAC;IACV,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC,CAAC,CAAC;IACV,CAAC;IAED,OAAO;IACP,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAE3B,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,UAAU,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,UAAU,CAAC,mBAAmB,EAAE,CAAC;IAC/C,MAAM,cAAc,GAAG,UAAU,CAAC,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACvE,MAAM,WAAW,GAAG,UAAU,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAE9D,QAAQ;IACR,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAE5B,MAAM,EAAE,GAAG,cAAc,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAEpE,QAAQ;IACR,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,IAAI,CAAC,CAAC,CAAC,CAAC;IACV,CAAC;IAED,OAAO;IACP,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,YAAY;QACrB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC7B,gBAAgB,EAAE,cAAc;KACjC,CAAC;IAEF,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAEhE,SAAS;IACT,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAEhD,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE3D,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAE1C,MAAM,YAAY,CAAC,oBAAoB,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAE1B,QAAQ;IACR,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAE/B,IAAI,CAAC,CAAC,CAAC,CAAC;AACV,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 命令 - query
|
|
3
|
+
*
|
|
4
|
+
* 查询 Corivo 中的信息
|
|
5
|
+
*/
|
|
6
|
+
interface QueryOptions {
|
|
7
|
+
limit?: string;
|
|
8
|
+
verbose?: boolean;
|
|
9
|
+
pattern?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function queryCommand(query: string, options: QueryOptions): Promise<void>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/query.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAyFtF"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 命令 - query
|
|
3
|
+
*
|
|
4
|
+
* 查询 Corivo 中的信息
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import { CorivoDatabase, getDefaultDatabasePath, getConfigDir } from '../../storage/database.js';
|
|
10
|
+
import { KeyManager } from '../../crypto/keys.js';
|
|
11
|
+
import { ConfigError } from '../../errors/index.js';
|
|
12
|
+
import { ContextPusher } from '../../push/context.js';
|
|
13
|
+
import { readPassword } from '../utils/password.js';
|
|
14
|
+
export async function queryCommand(query, options) {
|
|
15
|
+
// 读取配置
|
|
16
|
+
const configDir = getConfigDir();
|
|
17
|
+
const configPath = path.join(configDir, 'config.json');
|
|
18
|
+
let config;
|
|
19
|
+
try {
|
|
20
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
21
|
+
config = JSON.parse(content);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
throw new ConfigError('Corivo 未初始化。请先运行: corivo init');
|
|
25
|
+
}
|
|
26
|
+
// 解密数据库密钥
|
|
27
|
+
const password = await readPassword('请输入主密码: ');
|
|
28
|
+
const salt = Buffer.from(config.salt, 'base64');
|
|
29
|
+
const masterKey = KeyManager.deriveMasterKey(password, salt);
|
|
30
|
+
const encryptedDbKey = config.encrypted_db_key;
|
|
31
|
+
const dbKey = KeyManager.decryptDatabaseKey(encryptedDbKey, masterKey);
|
|
32
|
+
// 打开数据库
|
|
33
|
+
const dbPath = getDefaultDatabasePath();
|
|
34
|
+
const db = CorivoDatabase.getInstance({ path: dbPath, key: dbKey });
|
|
35
|
+
// 搜索
|
|
36
|
+
const limit = options.limit ? parseInt(options.limit, 10) : 10;
|
|
37
|
+
if (options.limit && isNaN(limit)) {
|
|
38
|
+
throw new Error('--limit 参数必须是有效数字');
|
|
39
|
+
}
|
|
40
|
+
const results = db.searchBlocks(query, limit);
|
|
41
|
+
if (results.length === 0) {
|
|
42
|
+
console.log(chalk.yellow(`\n未找到与 "${query}" 相关的记忆`));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// 显示结果
|
|
46
|
+
console.log(chalk.cyan(`\n找到 ${results.length} 条相关记忆:\n`));
|
|
47
|
+
for (const block of results) {
|
|
48
|
+
// ID 和内容
|
|
49
|
+
console.log(chalk.gray(block.id) + ' ' + chalk.white(block.content));
|
|
50
|
+
// 元信息
|
|
51
|
+
const annotation = block.annotation || 'pending';
|
|
52
|
+
const statusColor = getStatusColor(block.status);
|
|
53
|
+
const statusText = statusColor(block.status);
|
|
54
|
+
console.log(chalk.gray(` 标注: ${annotation} | 生命力: ${block.vitality} | 状态: ${statusText}`));
|
|
55
|
+
// 详细信息
|
|
56
|
+
if (options.verbose) {
|
|
57
|
+
console.log(chalk.gray(` 访问次数: ${block.access_count}`));
|
|
58
|
+
if (block.last_accessed) {
|
|
59
|
+
const lastAccess = new Date(block.last_accessed);
|
|
60
|
+
const daysAgo = Math.floor((Date.now() - block.last_accessed) / 86400000);
|
|
61
|
+
console.log(chalk.gray(` 最后访问: ${lastAccess.toLocaleString('zh-CN')} (${daysAgo}天前)`));
|
|
62
|
+
}
|
|
63
|
+
if (block.pattern) {
|
|
64
|
+
console.log(chalk.gray(` 模式: ${block.pattern.type} - ${block.pattern.decision}`));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
console.log();
|
|
68
|
+
}
|
|
69
|
+
// 附加上下文推送
|
|
70
|
+
const pusher = new ContextPusher(db);
|
|
71
|
+
// 决策模式推送
|
|
72
|
+
if (options.pattern) {
|
|
73
|
+
const patternContext = await pusher.pushPatterns(query, 3);
|
|
74
|
+
if (patternContext) {
|
|
75
|
+
console.log(patternContext);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// 相关记忆推送
|
|
79
|
+
const context = await pusher.pushContext(query, 5, {
|
|
80
|
+
showAnnotation: true,
|
|
81
|
+
showVitality: true,
|
|
82
|
+
showTime: options.verbose,
|
|
83
|
+
});
|
|
84
|
+
if (context) {
|
|
85
|
+
console.log(context);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* 获取状态对应的颜色函数
|
|
90
|
+
*/
|
|
91
|
+
function getStatusColor(status) {
|
|
92
|
+
switch (status) {
|
|
93
|
+
case 'active':
|
|
94
|
+
return chalk.green;
|
|
95
|
+
case 'cooling':
|
|
96
|
+
return chalk.yellow;
|
|
97
|
+
case 'cold':
|
|
98
|
+
return chalk.hex('#FF9500'); // Orange
|
|
99
|
+
case 'archived':
|
|
100
|
+
return chalk.gray;
|
|
101
|
+
default:
|
|
102
|
+
return chalk.gray;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/cli/commands/query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recover.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/recover.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CA2HpD"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 命令 - recover
|
|
3
|
+
*
|
|
4
|
+
* 密钥恢复流程
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'node:fs/promises';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { CorivoDatabase, getDefaultDatabasePath, getConfigDir } from '../../storage/database.js';
|
|
9
|
+
import { KeyManager } from '../../crypto/keys.js';
|
|
10
|
+
import { ConfigError, ValidationError } from '../../errors/index.js';
|
|
11
|
+
import { readPassword } from '../utils/password.js';
|
|
12
|
+
export async function recoverCommand() {
|
|
13
|
+
console.log('\n═══════════════════════════════════════════════════════');
|
|
14
|
+
console.log(' 数据恢复向导');
|
|
15
|
+
console.log('═══════════════════════════════════════════════════════\n');
|
|
16
|
+
// 检查配置文件
|
|
17
|
+
const configDir = getConfigDir();
|
|
18
|
+
const configPath = path.join(configDir, 'config.json');
|
|
19
|
+
let config;
|
|
20
|
+
try {
|
|
21
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
22
|
+
config = JSON.parse(content);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
throw new ConfigError('配置文件不存在。如果您是首次使用,请运行: corivo init');
|
|
26
|
+
}
|
|
27
|
+
console.log('请选择恢复方式:\n');
|
|
28
|
+
console.log(' [1] 使用恢复密钥(24 个单词,BIP39 标准)');
|
|
29
|
+
console.log(' [2] 退出\n');
|
|
30
|
+
const choice = await readPassword('请选择 [1-2]: ');
|
|
31
|
+
if (choice !== '1') {
|
|
32
|
+
console.log('已取消');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// 输入恢复密钥
|
|
36
|
+
console.log('\n请输入您的恢复密钥(24 个单词,用空格分隔):\n');
|
|
37
|
+
const recoveryKey = await readPassword('恢复密钥: ');
|
|
38
|
+
const inputWords = recoveryKey.trim().split(/\s+/);
|
|
39
|
+
if (inputWords.length !== 24) {
|
|
40
|
+
console.log('❌ 恢复密钥必须是 24 个单词');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// 验证恢复密钥
|
|
44
|
+
console.log('\n正在验证恢复密钥...');
|
|
45
|
+
try {
|
|
46
|
+
KeyManager.deriveFromRecoveryKey(recoveryKey);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (error instanceof ValidationError) {
|
|
50
|
+
console.log(`❌ ${error.message}`);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.log('❌ 恢复密钥验证失败');
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
console.log('✅ 恢复密钥验证通过');
|
|
58
|
+
// 设置新密码
|
|
59
|
+
console.log('\n请设置新的主密码(至少 8 位,包含字母和数字)\n');
|
|
60
|
+
const password1 = await readPassword('新密码: ');
|
|
61
|
+
if (!KeyManager.validatePasswordStrength(password1)) {
|
|
62
|
+
console.log('❌ 密码强度不足');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const password2 = await readPassword('确认新密码: ');
|
|
66
|
+
if (password1 !== password2) {
|
|
67
|
+
console.log('❌ 两次输入的密码不一致');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// 重新生成密钥
|
|
71
|
+
console.log('\n正在重新生成密钥链...');
|
|
72
|
+
const salt = KeyManager.generateSalt();
|
|
73
|
+
const newMasterKey = KeyManager.deriveMasterKey(password1, salt);
|
|
74
|
+
const dbKey = KeyManager.generateDatabaseKey();
|
|
75
|
+
const encryptedDbKey = KeyManager.encryptDatabaseKey(dbKey, newMasterKey);
|
|
76
|
+
// 更新配置
|
|
77
|
+
const newConfig = {
|
|
78
|
+
...config,
|
|
79
|
+
salt: salt.toString('base64'),
|
|
80
|
+
encrypted_db_key: encryptedDbKey,
|
|
81
|
+
recovered_at: new Date().toISOString(),
|
|
82
|
+
};
|
|
83
|
+
await fs.writeFile(configPath, JSON.stringify(newConfig, null, 2));
|
|
84
|
+
// 验证数据库
|
|
85
|
+
const dbPath = getDefaultDatabasePath();
|
|
86
|
+
try {
|
|
87
|
+
const db = CorivoDatabase.getInstance({ path: dbPath, key: dbKey });
|
|
88
|
+
const health = db.checkHealth();
|
|
89
|
+
if (health.ok) {
|
|
90
|
+
console.log('✅ 数据库验证通过');
|
|
91
|
+
const stats = db.getStats();
|
|
92
|
+
console.log(` 已恢复 ${stats.total} 个 block`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
console.log('❌ 数据库验证失败');
|
|
96
|
+
console.log(' 请从其他设备同步最新数据');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
console.log('⚠️ 无法打开数据库');
|
|
101
|
+
console.log(' 请从其他设备同步最新数据');
|
|
102
|
+
}
|
|
103
|
+
// 生成新的恢复密钥
|
|
104
|
+
const newRecoveryKey = KeyManager.generateRecoveryKey(newMasterKey);
|
|
105
|
+
const recoveryWords = newRecoveryKey.split(' ');
|
|
106
|
+
console.log('\n密钥链已更新!');
|
|
107
|
+
console.log('\n⚠️ 重要:您的新恢复密钥已生成(24 个单词)\n');
|
|
108
|
+
console.log(` ${recoveryWords.slice(0, 6).join(' ')}`);
|
|
109
|
+
console.log(` ${recoveryWords.slice(6, 12).join(' ')}`);
|
|
110
|
+
console.log(` ${recoveryWords.slice(12, 18).join(' ')}`);
|
|
111
|
+
console.log(` ${recoveryWords.slice(18, 24).join(' ')}`);
|
|
112
|
+
console.log('\n⚠️ 旧恢复密钥已失效,请保存新的恢复密钥');
|
|
113
|
+
console.log('\n下一步:');
|
|
114
|
+
console.log(' 在其他设备上重新授权(设备列表已重置)');
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=recover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recover.js","sourceRoot":"","sources":["../../../src/cli/commands/recover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 命令 - save
|
|
3
|
+
*
|
|
4
|
+
* 保存信息到 Corivo
|
|
5
|
+
*/
|
|
6
|
+
interface SaveOptions {
|
|
7
|
+
content?: string;
|
|
8
|
+
annotation?: string;
|
|
9
|
+
source?: string;
|
|
10
|
+
pending?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function saveCommand(options: SaveOptions): Promise<void>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=save.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/save.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,UAAU,WAAW;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDrE"}
|