agent-Specialization/CLAUDE.md
JOJO f31f8d6fd7 feat(host): host 模式同时加载 host/ 和 web/ 用户数据
- paths.py: 新增 IS_HOST_MODE / WEB_DATA_DIR / WEB_USER_SPACE_DIR
- user_manager.py: host 模式合并两处用户列表与工作区
- 已有 web 工作区直接复用,新数据写入 host/
- 更新 AGENTS.md / CLAUDE.md 文档
2026-06-16 22:39:32 +08:00

21 KiB
Raw Blame History

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 以 REST 任务轮询为主Socket.IO 用于兼容与实时辅助通道)

  • app.py / app_legacy.py - Web 服务入口与遗留实现
  • chat.py / chat_flow*.py - 对话与任务流编排runner / tool_loop / stream_loop / task_main 等拆分)
  • goal_flow.py - 自主目标循环
  • deep_compression.py - 上下文深度压缩
  • tasks.py / monitor.py / conversation.py / files.py / auth.py / admin.py - 任务、监控、对话、文件、认证、管理接口

core/

  • MainTerminal (main_terminal.py) - CLI 主终端,处理用户输入和 AI 对话循环;逻辑拆分到 core/main_terminal_parts/*commands / context / tools / 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 - 管理多个持久化终端会话
  • file_manager.py - 文件 CRUD包含搜索、替换和 append/modify streaming 功能
  • conversation_manager.py - 对话历史持久化
  • context_manager.py - 上下文构建、token统计、对话管理
  • memory_manager.py - 长期记忆管理
  • todo_manager.py - 待办事项管理
  • sub_agent_manager.py - 子智能体任务调度
  • user_manager.py - 用户认证和工作区管理
  • upload_security.py - 上传文件隔离扫描

utils/

  • api_client.py - 与 OpenAI-compatible API 交互,支持 thinking mode首次思考后续快速
  • 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.tsxcli/src/components.tsxcli/src/eventMapper.tscli/src/api.ts

docker/

  • terminal.Dockerfile - 终端容器镜像构建配置

Development Commands

Build & Run

# === 开箱即用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)

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)

npm --prefix cli install
# 开发启动
npm run cli            # 或 npm --prefix cli run dev
# 构建
npm run cli:build
# 类型检查
npm run cli:typecheck
# 可执行命令名构建后agents / agents-cli

Testing

# 主要离线冒烟用例unittest
python -m unittest test.test_server_refactor_smoke

# 改动后端接口适配(如 server/chat.py时补充
python3 -m py_compile server/chat.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

# 查看容器状态
docker ps -a | grep agent-term

# 查看调试日志(运行态日志默认在 ~/.agents/<mode>/logs/
tail -f ~/.agents/host/logs/debug_stream.log   # host 模式
tail -f ~/.agents/web/logs/debug_stream.log    # web/docker 模式

# 查看容器统计
tail -f ~/.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.py2026-06 更新):

运行态数据默认存放在 ~/.agents/<mode>(对齐 ~/.claude~/.codex不落在源码树。模式由 TERMINAL_SANDBOX_MODE 决定:host~/.agents/host,其它(默认 docker/web~/.agents/web。每个模式根下含 data/对话、用户库、记忆、sub_agents.json、sub_agent_tasksusers/api/users/logs/

路径解析优先级(高→低):

  1. 具体目录变量 DATA_DIR / LOGS_DIR / USER_SPACE_DIR / API_USER_SPACE_DIR(单独覆盖某目录)
  2. 模式根变量 AGENTS_HOST_HOME / AGENTS_WEB_HOME(整体搬迁该模式数据)
  3. 兜底 ~/.agents/<mode>

Host / Web 双路径机制2026-06:

  • paths.py 新增 IS_HOST_MODEWEB_DATA_DIRWEB_USER_SPACE_DIR 三个固定变量
  • host 模式下 UserManager 同时加载 host/web/ 的用户与工作区web 用户不覆盖已有)
  • 已有 web 工作区直接复用(保持旧数据可访问),新工作区写入 host/
  • web 模式:仅读取 web/ 数据,无变化

config/*.json 分两类:程序能力docker_risk_markers.jsonskill_hints.json)与 prompts/agentskills/ 一样锚定源码树;部署级配置custom_modelshost_workspacesauto_approvalgoal_reviewforbidden_commandshost_sandbox_policy)外置到 ~/.agents/<mode>/config/DEPLOY_CONFIG_DIR),读取走 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/<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.tsxcli/src/components.tsxcli/src/eventMapper.tscli/src/api.ts 内做最小闭环修改。
  • 涉及 monitor 动画/事件联动时,至少同步检查 MonitorDirector.tsstores/monitor.ts
  • 前端不强制本地构建:沙箱环境无法成功执行 npm run build / npm run cli:build,因此改完前端不必每次都跑构建验证。改动后用类型检查(npm run lint / npm --prefix cli run typecheck)或人工 review 自查即可,构建交由用户在本机或 CI 完成。

Working with Containers

使用 ContainerHandle:

# 文件操作
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

# 创建新对话
terminal.create_new_conversation(thinking_mode=True)

# 加载对话
terminal.load_conversation(conversation_id)

# 搜索对话
terminal.search_conversations(query="bug fix")

# 删除对话
terminal.delete_conversation(conversation_id)

前端设计风格统一规范(强制)

适用范围:所有前端 UIstatic/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.cjscolor-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-scrimposition: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 前端(重写中)
├── easyagent/         # 子智能体执行逻辑(旧版 sub_agent/ 已删除)
├── docker/            # 容器镜像
├── prompts/           # 系统提示词
├── scripts/           # 运维脚本(数据迁移 migrate_runtime_data.py 等)
├── android-webview-app/ # Android WebView 客户端工程
├── test/              # 测试用例
├── docs/ / doc/       # 设计与发布文档
└── _experiments/      # 本地实验残留与历史文档归档gitignored不进仓库

运行态数据(不在源码树):
~/.agents/<mode>/      # mode = host 或 web由 TERMINAL_SANDBOX_MODE 决定
├── data/              # 对话、用户库、记忆、sub_agent_tasks运行态
├── users/             # web 多用户工作区
├── api/users/         # API 用户工作区
└── logs/              # 日志文件

历史说明:data/users/logs/project/ 等过去曾在源码树内,现已默认迁至 ~/.agents/<mode>/。详见 Configuration 节「数据目录与路径变量」。

Development Tips

  • 修改系统提示词:编辑 prompts/main_system.txt
  • 调整工具限制:修改 config/limits.py
  • 容器镜像定制:编辑 docker/terminal.Dockerfile 并重新构建
  • 前端开发:在项目根目录运行 npm install && npm run devbuild 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-execLinux: bwrap + seccompWindows: WSL2),支持会话级 TTL 自动回退 direct -> sandbox
  • direct - 宿主机直接执行(高风险,仅建议短时使用)

路径授权语义

  • 前端路径授权分「可读可写」与「仅可读」:可读集合 = 可读可写 + 仅可读,可写集合 = 可读可写

自动审批智能体

  • 配置文件:config/auto_approval.jsonname/url/key/model/extra_params,及 timeout_seconds/max_rounds/max_command_timeout
  • 调试开关:modules/approval_agent.pyDEBUG_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