# 项目目录树(完整版) 问题:任务内 agent 本来就能用 shell `ls/find` 看 worktree, 但每次都要自己探路(费轮次/token),大项目噪音大、输出 是纯文本;任务外的 LLM(编辑器、协调方)只能用 `get_task_files` 一层一层列/读,没有“一眼看结构”的入口。 本批补三处,共用 `cloud/tree.py`,不改 codex 本体: ## 1. 结构化目录树工具 - REST:`GET /tasks/{id}/tree?path=&max_depth=&max_entries=` - 权限与 worktree 解析与 `/files` 同款:viewer+ 可读; cloud 任务与跨机 worktree 一律 409,解析不到 404。 - `max_depth` 1..5(缺省 3),`max_entries` 1..500 (缺省 200),非法整数 400,不静默回落。 - 只含名、类型(dir/file/symlink)、大小,不读文件内容。 - MCP:`get_task_tree`(cloud/mcp_server.py),参数同上, 直译为上述 REST 调用,服务端错误原样透传为 isError。 ## 2. 首轮注入顶层结构 worker 在 `run_one` 里 `_apply_project_repo` 之后调 `_apply_tree_injection`:只改内存副本,原 prompt/goal 不落库;goal 任务同时改内存里的 goal。 时序诚实点(不要把这条改回“worktree 快照”): 认领时任务 worktree 还没建出来(派发时 host.py 才按检出 建 worktree),所以注入贴的是**仓库检出顶层快照**, worktree 正是由它建出;注入文本里明写这一点,附件 seed 与 agent 新建文件不在快照内。来源只认宿主上已存在 的目录:非租户/环境任务用 `task["repo"]`,租户任务用 `tenants_root//` 检出,repo_url 为空的租户 任务用 `_tenant_dirs` 的 test_repo;都找不到时静默跳过, 绝不炸掉认领。 跳过:协调员任务、续跑与断点续跑、分支任务 (`forked_from`:其 worktree 来自分支,不是检出快照)。 上限:2 层、120 条(`tree.INJECTION_*`),深层用 shell 或 `get_task_tree` 再查;空目录不贴空章节。 ## 3. 安全与截断规则(tree.py) - 相对路径 only:绝对路径、`..` 逃逸、符号链接逃逸 一律拒绝;目录内的符号链接列为 symlink、不跟进。 - `.git` 永远不列;默认还忽略 `node_modules`、 `__pycache__`、`.venv`、`venv` 等。`.gitignore` 不解析。 - 遍历顺序确定(目录在前、同类按名排序),条数到顶 置 `truncated=True`;被 `max_depth` 或条数截断的目录 `children_truncated=True`,与空目录(`children=[]` 且 `children_truncated=False`)可区分。 单测:`cloud/tests/test_tree.py`(结构/忽略/链接/截断/ 渲染)、`test_server_task_tree.py`(端点/权限/错误码)、 `test_worker_tree_injection.py`(注入/跳过/内存副本)、 `test_mcp_server.py`(`get_task_tree` 翻译)。