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 公司体)。两个名称在代码中并存属正常现象。
快速启动
# 一次性安装 + 拷贝 .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 的进程。
常用命令
# 启动
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 |
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 |
<repo>/../data/skills/ |
Skill 仓库。在仓库外面一层,不是 <repo>/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 规格源,见上)。索引在 <code>docs/README.md</code>,逐条带状态说明 —— 找文档从那里进,别在本表里加文件名(这一行曾经列了 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,不新增业务逻辑,见 <code>docs/todo/system-design/29-dream-design.md</code> |
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 个指仓库外)。
仓库外 <repo>/../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 主库 + FTS5users.sqlite— 用户数据benchmark_logs.sqlite— Benchmark 运行数据(不是benchmark.sqlite)trained_skills/— 用户训练产物(按 userId 隔离)
仓库内 <repo>/data/ — LemonBoss 侧(company / okr / graph / devloop 都在这儿):
graph.sqlite— 图谱库(GRAPH_DB_PATH可覆盖)companies/— 公司态(含 DevLoop 项目根、agent memory)okr/logs/agents/— OKR 索引 / 运行日志 / agent 运行态
会话持久化有两套,不是一处:
<repo>/conversations/— ArenaSK / Innovator 侧(config.conversationsDir,CONVERSATIONS_DIR可覆盖)<agent 公司态目录>/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 Master Agent 必读: 你目前存在一个已知的底层 Tool Calling JSON 解析缺陷。当你试图在
Bashtool 中使用带有多重双引号的复杂命令(例如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