Files
codex-app-server/docs/project-tree.md
host ce7fb3afd6 feat: project directory tree + first-round snapshot
- 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
2026-10-30 14:46:11 +08:00

57 lines
2.8 KiB
Markdown
Raw Permalink 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.
# 项目目录树(完整版)
问题:任务内 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/<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` 翻译)。