From c7f16ba1efd8dd488c70cb19a7ad95c107142cfc Mon Sep 17 00:00:00 2001 From: yibo Date: Tue, 9 Jun 2026 16:33:07 +0800 Subject: [PATCH] docs(lifelog): 转向纯端上 App,废弃 lemonPCRM + 端上 CRM 补齐 TODO --- CLAUDE.md | 207 +++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------ lifelog-recorder/HANDOFF.md | 30 +++++++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 159 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index aea8e7a..8dfdf21 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,164 +4,35 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## 项目概述 -本仓库(`aipcrm/`)现在托管 **3 个互相关联但独立的子项目**: +本仓库(`aipcrm/`)的**主线 = `lifelog-recorder/`** —— Pixel 8 Pro 上一个**完全端上、零云端**的 Local-First 个人记忆 + 人脉管理(Personal CRM)原生应用:24/7 录音 + 本地中文 ASR + 声纹/人脸识别 + 端上 LLM 纪要/对话 + 以「人」为中心的联系人档案 + 全相册语义索引。所有能力跑在设备上,**不依赖任何 Mac/PC 服务**。 | 子项目 | 路径 | 形态 | 状态 | |---|---|---|---| -| **lemonPCRM** | `server/` + `frontend/` + `packages/` | Node.js + Express 后端 + 静态前端 | 主线 | -| **wechat_plain** | `wechat_plain/` | Android Xposed/A11y 模块 + Pixel 部署脚本 | 主线 | -| **lifelog-recorder** | `lifelog-recorder/` | Pixel 原生 Android 应用(Kotlin + Compose) | v0.8 (2026-06) | +| **lifelog-recorder** | `lifelog-recorder/` | Pixel 原生 Android 应用(Kotlin + Compose) | **主线 v0.8** | +| **wechat_plain** | `wechat_plain/` | Pixel 上微信 bot 的 Xposed/A11y 模块(端上) | 辅助 | +| **lemonPCRM** | `server/` + `frontend/` + `packages/` | Node.js + Express 后端 + 静态前端 | **已废弃** | -**lemonPCRM** — lemonAI 出品的 Local-First AI 个人人脉管理系统(Personal CRM)。以人为中心、以对话为链接,通过知识图谱管理微信、LinkedIn、X 等多平台社交关系,将每个联系人与其社媒动态、会议纪要、文件、照片全面关联。 +> [!IMPORTANT] 方向已转向纯端上 App +> 早期主线是 **lemonPCRM**(Mac 上 Node/Express + 知识图谱 + ACP 驱动 Claude CLI 的服务端 CRM)。 +> 现已**废弃**:其 Personal CRM 能力已在 `lifelog-recorder` 里**原生端上重实现**(联系人档案、人脸/声纹识别、 +> AI 印象、RAG 对话、照片语义检索),不再依赖 Mac。`server/` `frontend/` `packages/` 代码仅作历史留仓, +> **新功能不要往里加,也不要把 app 回链到它**。App 与旧 lemonPCRM 的能力对比 / 仍存差距见下文 +> §lifelog-recorder「App 即 Personal CRM:与旧 lemonPCRM 的能力对比」。 -AI 对话与编排层基于 ACP 协议驱动本地 Claude CLI 进程,提供单 Agent 执行和 Master → Sub-Agent 多轮编排能力。Node.js + Express,无数据库依赖(使用 Node 22.5+ 内置 `node:sqlite`),数据完全本地化。 +### wechat_plain(端上微信 bot,辅助) -**wechat_plain** — Pixel 上微信 bot 的 Xposed/A11y 落地(A11y UI 自动化是当前唯一能真把消息推进 message 表的发送链路;详见下文 §微信集成架构)。 +Pixel 上微信发送/跟踪的落地,纯设备内运行(不依赖 Mac): -**lifelog-recorder** — Pixel 8 Pro 上的 24/7 录音 + 本地中文 ASR + 时间轴 lifelog 应用(2026-06 新增,详见下文 §lifelog-recorder)。 - -## 常用命令 - -```bash -npm run setup # 首次初始化:cp .env.example .env + pnpm install -npm start # 生产模式(node server/index.js) -npm run dev # 开发模式(node --watch server/index.js,热重载) -./dev.sh # 杀掉端口占用进程 + npm run dev(推荐开发用) -``` - -无测试框架,无 lint 脚本。使用 pnpm workspaces(`packageManager: pnpm@10.28.1`)。 - -## 架构 - -### 技术栈 -- **后端**:Node.js (≥18) + Express,pnpm workspace monorepo -- **数据库**:Node 22.5+ 内置 `node:sqlite`(`DatabaseSync`),位于 `server/db/lemon_crm.db` -- **AI**:Claude CLI(本地子进程,`--dangerously-skip-permissions` 自动批准) -- **文件解析**:mammoth(.docx)、pdf-parse(.pdf) - -### 目录速查 - -| 目录 | 说明 | -|------|------| -| `packages/acp-core/` | ACP 协议层:Protocol / Transport / Launcher 三层抽象 + ClaudeCliProtocol / AcpProtocol | -| `packages/agent-core/` | Agent 运行时(ESM):目录驱动的 Agent、AgentBus、AgentRegistry、AgentScaffold | -| `server/index.js` | Express 入口(路由 + 静态前端) | -| `server/src/core/` | 编排引擎:orchestrator、master-session、agent-manager、session-pool、stream-executor、prompt-builder、parser、runtime-resolver | -| `server/src/engine/` | 进程层:run-registry、command-queue、process-guard、idle-timer、failover-error | -| `server/src/tools/` | Master 工具:call-agent-tool、tool-registry、graph/(图谱 MCP 工具集) | -| `server/src/standalone-entry.js` | 编程 API:`runMasterSession` / `runOrchestration` / `runSingleAgent` | -| `server/routes/` | API 路由:master-chat、config、graph、wechat、import、analysis、photo | -| `server/services/` | conversation-logger、file-parser、memory-service、claude-chat-service、wechat/、linkedin/、meeting/、photo/、x/ | -| `server/db/GraphStore.js` | 本地知识图谱存储层(SQLite):Person / Organization / Project / Event / Asset 节点 + KNOWS / BELONGS_TO / PARTICIPATED 等边 | -| `frontend/` | 静态前端(单 HTML 文件,由 server/index.js 托管) | -| `server/config/backends.json` | ACP Launcher / Client 定义 | -| `server/config/agents.json` | 静态 Agent 注册表(可选,也可由 `system/agents/` 目录发现) | - -### API 路由 - -| 路径 | 说明 | -|------|------| -| `POST /api/master/chat` | Master Agent 多轮对话(SSE) | -| `POST /api/master/upload` | 文件上传注入对话 | -| `GET /api/master/sessions` | 列出活跃 session | -| `DELETE /api/master/sessions/:id` | 关闭 session | -| `GET/PUT /api/config/items/:key` | 读写配置文件 | -| `GET /api/health` | 健康检查 | -| `GET /api/graph/nodes` | 列出图谱节点(?type=Person&limit=100) | -| `GET /api/graph/nodes/:id` | 查询单个节点(含边) | -| `POST /api/graph/nodes` | 创建/更新节点 | -| `GET /api/graph/search?q=关键词` | 全文搜索 | -| `POST /api/graph/edges` | 创建关系边 | -| `GET /api/graph/path?from=id&to=id` | 查询关系路径 | -| `POST /api/wechat/import-contacts` | 导入微信联系人到图谱 | -| `POST /api/wechat/import-chat` | 导入微信聊天记录 | -| `GET /api/wechat/contacts?q=搜索` | 查询微信联系人 | -| `GET /api/wechat/sessions` | 最近会话列表 | -| `POST /api/import/...` | 多平台数据导入 | -| `POST /api/analysis/...` | 图谱分析(关系链路、聚类等) | -| `POST /api/photo/...` | 照片服务(人脸聚类、向量检索) | - -### 配置文件 - -| 文件 | 说明 | -|------|------| -| `.env` | PORT(默认 3010)、HOST、CORS_ORIGINS 等 | -| `server/config.js` | 端口、CORS、目录路径的运行时配置对象 | -| `server/config/backends.json` | ACP Launcher 定义(command、args、protocol) | -| `server/config/agents.json` | 静态 Agent 注册(可选) | - -## 关键架构模式 - -### ACP 协议四层结构 - -``` -Application (AgentManager) - ↓ -Protocol (ClaudeCliProtocol 直接 spawn / AcpProtocol JSON-RPC) - ↓ -Transport (ProcessTransport stdio / PipeTransport / WebSocketTransport) - ↓ -Launcher (ProcessLauncher spawn / NoneLauncher 无操作) -``` - -`runtime-resolver.js` 根据 `backends.json` + `agents.json` 配置自动推断使用哪一层。 - -**ClaudeCliProtocol 调用方式**: -- 生成命令:`claude --input-format stream-json --output-format stream-json --verbose --include-partial-messages --dangerously-skip-permissions` -- 输入格式:`{"type":"user","message":{"role":"user","content":[{"type":"text","text":"..."}]}}` -- 输出:NDJSON 事件流 -- 单进程跨多轮复用(session reuse) - -**Mock 模式**:设置 `LEMONBOSS_CLAUDE_MODE=mock` 可读取 fixture 文件而不启动真实进程,用于调试。 - -### Master → Sub-Agent 调度流程 - -1. 用户消息 → `MasterSession.handleMessage()` -2. `PromptBuilder` 组装系统提示(含工具描述 + 可用 Agent 列表) -3. Claude 响应中的工具调用用 `[TOOL_CALL: tool_name] {...json...} [/TOOL_CALL]` 格式标记 -4. `ToolRegistry.parseToolCalls()` 解析后交给 `AgentManager.callAgent()` -5. `SessionPool` 按 `agentName:client:deploy:workDir[:scope]` 为 key 复用已有 session -6. 工具结果注回对话,最多循环 10 轮(`SAFETY_MAX_LOOPS=15`) - -**Orchestrator** 额外提供格式自动修正(`MAX_REPAIRS=5`)与结果验证(`ResultTracker`)。 - -### Agent 发现与记忆 - -- Agent 优先从 `system/agents/` 目录发现(目录驱动),`agents.json` 作为静态补充 -- 每个 Agent 的记忆存储在其目录下的 `memory/` 子目录,纯文件系统 -- `AgentScaffold` 用于创建新 Agent 目录结构 - -### 知识图谱(GraphStore) - -`server/db/GraphStore.js` 使用 `node:sqlite`(Node 22.5+ `DatabaseSync`),无需额外依赖。 - -- **节点类型**:Person、Organization、Project、Event、Asset -- **边类型**:KNOWS、BELONGS_TO、PARTICIPATED、CONTAINS、MENTIONED_IN、ASSOCIATED -- **分析状态**:`analysis_status` 字段跟踪节点是否已被 AI 分析(none / pending / done) -- **Master 工具**:`server/src/tools/graph/` 提供 `create_person`、`get_person`、`link_persons`、`search_graph`、`get_relationship_path` 等工具供 AI 调用 - -### 微信集成架构 - -`server/services/wechat/` 提供从 Mac 和 Pixel 双端点与微信交互的能力: - -- **发送消息(实际工作链路)**:`am broadcast com.hermes.wechat.SEND_MSG` → **`HermesAccessibilityService`**(lsposed-wechat-sendmsg 模块内)→ 启动微信 LauncherUI → 点搜索按钮 → 搜索 `toUserDisplayName`(**必须传 nickname**,如"火星人")→ 点搜索结果 → 找 `bkk` 容器内的 EditText 输入文本 → 点 `bql` 发送按钮。纯 UI 自动化,绕开所有反射 / hook 失败。 -- **消息跟踪**:`android-wechat-tracker-sqlcipher.js` 直接轮询解密后的 `EnMicroMsg.db`(SQLCipher) -- **自动回复**:`auto-reply.js` 结合 tracker + broadcast,在 Pixel 上独立运行 -- **数据导入**:`wechat-importer.js` / `wechat-reader.js` 将联系人和聊天记录导入知识图谱 - -> [!WARNING] 关于其他两条已废弃的发送路径 -> - **LSPosed 反射 API**(`HermesWeChatModule.sendTextMessageDirect`):监听同一广播但走 `u01.r1.a → m1.a()`。`Send result: true` 是**误报**——`builder.a()` 后主线程异步提交触发 null 异常被 swallow,消息不进 `message` 表。 -> - **Frida daemon 队列**(`android-wechat-sender-frida.js` + `wechat_plain/scripts/frida-daemon/frida_daemon.js`):Frida 17 + 微信 8.0.72 注入大体积 bundle 触发反调试,微信进程崩溃,已废弃。 -> 这两条路径的命名让人误解;真正能把消息推进 message 表的只有 A11y service。 +- **发送消息(唯一可用链路)**:`am broadcast com.hermes.wechat.SEND_MSG` → **`HermesAccessibilityService`**(lsposed-wechat-sendmsg 模块内)→ 启动微信 LauncherUI → 点搜索按钮 → 搜索 nickname(如"火星人")→ 点结果 → `bkk` 容器内 EditText 输入文本 → 点 `bql` 发送按钮。纯 A11y UI 自动化,绕开所有反射 / hook 失败。 +- **已废弃的两条发送路径(命名误导,勿用)**:LSPosed 反射 API(`HermesWeChatModule.sendTextMessageDirect`,`Send result: true` 是误报,消息不进 `message` 表);Frida daemon(Frida 17 + 微信 8.0.72 注入大 bundle 触发反调试崩溃)。真正能推进 message 表的只有 A11y service。 > [!IMPORTANT] A11y service 启用方式 -> `enabled_accessibility_services` 系统设置易被关闭。检查与重新启用: +> `enabled_accessibility_services` 系统设置易被关掉,重启: > ```bash -> adb shell "settings get secure enabled_accessibility_services" > adb shell "su -c 'settings put secure enabled_accessibility_services com.hermes.wechat.xposed/com.hermes.wechat.xposed.accessibility.HermesAccessibilityService; settings put secure accessibility_enabled 1'" > ``` -详见 `server/services/wechat/README.md`。 +详见 `wechat_plain/` 内文档。 ## lifelog-recorder(Pixel 8 Pro 24/7 录音 + 本地中文 ASR + 本地 LLM,v0.8) @@ -169,7 +40,7 @@ Launcher (ProcessLauncher spawn / NoneLauncher 无操作) ### 项目目标 -把 Pixel 8 Pro 当成**永远开机的麦克风**:7×24 后台录音 → VAD 切段 → 中文 ASR 转文字 → 入库 → 按时间轴显示和搜索 → LLM 总结成纪要。最终目的是把所有「我说过 / 别人对我说过」的内容沉淀成可搜索、可回放的个人记忆库,下接 lemonPCRM 的人脉图谱(某段语音 → 某联系人 → 某项目)。 +把 Pixel 8 Pro 当成**永远开机的麦克风**:7×24 后台录音 → VAD 切段 → 中文 ASR 转文字 → 入库 → 按时间轴显示和搜索 → LLM 总结成纪要。最终目的是把所有「我说过 / 别人对我说过」的内容沉淀成可搜索、可回放的个人记忆库,并在 **app 内自成端上 Personal CRM**(photolog):某段语音 → 声纹 → 联系人档案,照片 → 人脸 → 同一联系人。**整套 CRM 跑在设备上,已取代旧的 Mac 端 lemonPCRM**。 约束:**完全本地 / 零云端依赖 / 月成本 0 元 / 隐私走 0 网络**。 @@ -273,19 +144,43 @@ Foreground Service (foregroundServiceType=microphone, WAKE_LOCK partial) 剩余摘要: - ⭐ **语义搜图落地**(v0.8 已接 `EmbedClient`,但需在 Pixel llama-swap 配 `embed` 模型才生效;中文 embedding GGUF) -- ⭐ **回链 lemonPCRM**(Transcript / 照片 caption 实体 → GraphStore `MENTIONED_IN`,v2) +- ⭐ **内部 Transcript 实体 → Person 表**(端上 NER + 共现,取代旧「回链 lemonPCRM」;见下文 §下一步) +- ⭐ **微信抽取端上化**(消除 photolog 仅剩的 Mac 依赖;见下文差距分析 #6) + +### App 即 Personal CRM:与旧 lemonPCRM 的能力对比 + +App(photolog)已覆盖、并在「联系人」维度超过旧 lemonPCRM 的核心: + +| 能力 | 旧 lemonPCRM(Mac/server) | 现 app(端上) | +|---|---|---| +| 联系人实体 | `Person` 图节点 | `Person`(融合 **声纹/人脸/微信/手机** 四模态,更丰富) | +| 多源导入 | 微信 / LinkedIn / X / 会议 / 照片 | 微信 + 手机通讯录 + 手动 + **24/7 录音(独有)** | +| 每人聚合视图 | 社媒动态 / 纪要 / 文件 / 照片 | 聊天 / 朋友圈 / 照片 / **录音** / AI 印象 / 简历(`PersonProfileScreen` 四 tab) | +| AI | Master Agent over 图谱(工具编排) | RAG 对话 over 转写/纪要(`LifelogRetriever`)+ AI 印象 | +| 照片 | 人脸聚类 + CLIP 检索 | 人脸聚类 + 语义检索(端上 ML Kit + ArcFace + Qwen-VL + embed) | +| 部署 | Mac Node 服务(依赖 Claude CLI) | **纯端上**(更隐私 / 零成本 / 零网络) | + +**仍存差距**(旧 lemonPCRM 有、app 还没有): + +1. **人↔人关系图**:app 只有 *人↔模态*(声纹/人脸/微信/手机)链接,**没有 person↔person 边**(KNOWS / 同事 / 同项目)。app 现在是「带富资料的扁平联系人表」,不是知识图谱。 +2. **Organization / Project / Event 实体**:app 只有 `Person`/`Photo`/`Face`,没有组织/项目/事件节点。 +3. **关系分析**:旧有 关系路径(`path`) / 社群发现(`communities`) / 待跟进(`followups`);app 三者皆无。 +4. **AI agent / 工具编排**:app 是**纯 RAG 对话**,AI 不能对数据做动作(建人 / 连边);旧有 Master→Sub-Agent + 图谱工具(`create_person`/`link_persons` 等)。 +5. **Transcript 内容 → 实体**:app 只按**声纹**把录音连到 `Person`(谁说的),**没有从转写文本抽人名/项目**做关联(旧 lemonPCRM 的 `MENTIONED_IN`)——这正是下一步要补的。 +6. **微信抽取端上化**:微信联系人/头像/聊天/朋友圈仍由 **Mac 一次性抽取**(解密 `EnMicroMsg.db` + 抠头像)推到 `filesDir/wx_enroll/`,再由 `WeChatEnrollWorker` 端上入库。手机系统通讯录已完全端上;微信抽取是「纯 App」最后一块拼图。 + +### 下一步:Transcript 实体 → 内部 Person 表(取代旧「回链 lemonPCRM」) -### 与 lemonPCRM 的关系 +**不再回链外部 server**,改在 **app 内部**打通:从 `Transcript.text` / `Summary` 抽实体(人名/项目/地点,端上 LLM 或规则 NER)→ 与本地 `Person` 表匹配 → 建一张「提及」关系(新表 `mentions(segmentId, personId, ...)` 或 Person↔Segment 边)。让 `PersonProfileScreen` 除了现有「TA 自己说的」(声纹匹配段)之外,还能显示「**TA 被哪些录音提到、说了什么**」。这直接补差距 #5;同段被同时提到的人 → 共现边,又为差距 #1(人↔人关系图)打基础。 -目前**完全独立**——lifelog-recorder 的 Room DB 跟 lemonPCRM 的 GraphStore 没打通。未来计划:把 Transcript / Summary 表里的实体(人名 / 地名 / 项目)抽到 GraphStore 当 `MENTIONED_IN` 边,让你的「某次会议说了什么」可以从图谱里反查。这是 v2 范畴。 +> 上面 6 项差距的**可执行 TODO 清单(带优先级 P0–P3 + 做法)**见 `lifelog-recorder/HANDOFF.md` §「端上 CRM 补齐 — TODO」。路线:P0 #5 → P1 #1 → P2 #6。 ## 注意事项 -- `server/src/standalone-entry.js` 的 `loadConfig()` 优先读 `backends.json` + `agents.json`,无需数据库。 -- `prompt-builder.js` 的 `getSystemStateXML()` 只返回时间戳(公司/OKR 层已移除)。 -- Agent 目录内放 `SKILL.md` 文件会绕过协议封装,直接作为系统提示使用。 -- `server/index.js` 包含控制字符净化中间件:Agent 通过 curl 发送的 JSON body 可能含原始换行符,若解析失败会自动清理 `\x00-\x1F` 控制字符后重试。 +- **构建**:`cd lifelog-recorder && JAVA_HOME=/opt/homebrew/opt/openjdk@17 ./gradlew :app:assembleDebug`,`adb install -r ...`。无测试框架。改 Room schema **必须写 Migration**(`AppDatabase` 已去 destructive 改 fail-loud;24/7 录音库静默清掉是大事故,见 memory `lifelog-room-migration-wipe.md`)。 +- **改完即真机验证**:app 是 24/7 录音的命脉,改 `RecorderService` / 管线后务必装机看 logcat(`reconcile →` / `pipeline running` / `BlockProcessor`)确认录音没断。 +- **`keys.properties` / `local.properties` gitignored**:讯飞凭证 + Hermes 端点 → `BuildConfig`;`sdk.dir` 换机要改。模板见 `keys.properties.example`。 +- **`server/` `frontend/` `packages/`(旧 lemonPCRM)已废弃**:不再维护、不要往里加功能、不要让 app 依赖它。 -> [!WARNING] (Agentic Self-Correction Loop Prevention) -> **Master Agent 必读**:在 `Bash` tool 中使用含多重双引号的复杂命令(如 `curl -d '{"id":"lemonv"}'`)时,JSON 转义容易崩溃并陷入死循环。 -> **解决方案**:任何需要提交 JSON Payload 的操作,先写入 `/tmp/*.json` 文件,再通过 `curl -d @/tmp/payload.json` 发送。 +> [!NOTE] 旧 lemonPCRM 的服务端架构(ACP 四层 / Master→Sub-Agent / GraphStore / 微信 server 链路)已从本文件移除。 +> 如确需考古,查 git 历史里本文件的早期版本。 diff --git a/lifelog-recorder/HANDOFF.md b/lifelog-recorder/HANDOFF.md index ee853a2..c0d8630 100644 --- a/lifelog-recorder/HANDOFF.md +++ b/lifelog-recorder/HANDOFF.md @@ -254,11 +254,35 @@ Tier-0 PhotoFaceWorker (15min, battery-not-low) Tier-1 PhotoVlWorker (1 剩下: -1. **存储 TTL**:删超过 N 天的 .opus,文字永留。Periodic WorkManager job。 -2. **设置页**:存储用量、模型切换、provider 切换、暂停时段配置(v1 定的 MVP 是「一键暂停就够」,但 v2 可能要细化)。 +1. ✅ **存储 TTL**(2026-06-08 完成):`StorageManager.prune` 按天目录删超期 .opus、文字永留;每天 periodic worker;设置页「存储」段(用量 + 保留时长 + 立即清理),默认永久保留。 +2. ✅ **设置页**(基本完成):`SettingsScreen` 已含 纪要模型后端 / 聚类·合并·最短识别阈值 / llama-swap 端点 / 分段间隔 / **定时不录(quiet hours)** / 存储用量+TTL / 电池豁免。 3. ✅ **多 anchor 平均**(2026-06-07 完成,L2):重命名/合并某说话人时 `rebuildAnchor` 用该人名下全部段的均值重建 anchor,取代单段注册。 -4. **回链 lemonPCRM**:Transcript 提到的人名 / 项目 → GraphStore `MENTIONED_IN` 边。 +4. **内部 Transcript 实体 → Person 表**(取代旧「回链 lemonPCRM」):在 **app 内部**从 `Transcript.text`/`Summary` 抽实体(人名/项目,端上 LLM 或规则 NER)→ 匹配本地 `Person` → 建「提及」关系(新表 `mentions(segmentId, personId)`),让人物档案显示「TA 被哪些录音提到」(现仅显示「TA 自己说的」=声纹段)。同段共现的人 → 人↔人边。**不再回链 Mac 端 lemonPCRM**(已废弃)。 5. ✅ **hermes gateway 自启**(2026-06-04 完成):用 Magisk `service.d` 脚本开机拉起(Termux:Boot 未装,root 方案更稳),见下方「§ 自启(Magisk service.d)」。 +6. **微信抽取端上化**:消除 photolog 仅剩的 Mac 依赖(微信联系人/头像/聊天/朋友圈现由 Mac 一次性抽取推到 `filesDir/wx_enroll/`)。 + +### 端上 CRM 补齐 — TODO(对齐并超越旧 lemonPCRM) + +> 旧 Mac 端 lemonPCRM 已废弃,能力在 app 内重建。下表是「app 当前缺、旧 lemonPCRM 有」的 6 项, +> 按优先级排(P0 先做)。能力对比详见 CLAUDE.md §「App 即 Personal CRM」。 + +- [ ] **P0 · #5 Transcript 内容 → Person「提及」关系**(最高价值,最贴 app 形态) + - 现状:录音只按**声纹**连到人(谁说的);不从转写文本抽人名/项目。 + - 做法:块处理后(或事后 worker)对 `Transcript.text` 抽实体(端上 LLM 4B 或规则/词典 NER)→ 匹配本地 `Person`(name/realName/nickname/alias,拼音兜底)→ 写新表 `mentions(segmentId, personId, name, confidence)`(Room 迁移 +1)。 + - 出口:`PersonProfileScreen` 加「被提到」tab(现只有「TA 自己说的」=声纹段)。 + - 依赖:端上 4B 已就绪(llama-swap 8080)。 +- [ ] **P1 · #1 人↔人关系(共现边)** + - 做法:基于 #5,同一会话/时间段被同时提到 + 同时在场(声纹)的人 → `relations(personA, personB, kind, weight)` 共现/认识边,weight 随共现次数累加。 + - 出口:人物档案「相关的人」;后续可做关系图可视化。 +- [ ] **P2 · #6 微信抽取端上化**(消除最后的 Mac 依赖,工程债) + - 现状:微信联系人/头像/聊天/朋友圈由 Mac 解密 `EnMicroMsg.db`(SQLCipher)+抠头像,推到 `filesDir/wx_enroll/`。 + - 做法:把解密+抽取搬到端上(root + SQLCipher key 端上取),`WeChatEnrollWorker` 直接读微信库;配方见 memory `wechat-android-decrypt.md` / `wechat-avatar-face-enrollment.md`。 +- [ ] **P3 · #2 Organization / Project / Event 实体**(产品决策:要不要从「联系人表」长成「图谱」) + - 新增节点类型 + 与 Person 的边(属于/参与);可由 #5 的实体抽取顺带产出(项目名/公司名/事件)。 +- [ ] **P3 · #3 关系分析**:关系路径(两人间最短链)/ 社群发现(聚类)/ 待跟进(followups:从录音承诺「下周给他发X」抽待办)。依赖 #1 的关系边。 +- [ ] **P3 · #4 AI 能对数据做动作(agent/工具编排)**:让对话 AI 不止 RAG 问答,还能调工具建人/连边/改资料(端上轻量 tool-calling,Hermes 或本地模型)。最大、最后做。 + +> 路线:**P0(#5) → P1(#1) → P2(#6)**,三步把「录音→人→关系」在端上闭环;P3 三项是「要不要把 app 升级成真·知识图谱 + AI agent」的产品选择,按需再开。 ### hermes gateway 设置(v0.5 关键前置) -- libgit2 0.21.4