# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## 项目概述 **lemonPCRM** — lemonAI 出品的 Local-First AI 个人人脉管理系统(Personal CRM)。以人为中心、以对话为链接,通过知识图谱管理微信、LinkedIn、X 等多平台社交关系,将每个联系人与其社媒动态、会议纪要、文件、照片全面关联。 AI 对话与编排层基于 ACP 协议驱动本地 Claude CLI 进程,提供单 Agent 执行和 Master → Sub-Agent 多轮编排能力。Node.js + Express,无数据库依赖(使用 Node 22.5+ 内置 `node:sqlite`),数据完全本地化。 ## 常用命令 ```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。 > [!IMPORTANT] A11y service 启用方式 > `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`。 ## 注意事项 - `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` 控制字符后重试。 > [!WARNING] (Agentic Self-Correction Loop Prevention) > **Master Agent 必读**:在 `Bash` tool 中使用含多重双引号的复杂命令(如 `curl -d '{"id":"lemonv"}'`)时,JSON 转义容易崩溃并陷入死循环。 > **解决方案**:任何需要提交 JSON Payload 的操作,先写入 `/tmp/*.json` 文件,再通过 `curl -d @/tmp/payload.json` 发送。