# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## 项目概述 LemonBoss / ArenaSK — 多智能体自主开发系统 + AI Skill 竞技平台。Node.js + Claude CLI 驱动,提供 Agent 协作(公司 / OKR / 招聘 / Pipeline / Task Timeline)与 Skill 市场 / Arena 评测两套能力。 > 品牌历史:项目早期叫 ArenaSK(Skill 竞技场),现演进为 LemonBoss(多 Agent 公司体)。两个名称在代码中并存属正常现象。 ## 快速启动 ```bash # 一次性安装 + 拷贝 .env.example npm run setup # 开发模式(前后端分离,跑完整 ArenaSK + LemonBoss) npm run dev # 后端 server/index.js:3010 + 前端 vite:5173 # 等价快捷脚本(先 kill 占用端口再起) bash start.sh # server/index.js:3010 + vite:5173 # (历史轻量入口,仅 Agent Chat / Company / OKR / Tasks / DevLoop 子集) PORT=3010 node server/agent-server.js ``` > 端口默认 **3010**(`server/config.js`),不是 3000。`start.sh` 会先 kill 占用 3010 / 5173 的进程。 ## 常用命令 ```bash # 启动 npm run dev # 后端 + 前端 npm run server / server:dev # 仅后端 (start / --watch) npm run web / web:build # 前端开发 / 构建到 web/dist/ # 测试 npm test # vitest watch npm run test:unit # vitest run (CI 用) npx vitest run path/to/foo.test.js # 跑单个测试文件 npx vitest run -t "test name" # 按名称过滤单个测试用例 # 跑全量前先起「不带后台驱动」的 server:心跳每 5 分钟往 system/agents/ 建运行态目录, # 扫描该目录的守卫测试会被瞬时竞态打成偶发假失败(详见 docs/done/claude-cli-session-leak.md §七) DISABLE_BACKGROUND_AGENTS=1 bash start.sh # DevLoop 规范 npm run spec:extract # 从 docs/prd/newfunction/*.html 重新生成 _spec/*.md(改完 HTML 后必须跑) npm run spec:check # CI/pre-commit 用,校验 _spec/ 与 HTML 是否同步 # CLI / 工具 npm run skills:sync # 同步 Skill 到 Claude CLI 配置目录 npm run graph:seed # 按 system/agents/ 目录重建图谱种子数据 npm run okr:migrate # goals → okr 存量迁移 ``` ## 架构 ### 技术栈 - **后端**:Node.js (≥18) + Express + WebSocket + SQLite(better-sqlite3, FTS5) - **前端**:Vue 3 + Vite + vue-router + vue-i18n - **AI**:Claude CLI(本地子进程,`--dangerously-skip-permissions` 自动批准) - **包管理**:pnpm workspace(monorepo),`package.json` 含 `module-alias: { "@server": "server" }` ### 两个 Server 入口(重要) | 入口 | 端口 | 启动方式 | 挂载路由 | |------|------|----------|----------| | `server/index.js` | 3010 | `npm run dev` / `npm run server` / `bash start.sh` | 全量:`/api/claude-chat` `/api/config` `/api/evolution` `/api/innovator` `/api/master` `/api/open` `/api/arena` `/api/auth` `/api/users` `/api/whatsapp` `/api/agent` `/api/okr` `/api/company` `/api/graph-runs` `/api/tasks` `/api/devloop`,WS `/ws/claude`,插件 / 心跳 / 中断任务恢复,`NODE_ENV=production` 时托管 `web/dist/` 静态文件 | | `server/agent-server.js` | 3010 | 仅手动 `node server/agent-server.js`(历史保留) | 子集:`/api/agent` `/api/company` `/api/okr` `/api/graph-runs` `/api/tasks` `/api/devloop` | 两者**不要同时启动**(端口冲突)。默认走 `index.js`(`start.sh` / `npm run dev` 都指向它);`agent-server.js` 只在你想跑无依赖最小子集时手动启动。 ### 目录速查 | 目录 | 说明 | |------|------| | `server/index.js` | 完整 ArenaSK 服务(API + WS + 插件 + 前端托管),`start.sh` / `npm run dev` 默认入口 | | `server/agent-server.js` | 历史保留的轻量子集入口(Agent / Company / Goals / Tasks / DevLoop),仅手动启动 | | `server/routes/` | 各 API 路由(挂载点见上表两个入口,以入口文件为准) | | `server/services/` | 业务服务(skill-db, benchmark-runner, company-service, heartbeat-service, company-heartbeat-service, pipeline-service, retrain-pipeline, graph-engine, …) | | `server/src/core/` | Agent 引擎核心(orchestrator, master-session, agent-manager, scheduler, session-pool, prompt-builder, runtime-resolver, …) | | `server/src/engine/` | 进程层(command-queue, idle-timer, process-guard, run-registry, failover-error) | | `server/src/plugins/` | 插件系统(plugin-manager, agent-bridge, config-bridge, bootstrap) | | `server/src/core/devloop/` | DevLoop 编排核心:`loop-controller.js`(createProject / callAgent / runDocsPhase / runUnit) | | `server/services/devloop/` | DevLoop 支撑服务:path-resolver, git-vault, unit-registry(FSM), timeline-logger, bug-tracker, doc-store, changelog-writer, sse-broker | | `server/src/tools/devloop/` | DevLoop Agent 可调用工具(coder/tester/integrator/triager/doc/persistence-tools + tool-registry + sandbox) | | `server/routes/devloop.js` | DevLoop REST:`/api/devloop/projects` | | `system/agents/` | **全部 Agent 本体的唯一目录**。`_base/` 是元 Agent 骨架,`_registry.json` 只用于按 id 补 `benchmark_score`(**目录才是数据源头**,`graph-seed-service.seedAgents()` 直接扫目录)。`_` 前缀为保留 id,扫描时跳过 | | `system/agents/devloop-*/` | 六个 DevLoop Agent(pm, architect, coder, tester, integrator, triager),每个含 `config.json` + `prompt.md` + 一份指路用的薄 `agent.md` | | `system/org-graph-templates/` `system/work-graph-templates/` | Org/Work graph 的骨架模板库——公司类型 / org node 职能 → 图形状的**唯一查询入口**,`orggraph-planning`/`workgraph-planning` 建图时读这里选型,人工排查"为什么现场规划出这张图"也从这里查起。每个模板的 `whenToUse` 字段是选型依据,加新模板见各自 `README.md`「加一个新模板」一节;改完 `work-graph-templates/*.json` 跑一遍 `npx vitest run server/tests/unit/template-refs.test.js`(CI 用,查 `systemAgentId` 引用不落空) | | `server/src/tools/` | Master Agent 可调用的工具(call-agent, marketplace, orchestrate, train-skill, …) | | `web/src/views/` | 页面:AgentChat, AgentList, CompanyDashboard, GraphConsole, JobsPanel, OkrDashboard, PipelineEditor, QuotaMonitor, SkillsMarket, TaskTimeline + DevLoop 四页(Dashboard / Projects / NewRequirement / Ops)。TemplateAgents(手工模板管理页)已于 2026-08-23 随「system/templates/ 并入 system/agents/」一起下线,agent 本体现在完全走自动化招聘产生 | | `packages/` | `acp-core`, `agent-core`, `evolution`, `plugin-bootstrap` | | `/../data/skills/` | Skill 仓库。**在仓库外面一层**,不是 `/data/skills/`(后者不存在)。路径由 `config.skillsDataDir` 控制,见下「数据存储」的两个 data 根 | | `scripts/` | 运维脚本(含 `sync-skills.js`) | | `docs/` | 设计文档,**按状态分目录**:`done/`(已实现 / 长期参考手册,含 `system-design/` 01–26 章与 `user-guides/`)、`todo/`(当前主线,27/28 系列)、`todo/future/`(暂缓)、`_archive/`。另有 `prd/`(DevLoop 规格源,见上)。**索引在 [`docs/README.md`](docs/README.md),逐条带状态说明 —— 找文档从那里进,别在本表里加文件名**(这一行曾经列了 5 个具体文件,文档移进 `done/` 之后全成了死链) | ### 关键 API 路由 | 路径 | 说明 | |------|------| | `/api/open/skills` | Open API: Skill 搜索 / 下载(FTS5) | | `/api/open/arena/leaderboard` | Arena ELO 排行榜 | | `/api/innovator/skills` | Skill 管理(Admin) | | `/api/master/chat` | Master Agent 对话(SSE) | | `/api/agent/*` | LemonBoss Agent Chat | | `/api/company/*` `/api/okr/*` `/api/tasks/*` | 公司 / OKR / Task 管理(OKR 只此一个挂载点,`/api/goals` 别名已于 27-P3C §六.1 退役,有守卫测试盯着) | | `/api/auth/*` | JWT + GitHub OAuth | | `/ws/claude` | Claude 实时对话(仅 `index.js`) | | `/api/health` `/api/plugins` | 健康检查 / 插件状态 | | `/api/devloop/projects` | DevLoop:创建项目 + 跑 PM/Architect(POST)、列项目 / 查状态(GET,见下) | | `/api/dream/*` | 经验汇流(29-DREAM):`dream-service.js` 能力的 REST 封装,只读查询 + 触发 `dreamOnce`/`dreamSweep`,不新增业务逻辑,见 [`docs/done/system-design/29-dream-design.md`](docs/done/system-design/29-dream-design.md) | ### DevLoop 子系统 多 Agent 自动开发流水线(PM → Architect → Coder → Tester → Integrator → Triager),目前处于 P2(单 Unit 循环)阶段,正朝 P3(跨 Unit runProject)推进。 - **规格优先**:所有实现以 `docs/prd/newfunction/_spec/*.md` 为准(机器可读,由 `npm run spec:extract` 从同名 `*.html` 自动生成,**不要手改 `_spec/`**;改 HTML 后必须重跑 extract,否则 pre-commit hook 会拦)。跨切约定集中在 `_spec/CONVENTIONS.md`(ID 生成规则、错误响应形态、文件原子写入、并发锁策略、日志分流、命名风格)——写 DevLoop 代码前先读这份。 - **项目根**:每个 DevLoop 项目是独立 git 仓库,由 `path-resolver.allocateProjectRoot` 分配(`sandbox` 或 `linked-*` 模式),`git-vault` 负责 init/commit,每个 Agent 收尾后自动 commit(`loop-controller.commitAfterAgent`,commit kind 按 agent 名映射:pm→prd, architect→sdd, coder/tester→code, integrator→integ, triager→triage)。 - **Mock 模式**:P1-P2 阶段 Agent 调用默认走 `ClaudeCliProtocol({mock:true})`(`packages/acp-core/protocol/ClaudeCliProtocol.js`),不真正起 Claude CLI 子进程,而是从 `fixtures/devloop-mock/*.json` 回放固定的 chunks/files/result;显式传 `mock:false` 才会用真实 CLI。 - **L1 单 Unit 循环**(`runUnit`,P2):Coder(implement) → Tester(test),失败时把上一次 failure + coder.log 摘要打回去重跑(retry-with-reflection),直到 tester 通过或耗尽 `retry_budget`(默认 5)。每次状态转换都过 `unit-registry` 的 FSM(coding → testing → passed/failed → blocked)。 - **单元产物布局**:项目根下 `units/{unitId}/{spec.json, code/, contract.json, coder.log, runs/{runId}/result.json}`;跨 unit 只能读 `../{otherUnit}/contract.json`,禁止直接读别的 unit 的 `code/`(见 CONVENTIONS.md §12)。 - **审计轨迹**:`timeline.ndjson`(append-only,永不改已写行)记录所有 Agent 调用 / commit / 状态转换事件,`bugs.ndjson` / `changelog.ndjson` 走同样的追加模式。 - **测试**:`server/tests/devloop/**/*.test.js`(服务层 + 工具层单测)+ `server/tests/devloop/routes.test.js`(REST 层)。 ### 数据存储(SQLite,无需 PostgreSQL) > [!IMPORTANT] > **有两个不同的 `data/` 根,别混**。ArenaSK 时代的三个库落在**仓库外面一层**, > LemonBoss 的数据在**仓库内**。看到以 `data/` 开头的路径先确认是哪一个 —— 备份、迁移、 > 换机器时漏掉仓库外那半边,skill / 用户 / benchmark 数据会静默丢失。 > 判据看源码里 `path.resolve(__dirname, ...)` 的层数(当前 11 个模块指仓库内、3 个指仓库外)。 **仓库外** `/../data/` — ArenaSK 侧(`benchmark-db.js` / `skill-db.js` / `user-db.js`, 均可用 `SKILLS_DB_PATH` / `USERS_DB_PATH` / `BENCHMARK_DB_PATH` 等 env 覆盖): - `skills/` — Skill 目录(数万条),路径由 `config.skillsDataDir` 控制 - `skills.sqlite` — Skill 主库 + FTS5 - `users.sqlite` — 用户数据 - `benchmark_logs.sqlite` — Benchmark 运行数据(**不是** `benchmark.sqlite`) - `trained_skills/` — 用户训练产物(按 userId 隔离) **仓库内** `/data/` — LemonBoss 侧(company / okr / graph / devloop 都在这儿): - `graph.sqlite` — 图谱库(`GRAPH_DB_PATH` 可覆盖) - `companies/` — 公司态(含 DevLoop 项目根、agent memory) - `okr/` `logs/` `agents/` — OKR 索引 / 运行日志 / agent 运行态 会话持久化有**两套**,不是一处: - `/conversations/` — ArenaSK / Innovator 侧(`config.conversationsDir`,`CONVERSATIONS_DIR` 可覆盖) - `/conversations/{convId}/` — LemonBoss agent-chat 侧(`agent-chat.getConvDir` → `locator.companyStateDir`) ### 配置文件 | 文件 | 说明 | |------|------| | `.env` | 端口、CORS、`OPEN_API_KEYS`、各类目录覆盖;由 `npm run setup` 从 `.env.example` 生成 | | `server/config.js` | 端口(默认 3010)、CORS、Skill / Conversations 路径 | | `server/config/taxonomy.js` | 三维标签分类 | ## 注意事项 - 生产环境只跑 `server/index.js`:它会同时托管 API + `web/dist/` 静态文件(`NODE_ENV=production`)。 - `start.sh` **只**做:kill 占用 3010/5173 的进程 → 起 `server/index.js` → 起 `vite`。**不**会自动 `skills:sync` / `web:build` / 起 bot —— 那些要单独跑。 - `server/index.js` 与 `agent-server.js` 都内置了 **body-sanitizer 中间件**:在 `express.json()` 之前清掉 `\x00-\x1F` 控制字符,避免外部 Agent 通过 `curl` 传未转义换行/制表符导致的 `Bad control character` 报错。修改请求体解析链路前先看这两段。 - **agent-chat 的 `sessions` 池存的是常驻 claude CLI 子进程**(stream-json 模式,不是一次性的 `claude -p`)。 新增一条会创建会话的调用路径时,必须同时想清楚它的回收路径 —— 判据只有一条:**convId 会不会被下一轮复用**。 不复用的(心跳 / 日程 / 告警 / 日报)在 `CALL_KINDS` 里标 `true`,跑完即回收;会复用的(pipeline 被驳回重做、 人类多轮对话)标 `false`,靠空闲 TTL 兜底(`AGENT_SESSION_IDLE_MS`,默认 30 分钟)。 漏标的症状是**静默的**:不报错、不写日志、`git status` 干净,只有内存一路涨(曾经 2h43m 漏出 82 个进程 / 17.5 GB)。 守卫:`server/tests/unit/agent-chat-session-reclaim.test.js`。 - 模块别名 `@server` → `server/`(`module-alias` 注册),跨子包 require 时可用。 - Claude CLI 进程默认带 `--dangerously-skip-permissions`,写入受限路径前自己评估风险。 - DevLoop 详见上方「DevLoop 子系统」一节;需要 wireframe / SVG 图表 / 完整人类阅读版时才回查 `_spec/*.md` 同名的 `*.html`。 > [!WARNING] (Agentic Self-Correction Loop Prevention) > **Master Agent 必读**: 你目前存在一个已知的底层 Tool Calling JSON 解析缺陷。当你试图在 `Bash` tool 中使用带有多重双引号的复杂命令(例如 `curl -d '{"id":"lemonv", "name":"Lemonv"}'`)时,你的 JSON 转义会崩溃并导致你陷入"修复格式"的无限死循环,最终进程会被强制终止退出 (code=143)。 > **解决方案**: > 任何需要提交复杂 Payload (如 JSON) 的操作,**绝对禁止**直接在 `Bash` 的 command 参数里写 inline JSON 字符串。 > 如果你要创建公司或执行类似 API 请求,**必须先通过写入简单的 shell 脚本将 JSON 写入一个 /tmp/ 目录下的 `.json` 文件(确保你的 JSON 是单行紧凑格式/严格转义换行符,不要包含真回车换行 `\n`,以免引起 SyntaxError: Bad control character 崩溃),然后再通过 `curl -d @/tmp/payload.json` 发送。** > > 【创建公司/招聘的正确方式示例】 > 创建 /tmp/lemonv.json,然后执行 `Bash`: `curl -X POST http://localhost:3000/api/company/create -H "Content-Type: application/json" -d @/tmp/lemonv.json`