资讯动态

Beads 多仓库路由(Multi-Repo Routing)实战指南:让 `bd create` 智能决定每个 bead 归属的仓库

发布时间:2026/9/12 21:11:33 来源:尧图企业网站定制
Beads 多仓库路由Multi-Repo Routing实战指南让bd create智能决定每个 bead 归属的仓库【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads导读当同一个开发者在多个仓库之间工作OSS fork 私有规划仓库、规划仓库驱动实现仓库、一台机器上的多个项目检出时Beads 的路由Routing机制决定每个新创建的 bead 写入哪个仓库的数据库。本文以 docs/multi-agent/routing.md 为核心结合仓库源码讲解路由决策的优先级、角色检测、bd init --contributor向导、逐 bead 覆盖--repo与多仓库水合Hydration读完你可以在不污染上游 PR 的前提下自由规划、并在多个仓库之间维持统一视图。为什么需要路由贡献者困境路由要解决的是一个非常具体的场景你 fork 了一个使用 beads 的 OSS 项目然后开始在 fork 上工作。如果没有路由你在 fork 中创建的每一个规划类 bead 都会写入 fork 的.beads/数据于是你的 fork 的问题数据库在每次向 upstream 开 PR 时都与上游不断分叉——你只是想关于这个项目做规划却不得不在项目里做规划。路由通过检测你的身份maintainer / contributor来解决这个问题将bd create重定向到一个独立于项目的规划仓库默认~/.beads-planning这个仓库永远不会被 push 到上游。路由是**opt-in可选启用**的。没有任何路由配置时每个 bead 都落在当前仓库——本页所述的一切都不会改变单仓库工作流的行为。这一点在源码层面也有体现internal/routing/routing.go中DetermineTargetRepoWithRule在没有配置任何规则时返回.当前仓库并标记为RuleNone。路由如何决策严格的优先级运行bd create时目标仓库按照严格优先级选择--repo path—— 显式覆盖永远优先routing.mode: auto—— 按检测到的角色maintainer 或 contributor路由routing.default—— 其余一切情况默认.即当前仓库这一优先级在 cmd/bd/create.go 中有完整的源码实现bd create首先检查--repoflag 是否被显式设置cmd.Flags().Changed(repo)若设置则直接使用该值作为目标仓库否则调用routing.DetectUserRole(.)检测角色并从 config.yaml / 数据库配置中读取routing.mode、routing.default、routing.maintainer、routing.contributor最终调用routing.DetermineTargetRepo(routingConfig, userRole, .)得出落点。决策内核在 internal/routing/routing.gofunc DetermineTargetRepoWithRule(config *RoutingConfig, userRole UserRole, repoPath string) (string, RoutingRule) { // Explicit override takes precedence if config.ExplicitOverride ! { return config.ExplicitOverride, RuleExplicitOverride } // Auto mode: route based on user role if config.Mode auto { if userRole Maintainer config.MaintainerRepo ! { return config.MaintainerRepo, RuleMaintainer } if userRole Contributor config.ContributorRepo ! { return config.ContributorRepo, RuleContributor } } // Fall back to default repo if config.DefaultRepo ! { return config.DefaultRepo, RuleDefault } // No routing configured - use current repo return ., RuleNone }该函数还返回一个RoutingRule枚举RuleNone/RuleExplicitOverride/RuleMaintainer/RuleContributor/RuleDefault用于在 CLI 输出中准确说明为什么被路由走了而不是硬编码成 contributor 一种原因。读取同样遵循路由路由启用时bd list和bd ready从被路由到的仓库读取而bd show id之类的 ID 查询在当前仓库找不到时会回退到被路由的仓库。这一逻辑位于 cmd/bd/routing_read.go 的openRoutedReadStore它通过determineAutoRoutedRepoPath解析目标仓库路径若结果为空或.则保持本地读取RuleNone否则打开目标仓库的.beads/目录作为只读 store。特别地bd stats和bd show id不参与路由始终报告本地项目的事实——正是这种读取被路由、统计不路由的分裂让问题难以诊断因此 routing_read.go 在路由生效时向 stderr 打印一条 notice受--quiet抑制并给出对应的修复命令note: contributor routing (beads.rolecontributor, or inferred from the origin URL) routes bd list/ready to the contributor planning store, not this project (this project has N total issue(s)). Fix: git config beads.role maintainer角色检测Role Detection驱动 auto 模式的角色来自 git config——beads.role是权威来源bd config set beads.role contributor # 存储在 git config而不是数据库 bd config get beads.role在源码 internal/routing/routing.go 中DetectUserRole的检测顺序是读取 git config 中的beads.role首选roleFromGitConfig调用git config --get beads.role只认maintainer/contributor两个合法值jj 次级工作区特殊处理次级工作区没有自己的.git会先解析主工作区git.GetJJPrimaryWorkspaceRootFrom再重试读取同时把后续启发式判断锚定到主工作区的 git 仓库GH#2950回退到已废弃的远程 URL 启发式并打印警告。当beads.role未设置时bd打印警告并回退到远程 URL 启发式。detectFromURLinternal/routing/routing.go的判定规则如下Git 远程情况检测到的角色origin和upstream指向不同仓库fork 工作流contributorSSHorigingit...、ssh://或带凭据的 HTTPSmaintainer不带凭据的纯 HTTPSorigincontributor未配置远程本地项目maintainer注意SSH 并不能可靠地表示推送权限——fork 贡献者常常也通过 SSH clone。显式设置beads.role后启发式及其警告就永远不会运行。此外sameRemoteRepository会通过remoteRepositorySlug规范化远程地址支持githost:owner/repo.git与https://host/owner/repo.git两种形态、剥离.git后缀避免因协议书写差异把同一个仓库误判为 fork。设置Setup贡献者Contributorscd ~/projects/my-fork bd init --contributor这个交互式向导的实现位于 cmd/bd/init_contributor.gorunContributorWizard完整流程如下检测 fork 关系通过git remote get-url upstream判断是否存在upstream远程detectForkSetup。若检测到 fork向导显示 Detected fork workflow若没有upstream远程会提示git remote add upstream original-repo-url并询问是否继续。检查 origin 推送权限checkPushAccessSSH URLgit开头视为有推送权限纯 HTTPS 视为只读。有推送权限时向导会再次确认是否仍要使用独立规划仓库。创建规划仓库默认在~/.beads-planning若设置了BEADS_DIR环境变量则以它为准但会先警告BEADS_DIR优先于 contributor 路由。该目录若不存在会依次执行git init、创建.beads/目录、写入一份 README、并完成 initial commit使其成为独立的 git 仓库。配置路由在数据库 store 中写入routing.modeauto与routing.contributor规划仓库路径init_contributor.go。启用多仓库水合把规划仓库加入repos.additional使路由产生的 bead 在bd list中可见。fork 时配置同步源写入sync.remoteupstream让bd dolt pull从源仓库而不是你自己的 fork 拉取 issue 数据。向导结束后会输出配置摘要并提示尝试bd create Plan feature X -p 2验证路由效果。普通bd init也会自动检测 fork 模式存在与origin不同的upstream远程并自动套用同样的 contributor 配置autoConfigureForkContributorcmd/bd/init_contributor.go它是非交互且幂等的会创建~/.beads-planning、设置routing.modeauto、routing.contributor、sync.remoteupstream、写入git config beads.role contributor并配置水合若路由已配置则跳过幂等。传入--role maintainer可退出此自动配置。团队Teamsbd init --team共享一个仓库的团队通常不需要路由不设置路由时每个 bead 都落在共享仓库里。团队向导配置的是其余共享工作流——团队模式以及在受保护主干protected-main场景下为 issue 提交单独设置一个同步分支。想要私有 scratch 空间的团队成员可以显式路由实验内容bd create Try alternative approach --repo ~/.beads-planning-personal两种场景以及多阶段、多人格设置的完整逐步演练见 Multi-Repo Migration。配置参考Configuration Reference以下键用bd config set key value设置存储位置参见 configuration reference。其中beads.role写入 git config而非数据库见 cmd/bd/doctor/role.go 的读取逻辑先查 git config再回退数据库配置repos.primary/repos.additional写在.beads/config.yaml的repos:段见 repo 命令文档。键默认值含义routing.mode未设置auto按角色路由explicit或未设置把一切发送到routing.defaultrouting.default.auto 模式关闭时的目标routing.maintainer.auto 模式下 maintainer 的目标routing.contributor~/.beads-planningauto 模式下 contributor 的目标repos.primary未设置多仓库水合的主仓库repos.additional未设置从中水合 bead 的仓库列表beads.role未设置显式角色maintainer或contributor存储在 git config验证生效配置及各值的来源bd config show # 所有来源config.yaml、database、git、env bd config validate # 检查 routing.mode 取值及相关设置 bd where # 当前目录实际使用哪个数据库从源码看bd config validate对应 cmd/bd/doctor/config_values.go 中的validRoutingModes接受的routing.mode合法值为auto、maintainer、contributor、explicit四种validateRoutingPaths还会检查routing.default/routing.maintainer/routing.contributor指向的路径是否存在.除外。配置来源的优先级链在 docs/reference/configuration.md 有说明config.yaml按~/.beads/config.yaml→~/.config/bd/config.yaml→repo/.beads/config.yaml→$BEADS_DIR/config.yaml顺序查找后者覆盖前者config.local.yaml最后合并当 config.yaml 或环境变量遮蔽数据库键时bd config list会打印覆盖警告bd config show会报告每个生效键的来源。逐 bead 覆盖Overriding per bead--repo为单个 bead 完全绕过路由bd create Fix upstream bug --repo . # 强制写入当前仓库 bd create Private experiment --repo ~/scratch # 强制写入另一个仓库在 cmd/bd/create.go 中该 flag 的定义是Target repository for issue (overrides auto-routing)。注意显式--repo指向的目标如果是相对路径/裸路径且不存在 beads workspace创建会被拒绝并给出提示isAmbiguousRepoTarget的防呆逻辑cmd/bd/create.go要求传绝对路径或~/前缀的路径而来自配置的 auto 路由路径则始终允许自动创建auto-vivify。--repo也支持远程 URL——此时会通过remotecache.DefaultCache()确保远程仓库同步并打开其 storecmd/bd/create.go。发现的工作保持归属父仓库带discovered-from依赖创建的 bead 会继承父任务的source_repo因此执行任务过程中发现的后续工作始终归属到与父任务相同的仓库——无论你的角色是什么bd create Found race in auth --deps discovered-from:bd-abc # 继承 bd-abc 的 source_repo实现位于 cmd/bd/create.gocreate在解析--deps后若存在discovered-from依赖则查询父 issue 并继承其SourceRepo字段父 issue 查询失败或无source_repo时沿用默认。添加--repo可覆盖这一继承。多仓库水合Multi-Repo Hydration路由把 bead 写入另一个仓库——这意味着你当前的数据库里没有它们。**水合Hydration**把其他仓库的 bead 导入你的数据库每个 bead 都带source_repo标记于是bd list和bd ready呈现统一视图。配置方式是把其他仓库列入repos.additionalbd repo add ~/.beads-planning # 添加一个要水合的仓库 bd repo list # 显示 primary additional 仓库 bd repo sync # 从所有 additional 仓库导入 bead bd repo remove ~/.beads-planning # 移除并删除其已水合的 beadbd repo sync的实现细节在 cmd/bd/repo.go逐个读取每个 additional 仓库的.beads/issues.jsonl导出文件把 bead 连同其原始前缀一起导入并设置source_repo用mtime 缓存跳过导出未变化的仓库store.GetRepoMtime/SetRepoMtime比较issues.jsonl的ModTime导入时使用SkipPrefixValidation: true以支持跨前缀水合cross-prefix hydrationbd repo remove除了从repos.additional删除路径路径必须与添加时完全一致例如添加~/foo就必须移除~/foo而非/home/user/foo还会删除数据库中来自该仓库的已水合 bead见 repo 命令文档。bd init --contributor会自动接好水合链路bd doctor在路由目标缺失于repos.additional时给出警告——cmd/bd/doctor/config_values.go 专门检查routing.modeauto且存在路由目标时repos.additional是否已配置并包含每个路由目标展开~后逐一比对否则提示Run bd repo add routing-target to enable hydration。水合完成后来自其他仓库的 bead 就是你数据库里的普通行——可以按来源过滤或用普通依赖关联bd list --json | jq .[] | select(.source_repo ~/.beads-planning) bd dep add impl-42 plan-10 --type blocksbd dep add还支持针对另一个项目能力而非具体 bead的external:project:capability目标——见 bd dep 命令参考。一个 Agent 管理多个项目One Agent, Many Projects跨多个仓库工作的 AI Agent 应该运行单个beads MCP server 实例{ beads: { command: beads-mcp, args: [] } }server 会从每个请求的工作目录解析 beads workspace因此一份配置即可服务所有项目而每个项目保持自己隔离的数据库默认 embedded Dolt 位于.beads/embeddeddolt/server 模式使用.beads/dolt/。每个项目各自跑一个 MCP 实例反而容易让操作落到错误的数据库。若希望跨项目共享一个 Dolt server而非每项目 embedded 存储用bd init --shared-server初始化或设置BEADS_DOLT_SHARED_SERVER1所有项目共享~/.beads/shared-server/上的一个 server同时以各自的 issue 前缀命名的数据库保持隔离。安装与客户端配置见 MCP Server。排障Troubleshootingbead 落在错误的仓库bd config get routing.mode # auto? bd config get beads.role # 设置了显式角色吗 bd config show --source git # git config 贡献了哪些值修复方式显式设置角色bd config set beads.role maintainer、为单个 bead 强制目标--repo .、或完全禁用角色检测bd config set routing.mode explicit。路由后的 bead 不出现在 bd list路由目标没有被水合。添加并同步bd repo add ~/.beads-planning bd repo syncbd doctor能捕获这种错误配置对应 config_values.go 的一致性检查。发现类 bead 出现在错误的仓库这是有意的——带discovered-from依赖的 bead 继承父任务的source_repo。创建时用--repo覆盖即可。规划 bead 出现在上游 PR 中规划仓库必须是独立的 git 仓库绝不能提交到 forkls ~/.beads-planning/.git # 应该存在 bd config get routing.contributor # 应该指向规划仓库每次 bd create 都有角色警告bd在回退到 URL 启发式时会发出警告。永久消除bd config set beads.role maintainer # 或 contributor相关资源Multi-Repo Migration —— contributor、team、multi-phase 工作流的完整设置演练含手动配置routing.mode、repos.additional、多阶段/多人格仓库划分与最佳实践Agent Coordination —— 在 agent 之间分配与认领工作Federation —— 跨仓库、跨组织的 bead 点对点共享命令参考bd init、bd config、bd repo、bd create配置总览configuration referenceconfig.yaml 查找顺序、配置来源与优先级实现依据internal/routing/routing.go、cmd/bd/create.go、cmd/bd/init_contributor.go、cmd/bd/routing_read.go、cmd/bd/repo.go【免费下载链接】beadsBeads - A memory upgrade for your coding agent项目地址: https://gitcode.com/GitHub_Trending/beads1/beads创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价