关于 monorepo-setup-worktrees
为 Editframe 单体仓库提供按范围隔离的 Git worktree 管理技能,面向并行开发团队和 Agent。它通过统一命令行管理 worktree、Docker 服务及分支同步,并保护主 worktree 始终位于 main。
主要功能
- 01按 elements、web、render 范围创建环境
- 02管理 worktree 生命周期与健康检查
- 03暂停、恢复及清理 Docker 容器
- 04同步 main 并清理已合并分支
- 05执行渲染冒烟测试
适用场景
- 01为多个功能分支并行配置隔离服务
- 02按需升级 worktree 的服务范围
- 03合并后将 main 更新同步到活跃分支
- 04合并前验证渲染流水线更改
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ editframe/ skills --skill monorepo-setup-worktrees安装后在 Claude Code 中输入/monorepo-setup-worktrees确认已加载。
详细介绍
Monorepo 工作树系统
按范围隔离工作树,支持并行开发流。每个工作树都有隔离的 Docker 服务、数据库和域名。
范围
| 范围 | 服务 | 容器 | 创建时间 |
|---|---|---|---|
elements | 仅 Elements runner + dev-projects | 2 | ~28s |
web | Elements + telecine 核心(web、hasura、valkey、maintenance) | 8 | ~1:30 |
render | Elements + telecine 核心 + render pipeline(workers、scheduler) | ~22 | ~2:30 |
升级路径:elements → web → render。不支持降级。
工作树管理
所有工作树操作都使用统一的 CLI:scripts/worktree <command>。
worktree create <branch> [scope] # Create new worktree (default: web)
worktree list # List all worktrees
worktree status [branch] # Health check
worktree pause <branch> # Stop containers
worktree resume <branch> # Start containers
worktree remove <branch> [--force] # Full cleanup
worktree upgrade <branch> <scope> # Escalate scope (elements→web→render)
worktree merge <branch> # Merge branch into main (feature → main)
worktree pull # Fetch upstream, update local main, sync main → all worktrees
worktree prune [--dry-run] # Remove worktrees whose branches are fully merged into main
worktree smoke <branch> # One-shot render verification
worktree logs [branch] [options] # View logs
worktree doctor [branch] [--skills] # Diagnose issues
worktree editor-deps [branch] # Install host-side node_modules for editor tooling
worktree deps [--workspace=...] # Show dependency graph
架构
仓库布局
~/Editframe/
monorepo -> worktrees/main/monorepo (symlink for convenience)
worktrees/
main/
.worktree-scope # scope for main (e.g. "render")
monorepo/ # primary monorepo checkout [main]
telecine -> ../telecine # symlink
elements -> ../elements # symlink
telecine/ # primary telecine clone [main]
elements/ # primary elements clone [main]
<branch>/
.worktree-scope # scope for this branch
monorepo/ # monorepo worktree [branch]
telecine/ # telecine git worktree [branch]
elements/ # elements git worktree [branch]
主工作树(worktrees/main/)必须始终处于 main 分支。 切勿在主工作树目录中运行 git checkout、git switch 或任何切换分支的命令。所有功能开发都应在通过 worktree create 创建的专用分支工作树中进行。LLM Agent 最容易在以下情况下违反这一规则:直接运行 git checkout <branch>,把主工作树当作普通的单检出仓库,或使用需要预先检出分支的合并方式。
scripts/worktree.ts 通过两项严格保护措施强制执行此规则——请勿移除或放宽:
cmdCreate会在创建任何新工作树前断言主工作树处于main分支,并始终以main为基础创建新分支。cmdMerge会断言每个仓库都已处于main分支,并在不检出的情况下执行合并——绝不会在主工作树中调用git checkout。
~/Editframe/monorepo 是一个便捷符号链接,也是所有工作树命令的入口。
作为 Agent 在分支工作树中工作
Agent 的工作目录在启动时固定——通常是 worktrees/main/monorepo。cd 不会持久生效。 创建或找到分支工作树后,每次文件编辑、Git 命令和脚本调用都必须使用以分支工作树为根的完整绝对路径,而不是相对于 Agent 当前工作目录的路径。
分支为 my-feature 时,工作树根目录为 ~/Editframe/worktrees/my-feature/monorepo/。具体规则:
- 读取/编辑文件:使用
~/Editframe/worktrees/my-feature/monorepo/下的绝对路径 - Git 操作:使用
git -C ~/Editframe/worktrees/my-feature/monorepo <command>,或在工具调用中使用workdir参数 - Elements 脚本:
~/Editframe/worktrees/my-feature/elements/scripts/<script> - Telecine 脚本:
~/Editframe/worktrees/my-feature/telecine/scripts/<script> - 切勿在分支工作中使用相对路径或
worktrees/main/下的路径
查找现有分支的根目录:git worktree list | grep my-feature
脚本中的 EDITFRAME_DIR 始终为 $(dirname $(dirname $(dirname $(git rev-parse --show-toplevel))))——即从 monorepo 检出路径向上三级。
共享基础设施
editframe-postgres— 单个共享 PostgreSQL,每个工作树都有自己的数据库(telecine-<branch>)editframe-traefik— 共享反向代理,根据Host标头路由(<branch>.localhost)telecine-runner/elements-runner— 共享 Docker 镜像(不会为每个工作树重新构建)
数据库模板
telecine-template 从 telecine-main 克隆而来(304 个迁移 + 种子数据,克隆约需 0.6s)。在主工作树上运行 telecine/scripts/start 执行迁移时,模板会自动刷新。
端口偏移
工作树服务使用基于 cksum 的端口偏移(200 个槽位,间隔为 100),使 Postico 等主机工具能够连接。主工作树使用标准端口。
配置脚本
telecine/scripts/worktree-config— 导出WORKTREE_ID、WORKTREE_DATABASE、WORKTREE_DOMAIN、WORKTREE_DOCKER_PROJECT_NAME和端口变量elements/scripts/worktree-config— 使用相同模式配置 elements- monorepo 工作树根目录中的
.worktree-scope文件用于跟踪当前范围
Docker Compose 配置文件
- 无配置文件 = 核心服务(始终启动):runner、web、valkey、graphql-engine、data-connector-agent、maintenance
render配置文件:所有 worker 服务、scheduler-go、jit-transcodingdev配置文件:tracing、otel-viewer、mailhog、playwrighttelecine/scripts/start会读取.worktree-scope来设置COMPOSE_PROFILES
服务启动顺序
Runner 必须先启动,并且必须先完成 npm install,之后才能启动其他会执行应用代码的服务(web、dev-projects、workers)。创建和升级脚本会处理这一流程:up -d runner → npm install → up -d(其余服务)。
将 main 同步到工作树
PR 合并到 main 后(这种情况经常发生),请在 main 工作树中运行 worktree pull:
worktree pull
此命令会依次执行以下三项操作:
- 获取 monorepo、telecine 和 elements 的上游远程仓库
- 将
origin/main合并到 telecine 和 elements 的本地 main(无冲突时执行快进合并) - 将本地 main 合并到每个活动工作树分支
package.json、package-lock.json 和 VERSION.ts 中的冲突会自动通过采用 main 版本来解决。其他冲突会被报告并跳过 — 受影响的工作树不会被修改,需要手动解决冲突。
要清理分支已在所有三个仓库中完全合并到 main 的工作树:
worktree prune # remove all fully-merged worktrees
worktree prune --dry-run # preview what would be removed
prune 会先检查所有三个仓库,再执行任何移除操作 — 只有当某个工作树的分支同时是 monorepo、telecine 和 elements 中 main 的祖先时,才会将其清理。
工作树生命周期
create (elements, 28s) → upgrade (web, 63s) → upgrade (render)
↓ ↓
pause/resume pause/resume
↓
remove
开发服务器 URL
elements 的 dev-projects Vite 服务器使用 root: elements/dev-projects/。文件从根路径提供 — 而非 /dev-projects/ 路径。
video.html→http://<branch>.localhost:4321/video.htmlcanvas-demo.html→http://<branch>.localhost:4321/canvas-demo.html
URL 路径中不要包含 dev-projects/。
工作树中的 dev-projects
elements/dev-projects/ 已被 gitignore。工作树中只有已提交的空壳文件,不包含完整的 asset/src 目录树。
worktree create 会在工作树的 elements/.env 中设置 DEV_PROJECTS_HOST,使其指向 main 中的 dev-projects。docker-compose.yaml 中的 dev-projects 服务会将此路径挂载到 /packages/dev-projects,因此工作树的开发服务器始终能使用 main 中的完整文件树。
冒烟测试
worktree smoke <branch> 是一次性渲染验证。它不是持久化配置范围;请将其用作渲染管线变更的合并前检查。
- 需要
web或render范围(使用elements时会报错) - 如果范围是
web:临时启动 render 配置文件中的服务,并注册清理陷阱,在退出时停止这些服务 - 如果范围是
render:使用已运行的服务,不管理其生命周期 - 在 runner 容器中运行
telecine/scripts/smoke-test.ts,并设置EF_HOST=http://web:3000和工作树的EF_TOKEN - 输出仪表板 URL(
http://<branch>.localhost:3000),以便直观检查渲染输出 - 提示按 Enter 键后再停止 render 服务(如果这些服务是由该命令启动的)
渲染开发工作流:保持在 web 范围,直接运行单元测试,并使用 worktree smoke 作为合并检查,而不是让完整的 render 服务栈全天运行。
scheduler-go 是预构建的 Go 镜像,不由 docker-compose 管理。worktree smoke 会在首次运行时自动构建它。scripts/build-runner-images 也会构建它。
编辑器工具
Docker 容器使用命名卷来存放 node_modules,这些目录在主机文件系统中不可见。主机上的编辑器(VS Code、Cursor 等)需要自己的 node_modules,以解析 TypeScript 类型和 JSX 内置元素。
worktree create 会自动通过 npm install --ignore-scripts 安装主机端依赖。对于缺少主机端类型的现有工作树,请运行 worktree editor-deps <branch>。worktree doctor 会检测并报告缺失的主机端类型。
故障排查
- 端口冲突:两个分支的哈希值映射到了相同偏移量。使用 cksum 和 200 个槽位时,这种情况极不可能发生,但仍有可能。移除一个工作树并重新创建。
- 孤立容器:
worktree doctor会检测孤立项目(没有匹配 Git 工作树的容器),并打印用于清理它们的确切docker rm -f命令。 - 创建部分失败:如果
worktree create中途失败,工作树目录会存在,但内容不完整。重试前运行worktree remove --force <branch>。 - 模板过时:运行
scripts/update-template-db,根据当前主数据库状态刷新模板。