agent-Specialization/CLAUDE.md

408 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
> 和用户交流时默认使用中文。
## Project Overview
多用户 AI Agent 系统,为每个登录用户提供独立的 Docker 容器环境。支持终端交互、文件操作、对话管理和实时监控。主要用于学习和实验"智能体 + 真实 Dev Workflow",代码大量由 AI 生成。
## Core Architecture
### Entry Points
- **统一入口**: `python main.py` - 当前实现默认进入 Web 启动流程thinking_mode=True
- **推荐 Web 入口**: `python -m server.app` - 封装并转发到 `server/app_legacy.py`,主链路为 REST 任务轮询,默认端口 8091
- **兼容入口**: `python web_server.py` - 已标记 deprecated但仍可启动
### Key Components
**server/** (Flask 业务主线chat/task/status 已拆分子包,以 REST 任务轮询为主Socket.IO 用于兼容与实时辅助通道)
- `app.py` / `app_legacy.py` - Web 服务入口与遗留实现
- `chat/` / `chat_flow*.py` - 对话接口已拆分为子包与任务流编排runner / tool_loop / stream_loop / task_main 等拆分)
- `status/` - 状态/项目/容器/工作区相关接口(已拆分为子包)
- `tasks/` - 任务管理接口(已拆分为子包)
- `goal_flow.py` - 自主目标循环
- `deep_compression.py` - 上下文深度压缩
- `conversation.py` / `files.py` / `auth.py` / `admin.py` / `api_v1.py` / `context.py` - 对话、文件、认证、管理、API v1、请求上下文接口
**core/**
- `MainTerminal` (`main_terminal.py`) - CLI 主终端,处理用户输入和 AI 对话循环;逻辑拆分到 `core/main_terminal_parts/*`commands / context / tools_definition / tools_execution / tools_policy / tools_read 等)
- `WebTerminal` (`web_terminal.py`) - Web 终端,继承 MainTerminal支持轮询任务与实时通道兼容能力
- `tool_config.py` - 定义所有工具的配置和分类
**modules/**
- `user_container_manager.py` - 单用户-单容器管理,负责容器生命周期
- `container_file_proxy.py` - 容器内文件代理,通过 `docker exec` 沙箱化文件操作
- `terminal_manager.py` - 管理多个持久化终端会话
- `persistent_terminal/` - 持久化终端核心(已拆分为 base + mixin 子包)
- `terminal_ops/` - 终端命令执行相关能力(已拆分为 base + mixin 子包)
- `mcp_client_manager/` - MCP 客户端管理(已拆分为子包)
- `file_manager/` - 文件 CRUD包含搜索、替换和 append/modify streaming 功能(已拆分为子包)
- `conversation_manager/` - 对话历史持久化(已拆分为 base + mixin 子包)
- `context_manager/` - 上下文构建、token统计、对话管理已拆分为 base + mixin 子包)
- `memory_manager.py` - 长期记忆管理
- `todo_manager.py` - 待办事项管理
- `modules/sub_agent/` - 子智能体任务调度与执行(主进程内协程,工具调用复用主 WebTerminal
- `user_manager.py` - 用户认证和工作区管理
- `upload_security.py` - 上传文件隔离扫描
**utils/**
- `api_client.py` - 兼容入口,实际实现已迁移到 `utils/api_client/` 子包mixin 组织)
- `tool_result_formatter.py` - 兼容入口,实际实现已迁移到 `utils/tool_result_formatter/` 子包
- `terminal_factory.py` - 终端类型工厂
**static/**
- Vue 3 + TS 前端(`static/src/`,分层为 `app/` `stores/` `components/` `composables/`),聊天主链路使用 REST 任务轮询,保留 Socket.IO 兼容能力,包含对话流、终端输出、资源监控面板
- 监控动画核心文件:`static/src/components/chat/monitor/MonitorDirector.ts`(动画与场景执行)、`static/src/stores/monitor.ts`(事件队列与状态机)
**cli/**
- React 19 + Ink 6 + TypeScript CLI 前端(正在重写中),连接现有本地 Web API默认 `127.0.0.1:8091`),不是独立 agent runtime
- 关键文件:`cli/src/App.tsx`、`cli/src/components.tsx`、`cli/src/eventMapper.ts`、`cli/src/api.ts`
**docker/**
- `terminal.Dockerfile` - 终端容器镜像构建配置
## Development Commands
### Build & Run
```bash
# === 开箱即用release / 首次部署,推荐)===
# 首次初始化:建 venv、装依赖、跑配置向导模式/端口/管理员/密钥/模型)
./setup.sh
# 启动(首次无 .env 会自动跑向导,然后起服务)
./start.sh
# start.sh 透传参数给 server.app例如
./start.sh --thinking-mode
# === 手动方式(开发) ===
# 安装 Python 依赖
pip install -r requirements.txt # 开发用,宽松
pip install -r requirements.lock.txt # 可复现/打包用,精确版本
# 构建终端镜像
docker build -f docker/terminal.Dockerfile -t my-agent-shell:latest .
# 统一入口(默认进入 Web 启动流程)
python main.py
# 推荐 Web 启动
python -m server.app
# 可选参数
python -m server.app --path ./project --port 8091 --debug --thinking-mode
# 兼容启动方式deprecated
python web_server.py
```
### Frontend (根目录 Vue)
```bash
npm install
# 构建(默认只看最后 5 行,减少 Vite 构建资源列表等无关输出)
npm run build --silent 2>&1 | tail -n 5
# 开发监听(当前脚本是 build watch
npm run dev
# Lint
npm run lint
```
### CLI (React / Ink)
```bash
npm --prefix cli install
# 开发启动
npm run cli # 或 npm --prefix cli run dev
# 构建
npm run cli:build
# 类型检查
npm run cli:typecheck
# 可执行命令名构建后agents / agents-cli
```
### Testing
```bash
# 主要离线冒烟用例unittest
python -m unittest test.test_server_refactor_smoke
# 改动后端接口适配(如 server/chat/、server/status/、server/tasks/)时补充
python3 -m py_compile server/chat/*.py server/status/*.py server/tasks/*.py
# CLI 最小可复现验证
npm --prefix cli run typecheck
npm --prefix cli run build
```
> 仓库未发现 `pytest.ini`/`pyproject.toml`/`tox.ini`,不要默认要求 `pytest` 作为唯一入口。`test/test_system_message.py` 依赖外部 `MOONSHOT_API_KEY` 与网络,不属于离线稳定用例。
### Debugging
```bash
# 查看容器状态
docker ps -a | grep agent-term
# 查看调试日志(运行态日志默认在 ~/.agents/agents/<mode>/logs/
tail -f ~/.agents/agents/host/logs/debug_stream.log # host 模式
tail -f ~/.agents/agents/web/logs/debug_stream.log # web/docker 模式
# 查看容器统计
tail -f ~/.agents/agents/web/logs/container_stats.log
```
## Configuration
主要配置文件:`.env`(复制 `.env.example`
**必填变量**:
- `AGENT_API_BASE_URL` - OpenAI-compatible API 端点
- `AGENT_API_KEY` - API 密钥
- `AGENT_MODEL_ID` - 模型 ID (例如 deepseek-chat)
- `WEB_SECRET_KEY` - Flask session 密钥
**容器配置** (`config/terminal.py`):
- `TERMINAL_SANDBOX_MODE` - docker/host
- `TERMINAL_SANDBOX_IMAGE` - 容器镜像 (默认 python:3.11-slim)
- `TERMINAL_SANDBOX_NETWORK` - 网络模式 (bridge/none/host)
- `TERMINAL_SANDBOX_CPUS` - CPU 限制
- `TERMINAL_SANDBOX_MEMORY` - 内存限制
**资源限制**:
- `PROJECT_MAX_STORAGE_MB` - 单用户磁盘配额 (默认 2048MB)
- `MAX_ACTIVE_USER_CONTAINERS` - 并发容器数量 (默认 8)
**数据目录与路径变量** (`config/paths.py`2026-06 更新):
运行态数据默认存放在 `~/.agents/agents/<mode>`(对齐 `~/.claude`、`~/.codex`**不落在源码树**。数据根目录(`data_root`)默认为 `~/.agents/agents`,可通过 `AGENTS_DATA_ROOT` 整体搬迁;模式由 `TERMINAL_SANDBOX_MODE` 决定:`host` → `~/.agents/agents/host`,其它(默认 docker/web`~/.agents/agents/web`。数据根目录下还包含 `settings.json`(唯一配置文件)和 `config/`部署级配置host/web 共享)。每个模式目录下含 `data/`对话、用户库、记忆、sub_agents.json、sub_agent_tasks、`users/`、`api/users/`、`logs/`。
路径解析优先级(高→低):
1. 具体目录变量 `DATA_DIR` / `LOGS_DIR` / `USER_SPACE_DIR` / `API_USER_SPACE_DIR`(单独覆盖某目录)
2. 数据根目录变量 `AGENTS_DATA_ROOT`(整体搬迁运行态数据根目录,默认 `~/.agents/agents`
3. 兜底 `~/.agents/agents/<mode>`
**Host / Web 双路径机制2026-06**:
- `paths.py` 新增 `IS_HOST_MODE`、`WEB_DATA_DIR`、`WEB_USER_SPACE_DIR` 三个固定变量
- host 模式下 `UserManager` 同时加载 `host/``web/` 的用户与工作区web 用户不覆盖已有)
- 已有 web 工作区直接复用(保持旧数据可访问),新工作区写入 host/
- web 模式:仅读取 web/ 数据,无变化
> `config/*.json` 分两类:**程序能力**`docker_risk_markers.json`、`skill_hints.json`)与 `prompts/`、`agentskills/` 一样锚定源码树;**部署级配置**`custom_models`、`host_workspaces`、`auto_approval`、`goal_review`、`forbidden_commands`、`host_sandbox_policy`)外置到 `~/.agents/agents/config/``DEPLOY_CONFIG_DIR`host/web 共享),读取走 `config.resolve_deploy_config(name)`,回退链:部署目录 → 源码树 `.json` → 源码树 `.json.example`。含密钥/机器特定的 5 个不进 git仓库仅留 `.example`。
**日志策略**:
- API 请求体 dump 默认**关闭**`AGENT_API_DUMP_ENABLED=1` 开启。
- 混合轮转(`utils/log_rotation.py`):追加型单文件按大小轮转(默认 20MB×3 份dump 目录按份保留(默认 30 个)。阈值变量:`AGENT_LOG_ROTATE_MAX_BYTES` / `AGENT_LOG_ROTATE_BACKUPS` / `AGENT_DUMP_KEEP`
**数据迁移**:
- `scripts/migrate_runtime_data.py`:源码树 → `~/.agents/agents/<mode>`,复制+备份+可回滚+幂等,`logs/` 丢弃不迁。脚本复用 config 路径解析(模式由 `.env` 决定),执行前先 `--dry-run` 确认目标。
## Important Implementation Details
### File Operations
文件写入统一使用 `write_file`/`edit_file` 工具完成:`write_file` 负责覆盖或追加内容,`edit_file` 负责精确字符串替换,不再依赖历史版本的流式标签标记。
### Container Architecture
每个用户登录时:
1. `UserContainerManager` 创建专属容器
2. 容器挂载 `users/<username>/project/``/workspace`
3. 所有文件操作通过 `ContainerFileProxy` 在容器内执行
4. 终端会话通过 `docker exec` 运行
5. 空闲超时或登出后自动销毁容器
### Context Management
`ContextManager` 负责:
- 动态构建上下文(系统提示 + 工具 + 对话历史 + 聚焦文件 + 记忆)
- Token 统计和限制检查
- 对话历史保存和加载
- 自动保存机制(每次 API 调用后增量保存)
### Thinking Mode
支持"思考模式"(需配置 `AGENT_THINKING_MODEL_ID`
- 首次调用使用 reasoning 模型(如 deepseek-reasoner
- 后续调用使用快速模型
- 可通过 `THINKING_FAST_INTERVAL` 控制切换频率
- 失败时自动回退到思考模式
### Web Socket Events
主要事件:
- `send_message` - 发送用户消息
- `thinking_start/chunk/end` - 思考过程
- `text_start/chunk/end` - 文本响应
- `tool_preparing/start/update_action` - 工具执行状态
- `conversation_list_update` - 对话列表更新
- `terminal_output` - 终端输出
## Common Patterns
### Adding New Tools
1.`core/main_terminal_parts/tools_execution.py`(及相关 `tools_*.py`)实现执行逻辑
2.`core/tool_config.py` / `core/main_terminal_parts/tools_definition.py` 中注册工具定义
3. 如需在任务流/流式输出中特殊处理,在 `server/chat_flow*.py` 对应环节添加逻辑
### 代码修改约定
- **最小改动原则**:只改与需求直接相关文件,避免顺手重构。
- **文件编辑方式**:优先使用原生文件编辑工具,尽量不要用 `bash`/`python` 脚本批量改文件。
- **后端改动优先级**:先改 `modules/`、`server/` 内对应模块,最后才动入口。
- **前端改动优先级**:按 `static/src` 现有分层改(`app/` `stores/` `components/` `composables/`)。
- **CLI 改动优先级**:优先在 `cli/src/App.tsx`、`cli/src/components.tsx`、`cli/src/eventMapper.ts`、`cli/src/api.ts` 内做最小闭环修改。
- 涉及 monitor 动画/事件联动时,至少同步检查 `MonitorDirector.ts``stores/monitor.ts`
- **前端不强制本地构建**:沙箱环境无法成功执行 `npm run build` / `npm run cli:build`,因此改完前端不必每次都跑构建验证。改动后用类型检查(`npm run lint` / `npm --prefix cli run typecheck`)或人工 review 自查即可,构建交由用户在本机或 CI 完成。
### Working with Containers
使用 `ContainerHandle`:
```python
# 文件操作
result = container_handle.execute_file_op("read", path="/workspace/file.txt")
# 执行命令
result = container_handle.run_command("ls -la /workspace")
# 终端会话
result = container_handle.start_terminal(session_name="main", working_dir="/workspace")
```
### Managing Conversations
```python
# 创建新对话
terminal.create_new_conversation(thinking_mode=True)
# 加载对话
terminal.load_conversation(conversation_id)
# 搜索对话
terminal.search_conversations(query="bug fix")
# 删除对话
terminal.delete_conversation(conversation_id)
```
## 前端设计风格统一规范(强制)
> 适用范围:所有前端 UI以 `static/src` Web 为主;`cli/src` 在视觉可类比处同样适用;以及未来新增的任何界面)。
> 约束级别:写新 UI 或改动 UI 时**必须遵守**;遇到存量违规应在最小改动允许范围内顺手修正。
1. **禁止边缘光晕**:不使用任何 glow / 外发光 / 彩色光晕效果(大范围彩色 `box-shadow` 扩散、用 `filter: drop-shadow` 做光圈、`::before/::after` 模糊光晕等)。已有的要移除。允许的只是中性、克制的投影——沿用 `--claude-shadow` / `--theme-shadow-*` 这类已有 token不要自造发光阴影。**仅在用户明确允许或要求时才可使用光晕效果。**
2. **禁止原生浏览器组件**:不直接使用浏览器默认外观的 `<select>`、`<input type=checkbox/radio/range/date/color>`、`alert/confirm/prompt`、原生右键菜单、原生 tooltip 等。一律替换为与项目风格统一的自定义组件下拉、开关、单选、滑块、模态、Toast 等)。
3. **禁止圆角套娃**:不允许「圆角矩形里再套圆角矩形再套圆角矩形」的多层嵌套卡片——这是典型的垃圾审美,且会极大占据有效显示面积。容器层级要扁平:能用分隔线 / 留白 / 底色区分的,就不要再多包一层带边框圆角的盒子。
4. **图标外框对齐**:同一组图标按钮的外框(点击热区 / 容器)必须对齐统一,不能一个居中、一个左对齐、一个右对齐。同组按钮固定相同尺寸与对齐方式。
5. **图标视觉对齐而非理论对齐**:按图标的视觉重心对齐,而不是几何边界盒。对视觉重心偏移的图标(三角形 / 播放键 / 放大镜等做微调micro-nudge让它「看起来居中」而非「数值上居中」。
6. **颜色遵循三模式切换 + 两层 Token**:所有颜色必须走原生三模式(经典 `classic` / 明亮 `light` / 夜间 `dark`),禁止写死颜色字面量(含裸 hex、`rgb()`/`hsl()` 字面色、`var(--x, #hex)` 兜底),一律使用语义 CSS 变量。
- **三主题定位**(填色基准):**经典 = 抄 Claude 官网亮色盘**(暖奶油色阶 + 暖橙 primary `#cc785c`**浅色 = 抄 ChatGPT 亮色盘**(冷白 + 中性灰 + 近黑 primary `#181818`**深色 = 自研中性灰阶**(浅灰/深灰/黑,不硬凑暖调)。
- **两层结构**token 定义在 `static/src/styles/base/_tokens.scss`,分原始层 + 语义层;组件只引用**中性语义名**`--surface-*` / `--text-*` / `--border-*` / `--accent*` / `--state-*` 等)。`--claude-*` / `--theme-*` 是**过时兼容别名**,迁移完成后会删,新代码不要用。
- **表面层次**(经典):画布 `--surface-base` `#faf9f5` < 侧栏 `--surface-soft` `#f5f0e8` < 卡片 `--surface-card` `#efe9de` < 嵌套 `--surface-muted` `#e8e0d2` < 纯白浮起 `--surface-raised`亮色主题不许把所有表面塌成同一个白必须靠暖/冷灰阶拉开层次
- **强调色克制**primary`--accent` "CTA-only voltage"只点在主按钮/logo 等极少数处hover / 选中 / 运行态一律走中性灰跟各自主题表面色不抢镜
- **派生色**需要半透明 tint 时用 `color-mix(in srgb, var(--token) N%, transparent)` 从语义 token 派生不写死 rgba
- **新增颜色**必须在 classic / light / dark 三套主题及首屏回退 `:root:not([data-theme])`与经典同值都补齐
- **防回退栏杆**`.stylelintrc.cjs` `color-no-hex` / `declaration-property-value-disallowed-list` / `media-feature-name-disallowed-list` 三条规则拦截违规`build` 脚本含 `stylelint` 步骤会拦下裸色存量未清理文件在 `BASELINE_EXEMPT` 临时豁免清理一个移除一个不再回退切换逻辑见 `static/src/utils/theme.ts`
7. **带文字容器固定高度**所有含内部文字的选项 / 按钮 / 标签 / 容器必须固定高度禁止因文字多少被撑大撑高文字过长用省略号或内部滚动处理保持行高与块高稳定
8. **窗口设最大尺寸 + 内部滚动**所有弹窗 / 面板 / 列表必须设置 `max-height` / `max-width`超出时由内部容器滚动而不是把整个窗口顶大滚动条要么隐藏要么做样式适配贴合整体设计不暴露原生粗滚动条)。
9. **实体面板禁止半透明**所有实体 UI 容器对话区侧栏下拉/二级菜单抽屉对话框本体状态条tooltip 气泡输入栏等背景必须**不透明**且不加 `backdrop-filter` 磨砂背景一旦不透明磨砂就失去意义必须移除。**唯一例外**是遮罩层弹窗背后压暗的 scrim `--overlay-scrim``position:fixed;inset:0`和刻意的玻璃质感装饰这类保留半透明
## Security Considerations
- 所有用户操作在独立容器中执行与宿主机隔离
- 文件操作路径验证在 `FileManager._validate_path`
- 上传文件经过 `UploadQuarantineManager` 隔离和扫描
- CSRF 保护在 Web 端启用
- 登录失败次数限制和临时锁定
## Known Limitations
- 代码大量由 AI 生成未达到生产级别
- 容器资源配额依赖 Docker cgroups
- 前端处于改造中部分功能可能不稳定
- Token 统计基于 tiktoken可能与实际 API 有偏差
## Directory Structure
```
agents/
├── server/ # Flask 业务主线chat/task/goal/monitor/auth ...
├── core/ # 核心终端与工具编排main_terminal_parts/*
├── modules/ # 独立功能模块
├── utils/ # 辅助工具(含 log_rotation 日志轮转)
├── config/ # 配置拆分api/limits/terminal/paths ...,由 __init__ 聚合)
├── static/ # Vue 3 + TS Web 前端
├── cli/ # React + Ink CLI 前端(重写中)
├── modules/sub_agent/ # 子智能体执行逻辑(主进程内协程)
├── easyagent/ # 旧版 Node.js 子智能体实现,暂时保留但已不再使用
├── docker/ # 容器镜像
├── prompts/ # 系统提示词
├── scripts/ # 运维脚本(数据迁移 migrate_runtime_data.py 等)
├── android-webview-app/ # Android WebView 客户端工程
├── test/ # 测试用例
├── docs/ / doc/ # 设计与发布文档
└── _experiments/ # 本地实验残留与历史文档归档gitignored不进仓库
运行态数据(不在源码树):
~/.agents/agents/ # 数据根目录(可通过 AGENTS_DATA_ROOT 覆盖)
├── settings.json # 唯一配置文件
├── config/ # 部署级配置host/web 共享)
├── host/ # mode = host由 TERMINAL_SANDBOX_MODE 决定
│ ├── data/ # 对话、用户库、记忆、sub_agent_tasks运行态
│ └── logs/ # 日志文件
└── web/ # mode = web/docker
├── data/ # 对话、用户库、记忆、sub_agent_tasks运行态
├── users/ # web 多用户工作区
├── api/users/ # API 用户工作区
└── logs/ # 日志文件
```
> 历史说明:`data/`、`users/`、`logs/`、`project/` 等过去曾在源码树内,现已默认迁至 `~/.agents/agents/<mode>/`。详见 Configuration 节「数据目录与路径变量」。
## Development Tips
- 修改系统提示词编辑 `prompts/main_system.txt`
- 调整工具限制修改 `config/limits.py`
- 容器镜像定制编辑 `docker/terminal.Dockerfile` 并重新构建
- 前端开发在项目根目录运行 `npm install && npm run dev`build watch
- 查看详细执行流程监控 `logs/debug_stream.log`
## Permission Mode & Sandbox Execution (2026-05)
完整说明文档`docs/host_sandbox_and_permission_model.md`
系统有两套独立但叠加的控制
### 权限模式 (Permission Mode)
- `readonly` - `run_command` 在只读沙箱执行`write_file`/`edit_file` 等写入类工具直接拒绝
- `approval` - `run_command` 先走只读沙箱权限拒绝 `Operation not permitted`/`Permission denied`时触发前端审批通过后仅该次命令以可写沙箱重试
- `auto_approval` - 工作区内写入直接执行工作区外写入进入审批`run_command` 权限拒绝由后台审批智能体自动审核
- `unrestricted` - 不做权限模式拦截是否沙箱由执行环境决定
### 执行环境 (Execution Mode)
- `sandbox`默认- OS 沙箱执行macOS: `sandbox-exec`Linux: `bwrap + seccomp`Windows: `WSL2`支持会话级 TTL 自动回退 `direct -> sandbox`
- `direct` - 宿主机直接执行高风险仅建议短时使用
### 路径授权语义
- 前端路径授权分可读可写仅可读」:可读集合 = 可读可写 + 仅可读可写集合 = 可读可写
### 自动审批智能体
- 配置文件`config/auto_approval.json``name`/`url`/`key`/`model`/`extra_params` `timeout_seconds`/`max_rounds`/`max_command_timeout`
- 调试开关`modules/approval_agent.py` `DEBUG_SAVE_APPROVAL_AGENT_TRANSCRIPT`开启后写入 `logs/approval_agent/`
## Android Release Notes (Required for frontend update)
当改动前端并准备发 Android WebView 壳版本时必须同步完成
1. 更新版本号`android-webview-app/app/build.gradle.kts`
- `versionCode` 递增
- `versionName` 更新
2. 更新版本说明`android-webview-app/APP_CHANGELOG.md`
- 新版本条目写在顶部
3. 修改完成后提醒用户运行上传脚本
- `bash /Users/jojo/Desktop/agents/正在修复中/agents/upload_android_apk.sh`
参考文档`doc/android_app_release_and_update.md`