This file is the source of truth for coding agents working in this repository.
Update project guidance here; CLAUDE.md is only a compatibility import.
- Claude Code 2.1.277+ can load
AGENTS.mddirectly when no project or ancestorCLAUDE.md/CLAUDE.local.mdtakes precedence. Support also depends on the built-inagents-mdplugin; gateway and telemetry-disabled sessions before 2.1.281 have additional limitations. - Keep the root
CLAUDE.mdas the single line@AGENTS.md. This official import syntax loads the shared instructions for older or restricted sessions without maintaining a second copy. - The locked Agent SDK 0.3.156 declares
claudeCodeVersion: 2.1.156, below the direct-loading minimum. Bothclaude-code-action@v1workflows use a gateway and do not pinclaude_code_version. A locally installed CLI version does not establish their compatibility. - Preserve the executor's
settingSourcesselection and caller overrides, including[]. These control filesystem settings as well as project instruction loading; renaming the source of guidance is not a reason to change permissions, settings, or skill discovery. - CI prompts and documentation maintenance should read and update
AGENTS.md. For other repositories, honor their existingAGENTS.mdandCLAUDE.mdconventions.
References: Claude Code instruction loading and imports, 2.1.277 release notes.
Anycode — a multi-agent development system with Feishu (Lark) as collaboration UI, powered by Anthropic's Claude Code via the Agent SDK. Users send messages in Feishu chats, and the server executes Claude Code queries against a working directory on the host machine.
npm run dev # Start dev server with auto-reload (tsx watch)
npm run build # Compile TypeScript to dist/
npm start # Run compiled JS from dist/
npm run typecheck # Type-check without emitting
npm run lint # ESLint on src/npx vitest run # Run all tests (vitest)Feishu User → Feishu Platform → Bridge Server → Claude Agent SDK → Claude Code subprocess
↑
Progress cards + result cards sent back to Feishu
src/index.ts— Entry point: validates config, starts server, sets up 30-min cleanup interval and graceful shutdown (SIGINT/SIGTERM).src/config.ts— Environment-based configuration loader. Exports single config object with Feishu, Claude, workspace, memory, cron settings.src/server.ts— Express server with dual event mode: WebSocket (default, no public IP needed) or HTTP webhook.src/agent/— Multi-agent role system.registry.tsstores agent configs at runtime;router.tsroutes messages to agents by chat binding rules;config-loader.tsloads agent configs from JSON (config/agents.json) with hot-reload.src/claude/executor.ts— Wraps@anthropic-ai/claude-agent-sdkquery(). Streams SDKMessage, tracks cost/duration, supports session resumption and workspace restart with conversation trace forwarding. Budget:CLAUDE_MAX_BUDGET_USD(default $50),CLAUDE_MAX_TURNS(default 500).src/feishu/client.ts— Feishu API wrapper for sending/updating messages and cards.src/feishu/event-handler.ts— EventDispatcher: parse message → check allowlist → get/create session → enqueue task → execute → send result.src/feishu/message-builder.ts— Constructs interactive Feishu card messages for progress and results.src/feishu/thread-context.ts— Unified thread/workspace context resolution before execution. Defaults toDEFAULT_WORK_DIR; main agent usessetup_workspaceMCP tool to switch repos during execution.src/feishu/bot-registry.ts— Tracks bot members in group chats; auto-discovers via events and message senders.src/feishu/tools/— MCP tool suite:doc.ts(文档),wiki.ts(知识库),bitable.ts(多维表格),drive.ts(云空间),chat.ts,calendar.ts,contact.ts,task.ts. Action-based dispatch with Zod schemas.src/workspace/manager.ts— Git clone + workspace isolation. Supports remote URL (via bare cache) and local path modes.src/workspace/cache.ts— Bare clone cache layer with atomic creation and configurable fetch interval.src/workspace/registry.ts— Repo registry system. Scans DEFAULT_WORK_DIR + .repo-cache, maintains JSON index (.repo-registry.json) with canonical URL keys, generates Markdown for LLM reading. Caches source repo paths forisInsideSourceRepo().src/workspace/isolation.ts— Per-thread workspace isolation + source repo protection.isInsideSourceRepo()blocks writes to DEFAULT_WORK_DIR source repos viacanUseTool.src/pipeline/orchestrator.ts— State-machine-driven dev pipeline (plan → plan_review → implement → code_review → push → pr_fixup). Max 2 retries per phase.src/pipeline/reviewer.ts— Parallel review with 3 agents (correctness/security/architecture) + optional Codex reviewer.src/session/manager.ts— SQLite-backed session store keyed byagent:{agentId}:{chatId}:{userId}. Thread-level sessions bind threadId → workdir/conversationId.src/session/database.ts— SQLite persistence with 13 migrations. Stores sessions, thread sessions, summaries, and OAuth tokens.src/session/queue.ts— Per-chat FIFO task queue ensuring one Claude query runs at a time per chat.src/memory/— Long-term memory system.store.ts(SQLite + sqlite-vec CRUD),search.ts(hybrid BM25 + vector),extractor.ts(LLM auto-extraction),injector.ts(prompt injection),commands.ts(/memory slash commands).src/cron/— Scheduled task system.scheduler.ts(cron/interval/at scheduling with retry),store.ts(SQLite persistence),tool.ts(MCP tool for agent interaction).src/platform/types.ts— Platform-agnostic message interfaces (MessagePort, InboundMessage).src/utils/security.ts— User allowlist check and dangerous command regex detection.src/utils/logger.ts— Pino logger singleton.
- ESM throughout —
"type": "module"in package.json, ES2022 target,.jsextensions in imports. - Singleton instances —
sessionManager,claudeExecutor,taskQueue,feishuClient,loggerare module-level singletons. - Two-phase messaging — Send a progress card first, then update it with the final result card.
- Session isolation — Each Feishu chat gets its own working directory and serialized task queue.
canUseToolmust returnupdatedInput—{ behavior: 'allow' }alone causes SDK internal Zod validation failure. MCP tool handlers silently won't execute. Must return{ behavior: 'allow', updatedInput: inputObj }.bypassPermissionsfails under root — UsepermissionMode: 'acceptEdits'+canUseToolcallback instead.settingSourcesselects filesystem settings —'project'loads.claude/settings.jsonand enables project instructions;'local'loads.claude/settings.local.json. Preserve caller overrides, especially[]for SDK isolation. In this repository, project instructions enter through theCLAUDE.mdimport ofAGENTS.md.- Skills require
allowedTools: ['Skill']— SDK 默认不启用 Skill 工具。仅有settingSources: ['project']不够,还需在allowedTools中显式包含'Skill',否则.claude/skills/中的 SKILL.md 不会被加载。 - Feishu rich text breaks URLs —
github.com:user/repogets auto-linked by Feishu as[github.com:](http://github.com/)user/repo. Theworkspace/manager.tsnormalizeRepoUrl()handles SSH shorthand normalization. options.env完全替换子进程环境(SDK 0.3.x) — 一旦传入env,子进程不再继承父进程环境,必须自行展开:{ ...process.env, ANTHROPIC_BASE_URL: ... }。否则会丢失ANTHROPIC_API_KEY/PATH/HOME,导致 Claude Code 返回Not logged in · Please run /login。仅在配了代理ANTHROPIC_BASE_URL时才需要传env(见claude/executor.ts)。注意 0.2.x 是合并语义({...process.env, ...你的}),升级到 0.3.x 时这是隐蔽的破坏性变更。
Agent definitions, knowledge files, and persona prompts live in config/ but are not checked into git (deployment-specific). Only config/agents.example.json is tracked as a structural reference.
First-time setup: cp config/agents.example.json config/agents.json then customize. Without config/agents.json, the system falls back to a minimal built-in dev agent.
Loaded via dotenv (see .env.example):
- Required:
FEISHU_APP_ID,FEISHU_APP_SECRET - Claude:
ANTHROPIC_API_KEY,DEFAULT_WORK_DIR(default: parent of cwd),CLAUDE_TIMEOUT(default: 300s),CLAUDE_MAX_TURNS(default: 500),CLAUDE_MAX_BUDGET_USD(default: 50) - Workspace:
REPO_CACHE_DIR(bare clone cache),WORKSPACE_BASE_DIR(writable workspaces),WORKSPACE_BRANCH_PREFIX - Event mode:
FEISHU_EVENT_MODE(websocket|webhook),FEISHU_ENCRYPT_KEY,FEISHU_VERIFY_TOKEN(webhook only) - Memory:
MEMORY_ENABLED,DASHSCOPE_API_KEY,MEMORY_DB_PATH(default:./data/memories.db),MEMORY_EMBEDDING_MODEL,MEMORY_VECTOR_WEIGHT - Cron:
CRON_DB_PATH(default:./data/cron.db) - Security:
ALLOWED_USER_IDS(comma-separated, empty = allow all) - Server:
PORT(default: 3000),NODE_ENV,LOG_LEVEL
- 新功能必须附带单元测试 — 新增的模块/函数需要在
tests/下有对应的.test.ts文件。每个 feat commit 必须伴随对应的 test commit。 - Bug fix 需附带回归测试 — 修复的 bug 应有测试用例覆盖,防止回归。
- 复杂改动须通过完整回归 — 涉及多模块或核心逻辑的改动,提交前需运行
npx vitest run确保全部测试通过。 - PR 不得降低测试覆盖率 — 新增代码应有合理的测试覆盖,不允许只加功能不加测试。
- 部署方式取决于运行环境(PM2、systemd、Docker 等),服务启动时自动检测进程管理器类型(见
src/utils/runtime.ts)。 - 升级/拉取后必须跑
npm install—@anthropic-ai/claude-agent-sdk0.3.x 起,Claude Code CLI 二进制改为通过optionalDependencies按平台分发(@anthropic-ai/claude-agent-sdk-<platform>,约 240MB)。只git pull+ 重新npm run build+ 拷dist/不会拉到该二进制,服务会起不来。npm install会按 OS/CPU/libc 自动选包(glibc/musl、x64/arm64 均有)。同理,@anthropic-ai/sdk与@modelcontextprotocol/sdk在 0.3.x 是 peerDependencies,已提为本仓库的直接依赖。 - 自重启须在对话最后一步执行 — Claude 是服务的子进程,使用
sleep 5 && <restart command> &脱离当前进程,避免 kill 自己的父进程导致对话中断。
- TypeScript 5.7, Node.js 18+, Express 4
@anthropic-ai/claude-agent-sdkfor Claude Code execution@larksuiteoapi/node-sdkfor Feishu API + WebSocket events- Pino for structured logging, Zod available for validation
文档按生命周期分三个目录:
| 目录 | 内容 | 生命周期 |
|---|---|---|
docs/plans/ |
活跃的实施计划 | 短期,完成后蒸馏关键决策到 design/,再删除 |
docs/design/ |
模块架构与设计决策(描述现状) | 长期保留,随代码持续更新 |
docs/research/ |
调研分析 | 只读参考 |
- 开始新任务前,扫描
docs/plans/*.md的 YAML front matter,读取summary和read_when字段,判断是否与当前任务相关。如果相关,先读完该计划再动手。 - 也可以运行
node scripts/docs-list.mjs快速查看所有活跃计划的列表(支持--status in_progress过滤和--json输出)。 - 修改代码时,检查
docs/design/*.md的related_paths字段。如果当前修改涉及某文档的关联路径,阅读该文档,若描述与代码现状不符则一并更新(将提案口吻改写为现状描述)。 - Plan 完成时,将关键设计决策和架构信息蒸馏到
docs/design/对应文档,然后删除 plan 文件。 - 新建计划文件时,必须包含以下 front matter:
---
summary: "一句话描述"
status: draft # draft | in_progress | completed
owner: git-id
last_updated: "YYYY-MM-DD"
read_when:
- 触发场景 1
- 触发场景 2
---- Design 文档也使用 front matter,格式:
---
summary: "一句话描述"
related_paths:
- src/module/**
last_updated: "YYYY-MM-DD"
---