- cloud/tree.py: structured worktree tree (dirs first, ignore
.git/node_modules, symlinks not followed, entry/depth
truncation flags, text render for injection)
- GET /tasks/{id}/tree with /files auth + worktree resolution,
max_depth 1..5, max_entries 1..500, escape 400, missing 404,
cloud/cross-host 409
- MCP get_task_tree translating to the new endpoint
- worker first-round injection of a repo-checkout top-level
snapshot (2 layers, 120 entries) after repo resolution,
labelled as checkout snapshot not worktree; skipped for
coordinator/resume/fork, silent when no host source
- docs/project-tree.md; tests for tree, endpoint, injection,
MCP translation
2.8 KiB
项目目录树(完整版)
问题:任务内 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_depth1..5(缺省 3),max_entries1..500 (缺省 200),非法整数 400,不静默回落。- 只含名、类型(dir/file/symlink)、大小,不读文件内容。
- 权限与 worktree 解析与
- 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/<safe>/<safe> 检出,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 翻译)。