
Multica 项目与项目资源从 CLI 命令到任务上下文注入的完整实现地图【免费下载链接】multicaMake humans and AI agents work as one team — open-source and self-hostable.项目地址: https://gitcode.com/GitHub_Trending/mu/multicaMultica 中项目Project不只是工作分组更是注入给 AI Agent 的“持久上下文容器”项目上挂载的github_repo、local_directory资源会决定未来任务检出哪个仓库、在哪台 daemon 的哪个目录执行、以何种模式并发项目的description会直接进入每个任务简报的## Project Context段落。本文基于内置技能multica-projects-and-resources的源码地图references/projects-and-resources-source-map.md与对应实现源码完整梳理“一条 CLI 命令如何落库、如何被 daemon 消费、如何写进 Agent 工作区”的全链路并给出排查错误上下文的标准步骤。读完后你将能够使用multica project/multica project resource全套命令管理项目与资源理解execution_modeworktree的双层 capability 门禁及其失败模式定位资源数据从 API → daemon claim →.multica/project/resources.json→ 任务简报的注入路径。核心模型资源不是展示元数据而是任务上下文按技能文档SKILL.md的定义Projects are durable context containers. Resources attached to a project can affect future agent tasks.一个项目把相关工作聚合起来并承载“持久资源”。资源不只是 UI 上展示的属性它稍后会被注入到任务简报task brief与.multica/project/resources.json中。当前两种受支持的资源类型资源类型resource_ref关键字段用途github_repourl必填、ref可选默认检出分支/tag/SHA、default_branch_hint可选仅用于 prompt 提示为项目内未来任务提供持久 GitHub 仓库上下文local_directorylocal_path绝对路径、daemon_id必填、label可选、execution_mode可选in_place默认 或worktree把任务绑定到某台 daemon 的本地目录执行此外项目的description本身就是持久上下文当 issue或 quick-create 任务绑定到项目时项目描述会注入 Agent 简报的## Project Context段落并作为project_description写进.multica/project/resources.json。适合放“项目级规则/约定”这类应作用于项目内每个任务的内容。CLI 命令面cmd_project.go注册了什么server/cmd/multica/cmd_project.go 注册了两组命令项目本体list、get、create、update、delete、status资源子树project resource list/add/update/remove。合法的status取值在客户端侧被validateProjectStatus先行校验planned、in_progress、paused、completed、cancelled拼写错误会在本地快速失败并打印合法值列表而不是绕一次服务端拿到 400。创建项目时可顺带挂载仓库--repomultica project create --title title --repo github-url --output json--repo可重复。从源码看cmd_project.goCLI 把每个 URL 组装为{resource_type:github_repo,resource_ref:{url:url}}打包进 create 请求体的resources字段——注释明确说明这是为了“让服务端在同一事务里挂载资源避免失败时留下半成品项目”。--start-date/--due-date日历日与迁移 166project create/project update都接受--start-date/--due-dateYYYY-MM-DD日历日映射到project表的start_date/due_date列。迁移 166_project_dates.up.sql 的注释解释了设计动机与 issue 的日期列对齐以DATE存储、不含时刻与时区保证“3 月 1 日对所有观察者都是 3 月 1 日”两列均可空、无默认值加可空列是纯元数据变更无需重写表ALTER TABLE project ADD COLUMN start_date DATE, ADD COLUMN due_date DATE;更新时有一个值得注意的语义细节cmd_project.goCLI 用cmd.Flags().Changed(...)而非判空来收集日期字段这样显式传入--start-date 能到达服务端表示“清除日期”而不传该 flag 则保持不动——与cmd_issue.go中 issue 日期 flag 的语义一致multica project update project-id --due-date 2026-04-15 --output json multica project update project-id --start-date --output json # 清除开始日期project resource add类型快捷 flag 与通用 JSON 逃生舱完整命令示例来自 SKILL.mdmultica project list --output json multica project get project-id --output json multica project resource list project-id --output json multica project resource add project-id --type github_repo --url github-url --output json multica project resource add project-id --type github_repo --url github-url --ref branch-or-sha --output json multica project resource add project-id --type local_directory --local-path abs-path --daemon-id daemon-id --output json multica project resource add project-id --type local_directory --local-path abs-path --daemon-id daemon-id --execution-mode worktree --output json multica project resource update project-id resource-id --execution-mode in_place --output json multica project resource update project-id resource-id --url new-github-url --output json multica project resource update project-id resource-id --ref branch-or-sha --output json multica project resource remove project-id resource-id --output json各 flag 的精确语义cmd_project.gogithub_repo快捷 flag--url、非 JSON 的--ref作为检出 ref、--default-branch-hintlocal_directory快捷 flag--local-path、--daemon-id、--ref-label、--execution-mode通用逃生舱--ref json。任何未提供快捷方式的资源类型都可以走纯 JSON 路径无需改 CLI。--ref在github_repo上的“双重身份”是一个容易踩坑的点。buildResourceRefFromRefFlag只在值“看起来像 JSON”以{或[开头见looksLikeJSONPayload时才按 JSON 解析其余任何值——包括纯数字 tag2024或全数字短 SHA1234567——都被视为 checkout ref 并与--url合并。源码注释指出原因json.Unmarshal会把2024当成合法 JSON 数字从而悄悄吞掉一个本应作为检出 ref 的合法值。project resource update与现有resource_ref合并而非覆盖服务端把resource_ref当作“整体替换”的不透明 JSON见 UpdateProjectResourceRequest 的注释。因此 CLI 的update路径会先 GET 资源列表找到现有行再让buildResourceRefFromFlags以现有resource_ref为种子重建完整 payload——只传--default-branch-hint时原有的url会被保留而不是消失。几个细节传空字符串给--refgithub_repo、--ref-label、--execution-mode表示“删除该字段”清空回默认与清空 label 的机制一致非 JSON 的--ref在 update 时更新的是github_repo.resource_ref.ref即默认检出 ref未知资源类型下使用快捷 flag 会直接报错要求改用--ref json更新资源是一次“持久变更”更新后重新resource list是标准验证路径。execution_modeworktree校验链与双层 capability 门禁local_directory的execution_mode决定任务如何共享一个本地目录in_place默认Agent 直接在用户目录里跑由 daemon 的 per-path 互斥锁串行化一次一个任务第二个任务会进入waiting_local_directory等待worktree每个任务获得该仓库自己的 git worktree任务并发运行各自以agent/agent/task分支形式交付成果而不是编辑工作副本。要求路径是至少含一个 commit 的 git 仓库否则任务以显式错误失败。完整的校验与消费链条横跨 server 与 daemon 两侧保存时校验validateLocalDirectoryRef在server/internal/handler/project_resource.go中校验并归一化execution_mode零值字段缺省即in_place保证早于 worktree 模式存在的资源无需数据迁移即保持原行为project_resource.go 的注释。保存时 capability 门禁保存execution_modeworktree时requireWorktreeCapableDaemon会检查该 workspace 下最近一次心跳的 runtime 行是否通告了local-worktree-v1能力protocol.DaemonCapabilityLocalWorktreeV1定义于 server/pkg/protocol。不具备则返回HTTP 422错误码daemon_version_unsupported——修复方式是在那台机器上升级 Multica 客户端后重试。响应里的min_version字段取MinLocalWorktreeCLIVersionproject_resource.go——注意它只是展示给用户的版本号没有任何逻辑以它为准做门禁。领取时的权威门禁真正的权威检查发生在任务 claim 时——worktreeClaimBlockReason直接从 claim 请求自身读取能力头X-Client-Capabilities对不满足条件的 runtime 生成阻断原因并取消任务而不是降级为 in-place 运行。测试 worktree_claim_gate_test.go 覆盖了“版本字符串不参与判定、只看能力位”的组合场景。daemon 侧消费daemon 在 local_directory.go 中通过localDirectoryAssignment.UsesWorktree()读取该模式并在 execenv/local_worktree.go 里为每个任务构建 per-task worktree。local_directory_test.go 验证了“缺省即互斥in_place、execution_modeworktree时走 worktree”的行为。这个“保存时 422 领取时取消”的双检设计意味着即使某台机器的 runtime 后来失去了 worktree 能力已保存的worktree资源也不会被静默降级执行而是让任务以带原因的取消结束。服务端路由与数据面路由server/cmd/server/router.go 暴露/api/projects及/api/projects/{projectId}/resourcesPOST添加、PUT /resources/{id}更新、DELETE /resources/{id}移除。查询面server/pkg/db/queries/project_resource.sql 是project_resource行的 CRUD 查询层sqlc 生成。API 层对未知resource_type会在边界直接拒绝validateAndNormalizeResourceRef新类型只需在此登记无需 schema 迁移。注入链资源如何到达 Agent 的任务环境这是“资源 上下文”论断的实现证据。以 workdir 的落盘为例execenv/context.go 中的writeProjectResources把项目资源写入任务工作区的.multica/project/resources.json其中包含project_id、project_title与project_descriptioncontext.go 的ProjectDescription字段。execenv_test.go 会解码回读该文件并断言project_description与任务上下文一致。两条注入链分别是1.github_repo.resource_ref.ref→ 默认检出 refclaim 处理器server/internal/handler/daemon.go把ref提升为 daemon 侧的RepoData.Refdaemon 将其按任务存储在 daemon.go 中随后 daemon/health.go 在 checkout 请求未显式传 ref 时把它作为/repo/checkout的默认检出 ref。也就是说在 CLI 里给资源设一次--ref main项目内所有后续任务的仓库检出都会默认钉在main。2. 项目description→ 每个任务的## Project Context从源码结构看链路为claim handlerdaemon.go 的 claim 响应组装读取proj.Description填到 claim 响应的ProjectDescription字段定义于 server/internal/handler/agent.go→ daemon 经Taskserver/internal/daemon/types.go与TaskContextForEnvexecenv/execenv.go注释即“渲染进 brief 的 Project Context 段落的持久项目级上下文”传递 → 最终写入简报的## Project Context段落execenv/runtime_config.go并同步进.multica/project/resources.json的project_description。在评论中引用项目mention://project的渲染契约项目没有MUL-123这类可自动链接的短标识因此把项目标题写成散文只会产生“死文本”。正确写法是用项目 UUID 写 mention-linkRoadmapUUID 从multica project list --output json获取。关键契约这是纯渲染链接后端不解析它。证据在 server/internal/util/mention.go——MentionRe的类型组是(member|agent|squad|issue|all)不含project所以后端永远不会把它当作 mention 处理它不会入队任何任务、不会通知任何人——与issuemention 同属“无副作用”契约但比agent/squad会触发任务刻意更弱。mention_test.go 中的匹配用例也印证了类型集合边界。各客户端的呈现差异这也是技能文档明确交代的Web / Desktop在RichLinkpackages/views/rich-content/rich-content.tsx与编辑器MentionViewpackages/views/editor/extensions/mention-view.tsx中渲染为带项目图标与当前标题的 chipMobile没有 chip——apps/mobile/lib/markdown/markdown.tsx 保留默认富链接样式仅在onLinkPress中路由点击点击打开项目。因此优先使用 mention 形式而非粘贴项目 URL裸的站内项目 URL 只有在 web/desktop 上会被parseWorkspaceEntityLink自动 unfurl 成同样的 chip且其解析条件相当严格——必须同源通过URL解析判定而非前缀测试、无 query/fragment、匹配当前 workspace slug、id 必须唯一定位一个实体UUID或copyLink产出的 issue 标识形式如MUL-123解析不到实体时回退为普通链接MUL-5499。在移动端裸 URL 仍会交给Linking.openURL交给系统浏览器把读者带出应用。对 Agent 一侧mention://链接的说明位于 runtime brief 的 Mentions 段落由writeMentionsserver/internal/daemon/execenv/runtime_config_sections.go生成。实战添加资源的时机与错误上下文排查何时该加/改资源摘自 SKILL.md当用户要求“持久项目上下文”时——例如“把这个 GitHub repo 绑到项目上”“以后都用这个 repo”“agent 总是拿不到这个项目的仓库”“这个项目要在我的本地目录里跑”。注意区分multica repo checkout是任务局部的检出状态而项目资源是持久的、影响未来任务。排查“上下文不对”的五步法multica project get project-id --output jsonmultica project resource list project-id --output json核对github_repo.resource_ref.url/ 可选ref/default_branch_hint以及local_directory.resource_ref.daemon_id更新资源是持久变更更新后以重新 list 作为验证若资源与期望的任务上下文一致再往下查 runtime / 仓库检出路径。副作用提醒项目与资源的所有增删改都修改持久工作区状态并影响未来任务除非用户明确要求某个具体本地路径改动local_directory前应先行确认。【免费下载链接】multicaMake humans and AI agents work as one team — open-source and self-hostable.项目地址: https://gitcode.com/GitHub_Trending/mu/multica创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考