Trellis 教程
Trellis 相对与 superpowers是一个比较重的框架特别适合于团队开发特定项目(支持定义自己的spec)。科研的代码我感觉暂时不用等 Trellis 先发展一下Claude Code 下Trellis 的两个基础机制是会话开始时由SessionStartHook 自动触发session-start.pysession-start.py还会把start.md写进additionalContext并明确告诉 agent前面上下文已注入从 Step 4 开始等用户第一条消息若有活跃任务则先问是否继续。从任务数据结构看Trellis 的底层不是“全靠记忆”而是靠.trellis/tasks/下的任务目录和jsonl文件驱动。标准任务生命周期是create → init-context → add-context → start → implement/check → finish → archive其中implement.jsonl给 implement 用check.jsonl给 check 用debug.jsonl给 debug 用.trellis/.current-task则是当前任务指针Hook 会据此自动注入上下文。(Trellis 文档)1)会话刚开始时发生什么Hook 会在新会话开始时自动跑session-start.py。session-start.py会把 workflow、guidelines、spec 索引和start.md拼进additionalContext作为给 agent 的上下文。接下来有两种工作模式可以选择/start和/parallel(从这里其实可以看出来这里的设计并不是很精细因为start.md一定会被注入上下文但是其已经是一个完整的工作流了而parallel.md也是一个完整的工作流)。如果选择/start那么是不用手动运行/start的因为前面已经注入了start.md了如果选择/parallel才需要手动运行。2)/start的完整工作流start.md的作用是把开发会话拉到 Trellis 的标准单进程(同一时间只有一个 agent 在运行)串行路径上。它会读取workflow.md、运行get-context.py取回身份 / Git 状态 / 活跃任务 / 历史对话元信息、读取 spec 索引然后向用户汇报上下文并问“What would you like to work on?”。然后它会先做任务分类。当前start.md明确分成四类Question、Trivial Fix、Simple Task、Complex Task。其中 Question 是答疑Trivial Fix 是错字、注释或单行之类的小改动Simple Task 是目标清晰、范围小、1–2 个文件内的问题Complex Task 是目标模糊、涉及多个文件或架构判断的问题。对于Question / Trivial FixTrellis 允许直接处理不必先走完整任务化流程但如果在这个过程中真的改了代码start.md明确要求提醒用户运行/trellis:finish-work。这一点只适用于这两个分支不是整个/start流程结束时的统一提示。对于Simple Task流程是先做一次快速确认确认目标、开发类型和约束然后创建 task 目录写prd.md再进入共享工作流。start.md还特别强调Research 必须在需求清楚、PRD 已存在之后再做。如果变更触及跨层契约、数据库、API 签名或 infra 约束还要先过一遍 code-spec depth check再进入实现。(GitHub)对于Complex Task不会直接实现而是先进入/trellis:brainstorm。brainstorm 的步骤是先建 task再 seed 初始 PRD然后做 Auto-Context优先自己从 repo / docs / config 中拿能拿到的信息实在有不确定的并且无法自己获取的信息对用户进行提问一次只问一个高价值问题避免一条消息里堆一串问题每次用户回答后都要立即更新 PRD最后做一次结构化最终确认用户确认后才并入共享的任务工作流无论是 Simple Task 还是 Complex Task最终都会汇入同一条标准 Task Workflow研究代码库、配置jsonl上下文、激活任务、调用 implement agent、再调用 check agent最后进入 complete。start.md的 Complete 步骤要求的是确认 lint/typecheck 通过、汇报实现内容、提醒用户测试变更、准备好后 commit并运行/trellis:record-session记录本次会话。这里不会显式提醒用户再跑一次/trellis:finish-work/finish-work在命令参考中被定义为提交前的收尾检查命令而不是/start完成步骤里的标准提示项。所以记住在提交之前跑一次/finish-work/trellis:record-session本身也是一个独立收尾动作。文档写得很清楚它通常在用户已经测试并 commit 之后使用底层会追加会话记录到 journal(历史对话)必要时滚动新日志文件并更新 workspace 的index.md。换句话说/start负责把任务做完会话沉淀由/record-session单独负责。在开启一个新对话的时候历史对话的元信息会被注入到上下文中至于是否读取具体的历史记录由 agent 自己决定3)/trellis:parallel的完整工作流/trellis:parallel是Claude Code 专属的多 agent 并行编排入口适用于复杂度高、预计超过 30 分钟、可以拆成独立子任务、并且需要在独立 worktree 中隔离开发的情况。多会话文档和命令文档都把它定义成worktree / multi-session模式每个任务一个 worktree、一个 Claude Code 会话、一个分支各会话独立运行。这个命令启动后先读取当前上下文和项目规范然后向用户确认三件事要开发什么 feature、涉及哪些模块、开发类型是 backend / frontend / fullstack。确认后再根据复杂度分流复杂需求走Plan Agent简单而清晰的需求走Manual Configuration。走Plan Agent时Plan 会先做需求合理性判断不清晰、过大、不合理或有风险的需求可以被直接拒绝。若接受则 Plan 会调用 Research Agent 分析代码库创建并配置 task 目录写prd.md产出task.json / prd.md / implement.jsonl / check.jsonl / debug.jsonl然后把这个 task 交给multi_agent/start.py去启动 worktree 会话。走Manual Configuration时主 orchestrator 自己做这些准备创建 task 目录、init-context、设置 branch 和 scope、按需添加上下文、写prd.md、validate最后调用multi_agent/start.py $TASK_DIR启动 worktree 会话。也就是说简单且边界清晰的任务不一定非得先过 Plan Agent。每个 worktree 会话都有自己的 dispatch agent。Dispatch 是 worktree 里的纯调度器。它自己不读 specs 或 requirements不负责复杂分析只负责读取.trellis/.current-task指向的 task 目录、读取其中task.json的next_action数组然后按 phase 顺序调用子 agent 或脚本。注意dispatch.md中的Phase Handling只是“各 action 的处理方式说明”不是“每次必须把所有 action 都跑一遍”。是否执行某个阶段取决于next_action写了什么。也就是说执行的阶段(phase)取决于next_action一般来说dispatch 通常会按这个顺序推进implement → check → finish → create-pr。这里最容易误解的是finish它是再次调用check agent只是 prompt 带[finish]标记。debug虽然和 implement/check 一样都是 dispatch 可调用的并列 subagent但它不是默认主线里的固定阶段。dispatch.md的错误处理写得很明确如果某个 subagent 失败而 dispatch 认为问题可恢复就调用 debug agent 去修如果不可恢复再通知用户并请求指导。因此debug 的定位是异常恢复 / 定向修复通道。Implement、Check、Debug 三者的职责也已经比较明确Implement 会先读 PRD / 技术设计 / 自动注入的 specs再实现功能并至少运行项目的 lint 和 typecheck 做验证Check 先看git diff再按 specs 审查目录、命名、类型、潜在 bug并且必须 self-fix(修复代码)不是只报问题Debug 则是针对已知错误或 issue 描述做精确修复避免顺手做无关重构在 dispatch agent 的最后阶段会创造草稿 pr create-pr阶段是真正的 GitHub PR 创建。Dispatch 和create_pr.py都明确写了这一步会stage 并 commit 改动、push 到 origin、再用gh pr create --draft直接创建 Draft PR同时把task.json更新到 review 状态并写入pr_url。而且这是整个并行流水线里唯一允许执行 git commit的动作。由于要创造pr我们需要将仓库绑定到一个Github远程仓库PR 创建之后人的职责就比较简单了去 GitHub 上 review没问题就 merge然后回到本地主仓把目标分支拉到最新再清理这个任务的 worktree。多会话文档给出的口径是cleanup.py会删除 worktree但保留分支合并后的分支再按正常 Git 流程删除。不过这里有一个实现细节差异文档页写的是“cleanup 删除 worktree 但保留分支”但当前仓库里的cleanup.py实现实际上是清理时会归档 task、移除 registry、删除 worktree并且默认还会删除本地 branch只有加--keep-branch时才保留分支。脚本的帮助信息和实现都写了这一点所以如果你按“当前仓库实现”来跑应以脚本行为为准。注意最后还有一步什么task.py finish和task.py archive可以区分一下之后第一步trellis init的选项可以。先把范围说清楚如果严格按我上一条的“第一步”定义也就是init(options)刚进入后、还没开始真正创建.trellis/和平台目录之前那一段里“已经会立刻影响执行路径”的选项主要是下面这些。源码对应位置在init.ts开头先设置写入模式再处理开发者名再解析 registry、template strategy最后进入 monorepo 检测。(GitHub)1.-f/--force这个是第一步里最直接生效的。源码里options.force会把writeMode设成force然后调用setWriteMode(writeMode)含义就是后续 Trellis 写管理文件时遇到已有文件按“强制覆盖”策略走。文档 FAQ 也把它说明成“强制覆盖已有文件”。(GitHub)2.-s/--skipExisting这也是第一步立即生效的。源码里如果没有force、但有skipExisting就把writeMode设成skip表示后续遇到已存在文件时跳过。文档 FAQ 对应写的是“跳过已有文件”。而且它和--force是if / else if关系所以两者同时给时源码优先走force。(GitHub)3.-u/--user这是你例子里实际传入的那个。源码先执行let developerName options.user也就是说只要你传了-u user_name它就直接采用这个名字不再依赖git config user.name。文档也明确说了-u用来设置开发者身份并创建.trellis/workspace/{username}/。(GitHub)4.-y/--yes这个在第一步的作用不是“立刻创建文件”而是抑制交互。源码里当没有拿到developerName时只有在!options.yes的情况下才会提示Your name:另外后面的 monorepo 决策里options.yes也会直接接受默认选择。FAQ 里对应说明是“跳过确认使用默认配置”。(GitHub)5.--registry这个也属于前置生效选项。源码在项目类型探测后立即解析options.registry如果 registry 地址非法会直接报错并return后面初始化不继续。也就是说它在很早阶段就能改变执行路径甚至提前终止。文档里把它定义为“从自定义仓库拉取 spec 模板”。(GitHub)6.--overwrite/--append这两个不是全局写文件策略而是模板写入策略。源码会先把templateStrategy默认设成skip如果给了--overwrite就改成overwrite给了--append就改成append。这个策略随后会用于远程 spec/template 下载和落盘。文档里也写得很直接--overwrite是“模板时覆盖已有 spec”--append是“只补充缺失文件”。(GitHub)7.--monorepo/--no-monorepo这也是在前段就开始影响逻辑的。源码是if (options.monorepo ! false)才会进入自动检测注释里明确写了true --monorepofalse --no-monorepoundefined auto。如果你强制指定--monorepo但当前仓库没检测到 monorepo 配置程序会直接报错退出。最近更新日志也写到trellis init会自动检测 pnpm/npm/Cargo/Go/uv workspaces 和 git submodules。(GitHub)有些选项不是我说的“第一步”就生效而是稍后阶段才生效8. 平台 flags--claude、--cursor、--iflow、--opencode、--codex、--kilo、--kiro、--gemini、--antigravity、--windsurf、--qoder、--codebuddy、--copilot这些参数确实属于init的合法选项InitOptions接口里也列出来了文档和 README 也都列了平台选项。但它们主要影响的是后面的“平台配置阶段”决定是否生成.claude/、.cursor/、.agents/skills/、.kilocode/、.kiro/等平台目录不是最前面那段写入模式/开发者识别逻辑。(GitHub)9.-t/--template这个也是init的正式参数文档里示例是trellis init -t electron-fullstack。但它的效果主要体现在后续模板选择/下载阶段有没有预选模板、是否跳过某些交互而不是我上一条里定义的“第一步”核心逻辑。源码接口里有template?: string。(GitHub)所以如果只问“第一步里最关键、最早就会改执行路径的选项”可以压缩成这张表-f全局强制覆盖-s全局跳过已有文件-u直接指定 developer name-y跳过交互确认--registry提前决定模板源非法会直接中止--overwrite/--append提前决定模板落盘策略--monorepo/--no-monorepo提前决定 monorepo 检测路径 (GitHub)而你给的这条trellis init -u user_name在“第一步”里真正触发的核心效果只有两个一是把developerName直接设成user_name二是因为你没有给-f/-s/-y所以写入模式保持默认ask交互也保持开启。也就是说后面如果遇到平台选择、模板选择、monorepo 确认仍然可能会问你。(GitHub)下一条我可以继续把这个拆成“只针对trellis init -u user_name这一条命令按源码逐行走一遍最前 50~100 行执行流”。Q已有文件指的是哪些文件是否强制覆盖有什么区别吗monirepo是什么有什么用-t 和 registry的关系是什么A可以分开说。1)“已有文件”具体指哪些--force和不强制覆盖有什么区别在init里--force和--skipExisting先被转换成全局writeMode默认是ask--force变成force--skipExisting变成skip。而真正写文件时writeFile()的规则是文件不存在就直接写文件已存在但内容完全相同就静默跳过内容不同则按模式处理——force覆盖skip跳过append追加ask则弹交互让你逐个选“跳过 / 覆盖 / 追加 / 对后续全部生效”。(GitHub)所以这里的“已有文件”更准确地说是所有通过writeFile()落盘且目标路径已经存在、并且内容不同的文件。从createWorkflowStructure()可以确认至少这些核心文件受这个机制控制.trellis/scripts/、.trellis/workflow.md、.trellis/.gitignore、.trellis/config.yaml、.trellis/workspace/index.md、.trellis/worktree.yaml以及.trellis/spec/里的 guides / frontend / backend 模板文件。(GitHub)再往外一层看Trellis 初始化本来就主要生成Trellis 自己的结构文件和平台接入文件例如.trellis/、.claude/、.cursor/、AGENTS.md、.agents/、.kilocode/、.kiro/等而不是去改你的业务源码目录。也就是说--force的覆盖对象通常是这些 Trellis 管理的文件。(GitHub)但有一个边界要注意并不是init里的所有写入都走writeFile()。例如 bootstrap 任务00-bootstrap-guidelines是直接用fs.writeFileSync()写task.json、prd.md和.current-task而且如果这个任务目录已经存在源码会直接return true不会重写它。所以--force不是“无脑覆盖 init 过程中的一切文件”它首先保证的是writeFile()那一类写入。(GitHub)把差异压缩成一句话不加--force默认是ask遇到冲突会逐个问你怎么处理。(GitHub)加--force遇到受writeFile()管理且内容不同的已有文件直接覆盖不再逐个确认。(GitHub)还要再区分一个容易混的点--force是全局文件写入模式而--overwrite/--append是远程 spec 模板下载时对.trellis/spec冲突目录的策略。源码里templateStrategy是单独算的如果.trellis/spec已存在且你没给--overwrite/--append它会额外问你是skip / overwrite / append。(GitHub)7)monorepo 是什么有什么用放在 Trellis 这个上下文里monorepo可以理解成一个 Git 仓库里包含多个 package / app / service / workspace。Trellis 当前会把 pnpm/npm/Cargo/Go/uv workspaces 和 git submodules 这类多包结构识别成 monorepo 候选。(GitHub)它的用处在 Trellis 里不是抽象概念而是非常具体的三件事第一按包拆 spec。开启 monorepo 模式后Trellis 不再只生成单一的.trellis/spec/frontend、.trellis/spec/backend而是给每个包生成自己的spec/package/...目录源码里就是循环packages对每个包写spec/name/。文档更新也明确写了trellis init会生成“按包划分的 spec 目录”。(GitHub)第二把包信息写进.trellis/config.yaml。writeMonorepoConfig()会把自动探测出的包写成packages:列表并选一个default_package:。这样后续 Trellis 的任务、上下文注入、脚本调用就知道“当前到底是在操作哪个包”。(GitHub)第三让后续脚本和上下文按包工作。Trellis 的 changelog 里已经把这层支持写出来了session-start 支持spec_scope过滤task.py和add_session.py支持--package动态 spec 发现也支持 monorepo 的路径结构例如spec/cli/backend/。这意味着 AI 注入上下文时不必把整个大仓所有规范一股脑塞进去而是可以更精确地只读当前包相关的规范。(Trellis Docs)所以monorepo 的核心价值就是你仓库里有多个子系统时Trellis 能把“规范、任务、上下文”从“整个仓库一锅端”变成“按 package 精确路由”。对于前后端同仓、多 app、多 service、带 submodule 的项目这会明显减少上下文污染。这个判断是我根据 Trellis 生成packages配置、按包建 spec、以及按包过滤上下文这几处实现综合得出的。(GitHub)9)-t和--registry的关系是什么这两个参数不是替代关系而是“源”和“目标”的关系--registry指定去哪里找模板。文档写得很明确它是“从任意 Git 仓库拉取 spec 模板”Trellis 会先判断这个仓库是 Marketplace 模式还是直接下载模式。(Trellis Docs)-t/--template指定在这个模板源里选哪一个模板 ID。源码里单仓/多仓下载都把options.template传给downloadTemplateById(...)在 monorepo 下--template还会作为“所有 package 的默认模板”。(GitHub)具体关系是这样的情况 A只写-t不写--registry那-t默认就是从 Trellis 的默认模板源里选一个模板 ID。源码里selectedTemplate最终会触发 “download specific template by ID” 这条路径。(GitHub)情况 B只写--registry不写-t这时 Trellis 先看这个 registry 是哪种模式如果仓库里有marketplace/index.json就是Marketplace 模式会读取模板列表并让你交互选择如果没有index.json就是直接下载模式把整个marketplace/specs/当成一个模板直接下。(Trellis Docs)情况 C--registry和-t一起写这是最明确、最稳定的组合--registry指定模板仓库-t指定这个仓库里的模板 ID。对于有多个模板的 marketplace registry这基本就是“从某个模板仓里精确点名下载哪一个”。源码里downloadTemplateById(..., options.template, ..., registry, ...)正是这么传参的。(GitHub)还有一个源码层面的细节很重要在-y模式下如果你给了--registry但没给-t而该 registry 又是一个包含多个模板的 marketplaceCLI 会直接报错因为它无法自动猜该选哪个模板报错文本就写着“Use --template to specify which one, or remove -y for interactive selection.”。( GitHub)所以你可以把它记成一句话--registry 模板仓库地址-t 该仓库中的模板 ID。没有--registry时-t用默认模板源有--registry时-t就是在那个 registry 里选具体模板。(Trellis Docs)如果你愿意我下一条可以继续把这三个参数组装成几条最容易踩坑的命令示例比如单仓、monorepo、自定义 registry、覆盖策略各怎么写。所以如果识别到了monorepo最好就是启用monorepo吗通常是但不是“只要识别到就一定要开”。我的工程判断是如果 Trellis 检测出的那些 package确实是你会分别开发、分别维护、甚至规范都不同的子系统那就应该启用 monorepo mode。启用后它会按包生成spec/name/并把packages和default_package写进config.yaml后续脚本也支持按 package 过滤上下文所以 AI 读到的规范会更精确不容易把 A 包的约定带到 B 包。(Trellis Docs)不建议开的情况也很明确如果它只是“形式上是 workspace / submodule”但你实际把整个仓库当成一个应用来开发目录规范、编码约定、任务边界都基本统一那不开反而更省事。不开时 Trellis 会走单仓模式只生成全局.trellis/spec/维护成本更低。(GitHub)你可以用一个很实用的判断标准如果你平时会自然地说出这些话就该开“web 和 api 的规范不一样。”“这个包是 library那个包是 service。”“不同包需要不同上下文不想让 AI 混读。”如果你更常说的是“这其实就是一个项目只是用 pnpm workspace 管依赖。”那就没必要开。这个结论是根据 Trellis 的实现推出来的因为它在检测到 monorepo 后会专门列出包并询问Enable monorepo mode?默认值还是true说明作者倾向于“真 monorepo 就启用”但仍然把最终决定留给你。(GitHub)所以我给你的结论是识别到 monorepo 时默认应当先倾向于启用但前提是这些 package 对你来说真的是“独立边界”而不是仅仅共享一个 workspace 外壳。如果你愿意我可以下一条直接给你一个“哪些仓库应该开 / 不该开”的具体判断清单按前端 monorepo、后端多服务、子模块仓库三类来讲。那么--registry指定了远程模板的url之后对这个远程模板有什么格式要求吗有。要分成两层看一层是--registry这个值本身的 URL/源格式要求另一层是远程仓库内部模板的目录与索引格式要求。当前 Trellis 文档把--registry定义为从自定义 Git 仓库拉取 spec 模板官方支持 GitHub、GitLab、Bitbucket源码里还进一步表明它能解析 public HTTPS、public SSH、self-hosted HTTPS/SSH、带端口的地址以及带分支/子目录的 browse URL。默认分支是main而且至少要能解析出user/repo这一级。(Trellis Docs)1.--registry的地址支持什么格式源码支持的输入形式比文档写得更宽一些核心包括这些gh:org/repo、gitlab:org/repo#ref这类 giget 风格https://github.com/org/repogitgithub.com:org/repohttps://gitlab.example.com/org/repogitgitlab.example.com:org/repossh://githost:2222/org/repohttps://host/org/repo/-/tree/branch/pathGitHub/Bitbucket 的带/tree/branch/subdir浏览地址也会被规范化处理。(GitHub)所以你不一定只能传仓库根 URL。从源码看传到某个分支甚至子目录都是可以被解析的RegistrySource里就明确保存了repo、subdir、ref、rawBaseUrl。(GitHub)2. 远程模板仓库官方要求的结构是什么官方文档给出的“标准发布方式”是仓库里有一个marketplace/目录如果要做多模板 marketplace就再放一个marketplace/index.jsonindex.json里列出模板项每项至少包含id、type、name、pathdescription和tags是可选文档示例里type用的是specpath类似marketplace/specs/my-stack。(Trellis Docs)文档给的示例索引长这样{ version: 1, templates: [ { id: my-stack, type: spec, name: My Stack Template, description: 我们技术栈的编码规范, path: marketplace/specs/my-stack, tags: [react, node, typescript] } ] }这不是我概括是官方文档原样给出的结构。(Trellis Docs)3. Marketplace 模式和 Direct Download 模式各自要求什么Marketplace 模式这是有marketplace/index.json的情况。Trellis 会先去取这个索引源码里probeRegistryIndex()的逻辑很直接404 视为“没有 index.json”200 且能解析 JSON就读取其中的templates数组。(GitHub)所以在 marketplace 模式下硬性要求基本就是registry 对应位置能拿到index.jsonindex.json是合法 JSON里面有version和templates你通过-t选中的模板 ID 必须存在当前实现里模板type必须是spec否则会报 “only spec is supported”。(GitHub)Direct Download 模式这是没有index.json的情况。文档写法是如果仓库没有marketplace/index.jsonTrellis 会把整个marketplace/specs/目录当成单个模板直接下载。源码对应的下载函数downloadRegistryDirect()也说明了这种模式是“把 registry source 直接下载到.trellis/spec”。(Trellis Docs)这里有个很关键的约束如果你同时传了--registry和-t但这个 registry 没有index.json源码会直接报错Registry has no index.json. Remove --template to use direct download mode.也就是说有-t→ registry 必须提供index.json没有-t→ 可以走 direct download。(GitHub)4. 模板目录内部需要长什么样文档把“每个模板”的目标结构描述为一个 spec 树包含frontend/、backend/、guides/和README.md这类内容。Trellis 下载后安装位置是.trellis/spec源码里spec类型模板的安装目标也确实是.trellis/spec。(Trellis Docs)这里有一个我基于源码做的实际建议因为downloadTemplateById()会把模板路径resolved.path直接下载到目的目录.trellis/spec所以最稳妥的做法是让path指向“其内容本身就应该成为.trellis/spec/内容”的那个目录也就是里面直接放frontend/、backend/、guides/等而不是再多套一层无关外壳目录。这个结论来自源码里resolved.path被直接拼成下载源再落到getInstallPath(..., spec)的行为。(GitHub)5. 你实际搭自定义 registry 时最稳的两种写法写法 A标准 marketplace 仓库适合多个模板。repo/ └─ marketplace/ ├─ index.json └─ specs/ ├─ my-stack/ │ ├─ frontend/ │ ├─ backend/ │ ├─ guides/ │ └─ README.md └─ another-stack/ └─ ...调用方式trellis init --registry https://github.com/your-org/your-spec-templates -t my-stack这完全符合文档示例和源码的index.json template id流程。(Trellis Docs)写法 B单模板直链目录适合你只有一个模板不想维护index.json。trellis init --registry https://github.com/your-org/your-spec-templates/tree/main/marketplace/specs/my-stack这条之所以成立是因为源码能解析/tree/branch/subdir形式并且 direct mode 会把 registry source 直接下载到.trellis/spec。这时不要再加-t。(GitHub)6. 可以把要求压缩成一句话最稳的约束可以记成想配合-t用你的 registry 必须提供index.json并且每个模板项至少有id/type/name/path其中type现在必须是spec。(GitHub)不想配index.json就把--registry指到一个单模板目录别加-t让 Trellis 直接下载它到.trellis/spec/。(GitHub)如果你愿意我可以下一条直接给你写一个可用的最小自定义 registry 仓库示例包括index.json和目录树。在创建之后应该首先完成bootstrap任务读取prd.md即可workflow.md是最开始编辑的编辑过了一般就不会修改了(除非手动)worktree.yaml 管并行 agent 的运行环境怎么搭这个可以仔细学一下如何修改