Skip to content

模块拆分设计 #3

Description

@SATA260

1. 文档定位

本文将 MVP 拆分为六个一级功能模块,定义每个模块的职责、功能边界和核心归属,并通过端到端用户故事与伪代码说明模块协作关系。

本文中的“项目”是产品领域对象,表示一个本地 Git 项目及其远端映射;不使用 Repository 作为领域对象名称。后端数据访问层如需使用 Repository 模式,应使用 ProjectStoreTaskStore 等名称,避免和产品概念混淆。

.codedock 分为两个互不混用的位置:

位置 归属 保存内容 是否进入 Git
<项目根>/.codedock/ 项目与团队 规则、Commit 约定、Issue/PR 模板、可共享提示词 可以,由团队决定
~/.codedock/projects/<project-id>/ 本机用户与 CodeDock 工作分组、任务、会话、运行、审批、GitHub 快照、变更集、测试结果、本机草稿 不可以

系统密钥、登录凭据和自动批准策略不属于任一 .codedock 目录,应保存在系统密钥链或等价安全存储。下文“本机状态”均指第二个目录中的数据。

2. 模块总览

模块 解决的问题 核心归属 不负责
项目与 Git 工作台 管理本地项目、Worktree、改动和 Git 操作 项目、Worktree、Git 状态、暂存内容、Git 操作记录、Commit Message 草稿 任务编排、Agent 运行、GitHub 内容同步
任务看板与工作分组 将研发目标和相关本地、远端、Agent 信息组织为可操作任务 工作分组、任务、任务状态、任务关联关系 执行 Git 命令、运行 Agent、拉取 GitHub 内容
Agent 编排与会话 统一发起、观察、审批和接管不同 Agent 的会话 会话、运行、审批、运行事件、Agent 适配 保存任务定义、直接决定 Git 暂存范围、发布远端内容
项目上下文与团队规范 加载项目规则、模板和用户预置,生成可预览的追加上下文 规范快照、提示词预置、模板、上下文包 覆盖外部 Agent 原始提示词、执行 Git 或 GitHub 操作
GitHub 集成与草稿发布 同步远端 Issue/PR、解析链接、生成和发布本机草稿 GitHub 资源、同步快照、本机 Issue/PR 草稿、发布确认 执行本地 Commit、拥有任务或会话的资源关联、替用户确定 PR 目标分支
变更归属与任务结果 识别 Agent 产生的变更,形成可追溯结果并提交暂存建议 变更集、文件归属、测试结果、任务结果摘要 直接执行 git add、生成 Commit Message、决定任务业务目标
项目与 Git 工作台 <----> 变更归属与任务结果
          ^                         ^
          |                         |
任务看板与工作分组 <----------> Agent 编排与会话
          ^                         ^
          |                         |
GitHub 集成与草稿发布 --> 项目上下文与团队规范

约束:模块之间只能通过明确的命令、查询结果或事件传递数据。一个模块可以读取其他模块公开的结果,但不能直接修改其他模块拥有的状态。

3. 模块一:项目与 Git 工作台

职责与功能

  • 发现并登记本地项目,读取远端地址、默认分支和项目内 Worktree。
  • 管理 Worktree 的创建、选择、切换、绑定、清理和完整路径展示。
  • 读取并展示分支、提交历史、远端状态、未暂存改动、已暂存改动和 Diff。
  • 执行用户确认后的暂存、取消暂存、Commit、Pull、Push、分支切换、Merge、Rebase、Reset 等 Git 操作。
  • 在操作前说明影响和风险,在操作后保存可追溯的 Git 操作记录。
  • 根据当前 Worktree 的已暂存 Diff、项目规则和关联任务上下文,通过受限的文案生成能力生成 Commit Message 草稿;用户编辑后手动 Commit。
  • 为写入型 Agent 会话提供 Worktree 占用检查和写入租约。

核心归属

归属对象 含义
项目 本地根路径、Git 公共目录、远端映射、默认分支等项目识别信息
Worktree 路径、分支、HEAD、当前状态、当前写入租约
Git 状态快照 工作区、暂存区、分支和远端状态的可展示快照
Git 操作记录 操作请求、用户确认、执行结果、失败原因和关联任务
Commit Message 草稿 基于当前已暂存改动生成、可编辑、尚未提交的提交文案

边界

  • 可以:执行经过权限和用户确认的本地 Git 操作,并向其他模块公开状态与结果。
  • 不可以:创建任务、发起编码 Agent 会话、同步 GitHub Issue/PR、自动发布远端内容。
  • 不可以:将 Commit Message 生成扩大为可修改文件、执行命令或复用写入型 Agent 权限的 Agent 运行;它只读取已暂存 Diff、规则和已关联任务摘要。
  • 不可以:对整个 Worktree 执行无归属的全量暂存;Agent 产生的暂存候选必须来自“变更归属与任务结果”模块。
  • 不可以:在已有写入租约时启动第二个写入型 Agent;只读会话不占用写入租约。

用户故事

用户在“修复登录错误”任务中查看 Codex 的修改。Git 工作台显示 /workspace/app-login-fix、当前分支、已暂存 Diff 和未暂存 Diff。用户只保留与任务相关的已暂存文件,生成 Commit Message 后编辑文案,点击 Commit 并确认,再自行点击 Push。

4. 模块二:任务看板与工作分组

职责与功能

  • 创建、编辑、归档和排序工作分组及其任务卡片。
  • 将多个 GitHub Issue/PR、会话、Worktree、变更集、测试结果和本机草稿关联到一个任务。
  • 为任务指定主 Issue 或主 PR,但允许保留多个补充资源。
  • 聚合任务状态:待处理、运行中、等待确认、需要提权、成功、失败、已取消。
  • 提供分组级批量操作入口,例如查看所有待审批、启动会话、进入任务详情。
  • 根据其他模块发布的事实事件更新任务展示,不反向修改其内部状态。

核心归属

归属对象 含义
工作分组 项目内的任务组织单元、排序和视图偏好
任务 目标、人工补充、状态、主资源、活动 Worktree
任务关联 保存在本机状态中的任务和 GitHub 资源、会话、Worktree、变更集、本机草稿之间的关系
任务状态投影 由 Agent、Git、变更集和发布状态归约出的面向用户状态

边界

  • 可以:管理研发任务的目标、组织关系和展示状态。
  • 不可以:把 GitHub Issue 的正文复制为可编辑的任务事实;远端内容仍由 GitHub 集成模块拥有。
  • 不可以:拥有会话消息中的资源引用;该关系属于 Agent 编排与会话模块,任务只拥有任务级关联。
  • 不可以:直接启动 Shell、Git、gh 或 Agent 进程;只向对应模块提交命令。
  • 不可以:仅因 Agent 成功结束就将任务标记为完成;任务仍可要求用户审阅、Commit 或发布草稿。

用户故事

用户建立“登录改造”工作分组,从 Issue #42 创建“修复登录错误”任务,又把关联 PR #57 和依赖 Issue #31 加入任务。看板卡片随即显示一个正在运行的 Codex 会话、一个等待审批的 Claude 会话和对应 Worktree 的已暂存改动。

5. 模块三:Agent 编排与会话

职责与功能

  • 接入产品自有 Agent、本机 Codex、Claude 及后续 Agent Provider。
  • 创建会话和运行,管理开始、排队、暂停、继续、取消、重试和人工接管。
  • 对写入、执行命令、网络访问等工具请求执行权限检查与用户审批。
  • 记录流式输出、工具调用、运行事件、测试命令结果和失败原因。
  • 把运行请求交给指定 Worktree;写入型运行必须先取得 Git 工作台颁发的写入租约。
  • 将 Agent 完成时的文件观察结果发送给“变更归属与任务结果”模块,而非自行执行暂存。
  • 将会话和运行状态事件发送给任务看板模块,供任务卡片归约展示。

核心归属

归属对象 含义
会话 一个 Agent 的长期对话容器、所属任务和工作目录
会话消息与资源引用 保存在本机状态中的消息,以及消息与 GitHub 资源的关联
运行 一次用户触发的执行、输入快照、状态和终止原因
审批请求 待用户决定的权限、命令或高风险操作请求
运行事件 输出增量、工具调用、状态变化和失败事实
Agent 适配 Codex、Claude、自有 Agent 的调用方式和能力声明

边界

  • 可以:运行 Agent、处理审批、记录运行事实、通知下游变更观察结果。
  • 不可以:覆盖 Codex、Claude 的内置提示词或规则;只能追加经上下文模块生成的 Context Packet。
  • 不可以:直接修改 Git 暂存区、自动 Commit、Push 或发布 Issue/PR。
  • 不可以:自行拼接未经用户确认的全部 GitHub 内容;每次运行只使用其 Context Packet 中列明的资源快照。

用户故事

用户在任务中选择 Codex 和一个 Worktree,点击“开始编码”。系统展示 Context Packet,用户确认后运行启动。Codex 请求运行测试时被记录;它尝试执行需要额外权限的命令时,任务卡片转为“等待确认”。用户同意后运行继续,最终将文件变更观察结果交给变更归属模块处理。

6. 模块四:项目上下文与团队规范

职责与功能

  • 读取项目级 .codedock/ 中版本化的共享提示词预置、规则、Commit 约定、Issue/PR 模板。
  • 读取本机级 .codedock/ 中用户私有的提示词预置;本机预置只能追加,不能削弱项目规则。
  • 兼容读取项目中的 AGENTS.mdCLAUDE.md.github/ 模板。
  • 合并项目规则、任务目标、用户补充、选中的 GitHub 快照和 Worktree 信息,生成可预览的 Context Packet。
  • 为 Git 工作台提供 Commit Message 规则和模板,为 GitHub 集成提供 Issue/PR 草稿模板。
  • 在创建运行时固定上下文版本;后续配置变化不影响已开始的运行。
  • 给出规则冲突或缺失的诊断,但不代替用户修改项目规则。

核心归属

归属对象 含义
项目规范快照 项目级规则文件来源、版本、加载结果和诊断
提示词预置 项目级共享或本机私有的、可追加到任务或 Agent 的提示词片段
模板 Commit、Issue、PR 文案的结构和默认字段
Context Packet 某次 Agent 运行实际使用的追加上下文和资源版本

边界

  • 可以:读取、合并、校验和输出规则、模板及上下文快照。
  • 不可以:保存密钥、模型账号、自动批准策略等机器私有信息到任一 .codedock/;这些内容使用系统安全存储。
  • 不可以:发起 Agent、写入项目代码、执行 Git 命令或调用 GitHub CLI。
  • 不可以:覆盖外部 Agent 的原生系统提示词;产物始终是追加上下文。

用户故事

团队在项目级 .codedock/ 中规定提交格式、PR 模板和“登录模块先补测试”的提示词;用户在本机级 .codedock/ 保存个人的额外提示词。用户启动任务时,系统显示本次 Codex 将获得的追加上下文,其中包含适用规则、Issue #42 的同步快照、用户补充和目标 Worktree 路径。用户确认后才启动运行。

7. 模块五:GitHub 集成与草稿发布

职责与功能

  • 使用 GitHub CLI 同步项目远端的 Issue、PR、评论和必要的 PR 元数据。
  • 保存远端内容的同步快照、原始 URL、同步时间和版本信息,明确本地内容可能过期。
  • 解析对话中的 GitHub Issue/PR 链接,返回可由任务模块或会话模块关联的规范化资源。
  • 支持从远端资源创建任务;任务级关联由任务看板保存,会话消息级关联由 Agent 编排保存。
  • 根据 Agent 产物和模板创建可编辑的本机 Issue/PR 草稿,保存到 ~/.codedock/projects/<project-id>/drafts/
  • 在用户确认目标仓库、源分支、目标分支、标题与正文后,通过 GitHub CLI 进行发布。

核心归属

归属对象 含义
GitHub 资源 远端 Issue 或 PR 的规范化标识、原始链接和基础元数据
同步快照 特定时间获得的正文、评论、标签、状态和版本信息
本机草稿 保存在本机状态中的待发布 Issue/PR 标题、正文、模板来源、关联任务和文件路径
发布确认 用户确认的目标、内容和发布时间,及其执行结果

边界

  • 可以:读取 GitHub 内容、维护快照、生成草稿、在用户确认后调用 gh 发布。
  • 不可以:拥有资源与任务或会话的关联;它只提供规范化资源和快照,由调用模块保存关联。
  • 不可以:把本地快照当作实时远端事实;界面必须显示最近同步时间并允许刷新。
  • 不可以:在没有确认的情况下创建、修改、关闭 Issue/PR,发布 Review,或替用户决定 PR 的源分支和目标分支。
  • 不可以:执行本地 Git Commit、Push 或管理 Worktree。

用户故事

用户在会话中粘贴 https://github.com/acme/login/issues/42。GitHub 集成识别为 Issue,会话模块在本机状态中记录消息引用,并让用户选择是否再链接到当前任务。编码完成后,用户要求生成 PR 草稿;系统按照项目模板写入 ~/.codedock/projects/<project-id>/drafts/pr-login-fix.md。用户编辑后确认目标分支为 main,才允许调用 GitHub CLI 创建 PR。

8. 模块六:变更归属与任务结果

职责与功能

  • 在 Agent 运行开始前记录 Worktree 基线:HEAD、暂存区状态和文件状态。
  • 在运行结束、取消或失败时对比基线与当前状态,识别该运行观察到的文件修改、删除和新增文件。
  • 区分用户原有改动、其他运行已归属的改动和当前运行候选改动;对无法安全判断归属的文件标记为待用户决定。
  • 汇总测试命令、退出码、输出摘要和 Agent 自述,形成运行结果和任务结果摘要。
  • 向 Git 工作台提交“可暂存候选”而非直接暂存;Git 工作台执行实际 git add,用户仍可取消或调整。
  • 向任务看板发布变更集、测试结果和可审阅状态。

核心归属

归属对象 含义
运行基线 运行开始时的 HEAD、索引和工作区文件状态
变更集 与运行关联的候选文件、Diff 摘要、归属置信度和审阅状态
测试结果 命令、退出码、关键输出、运行时间和所属运行
任务结果摘要 Agent 输出、变更集和测试结果的可读聚合

边界

  • 可以:比较快照、计算归属建议、汇总结果、通知 Git 工作台和任务看板。
  • 不可以:直接调用 git addgit commitgit push;Git 操作始终属于 Git 工作台。
  • 不可以:把“运行中观察到变化”自动认定为“Agent 所做变化”;已有用户改动、并发改动和不确定改动必须保守处理。
  • 不可以:修改任务目标、远端资源正文或 Agent 会话历史。

用户故事

Codex 开始前,Worktree 已有用户修改的 README.md。Codex 结束后改动了 login.ts、新增 login.test.ts,并触及 README.md。变更归属模块只把前两项列为可暂存候选,把 README.md 标记为“与原有修改重叠,待用户决定”。Git 工作台据此暂存两个安全文件。

9. 端到端用户故事:从 Issue 到本地暂存与 PR 草稿

用户准备处理 GitHub Issue #42“修复登录错误处理”。他打开项目,在看板中创建任务,关联 Issue #42、一个依赖 Issue 和正在讨论的 PR。用户选择一个新的 Worktree,确认运行上下文后启动 Codex。Codex 修改代码、运行测试,产生的可归属改动进入暂存区。用户生成 Commit Message 并手动 Commit、Push;随后生成并编辑保存在本机数据目录的 PR 草稿,确认目标分支后发布。

9.1 创建任务并关联远端资源

func CreateTaskFromIssue(input CreateTaskFromIssueInput) (Task, error) {
    // GitHub 集成负责把 URL 或编号解析为规范化的 GitHub 资源,
    // 并返回最近一次同步快照;它不创建任务。
    issue := githubResources.ResolveAndRefresh(input.ProjectID, input.IssueReference)

    // 任务看板拥有任务本身和资源关联关系。
    task := tasks.Create(TaskDraft{
        ProjectID:       input.ProjectID,
        GroupID:         input.GroupID,
        Title:           issue.Snapshot.Title,
        PrimaryResource: issue.ID,
        UserNotes:       input.UserNotes,
    })
    tasks.LinkResource(task.ID, issue.ID, RolePrimary)

    // 事件只表达“任务已关联资源”这一事实;GitHub 快照仍由 GitHub 模块维护。
    events.Publish(TaskResourceLinked{TaskID: task.ID, ResourceID: issue.ID})
    return task, nil
}

9.2 创建 Worktree 并启动 Agent

func StartCodingRun(input StartCodingRunInput) (Run, error) {
    task := tasks.Get(input.TaskID)

    // Git 工作台创建 Worktree,并检查该路径是否存在写入型会话占用。
    worktree := gitWorkspace.CreateOrSelectWorktree(
        task.ProjectID,
        input.WorktreeChoice,
        input.BranchName,
    )
    lease := gitWorkspace.AcquireWriteLease(worktree.ID, input.SessionID)
    if lease.IsDenied() {
        // 调用方展示“继续已有会话 / 只读运行 / 新建 Worktree”三个选项。
        return Run{}, ErrWorktreeBusy
    }
    tasks.BindWorktree(task.ID, worktree.ID)

    // 上下文模块从任务关联中选择资源快照,追加项目规则和用户补充。
    // 它不改写任何外部 Agent 的原始提示词。
    packet := projectContext.BuildContextPacket(ContextRequest{
        TaskID:              task.ID,
        WorktreeID:          worktree.ID,
        SelectedResourceIDs: input.ResourceIDs,
        UserInstructions:    input.UserInstructions,
        AgentKind:           input.AgentKind,
    })
    RequireUserConfirmation(packet)

    // 变更归属模块在写入前记录基线,用于把用户已有改动排除出候选暂存内容。
    baseline := changeResults.RecordRunBaseline(worktree.ID, input.SessionID)

    // Agent 编排模块创建会话和运行;它只使用确认后的 Context Packet。
    run := agents.StartRun(StartRunRequest{
        SessionID:      input.SessionID,
        TaskID:         task.ID,
        WorktreeID:     worktree.ID,
        WriteLeaseID:   lease.ID,
        ContextPacket:  packet,
        BaselineID:     baseline.ID,
        AgentKind:      input.AgentKind,
    })
    return run, nil
}

9.3 处理审批、变更归属和暂存

func OnRunFinished(event RunFinished) error {
    // Agent 编排模块已保存运行日志和工具结果,现只公布终态事实。
    run := agents.GetRun(event.RunID)

    // 变更归属模块把运行前基线与当前 Worktree 对比。
    // 它将不确定或与既有修改重叠的文件留给用户,而非自动暂存。
    changeSet := changeResults.AnalyzeRunChanges(run.BaselineID, run.WorktreeID)
    tests := changeResults.CollectTestResults(run.ID)
    changeResults.Publish(TaskResultReady{
        TaskID:      run.TaskID,
        ChangeSetID: changeSet.ID,
        TestResultIDs: tests.IDs,
    })

    // Git 工作台是唯一执行 Git index 写入的模块。
    // 仅将归属明确且用户确认的候选文件加入暂存区。
    approvedPaths := RequireUserFileSelection(changeSet.SafeCandidatePaths)
    gitWorkspace.StagePaths(run.WorktreeID, approvedPaths, StageReasonAgentRun)

    // 任务看板消费事件,展示“待审阅 / 已暂存 / 测试结果”。
    tasks.UpdateProjection(run.TaskID)
    gitWorkspace.ReleaseWriteLease(run.WriteLeaseID)
    return nil
}

9.4 提交代码和发布 PR 草稿

func CommitAndPublish(input CommitAndPublishInput) error {
    // Commit Message 归 Git 工作台:输入是已暂存 Diff、项目规范和任务引用。
    message := gitWorkspace.GenerateCommitMessage(CommitMessageRequest{
        WorktreeID: input.WorktreeID,
        TaskID:     input.TaskID,
    })
    finalMessage := RequireUserEditAndConfirmation(message)
    gitWorkspace.Commit(input.WorktreeID, finalMessage)

    // Push 具有远端影响,始终独立确认。
    gitWorkspace.Push(RequireUserPushConfirmation(input.WorktreeID))

    // GitHub 集成基于模板、任务资源和用户提供的目标分支生成本机 PR 草稿。
    // 草稿保存在用户的本机数据目录,此时尚未调用 GitHub,也不会进入 Git 暂存区。
    draft := githubResources.CreatePullRequestDraft(PullRequestDraftRequest{
        TaskID:       input.TaskID,
        SourceBranch: input.SourceBranch,
        BaseBranch:   input.BaseBranch,
    })
    githubResources.SaveDraftToLocalStore(draft)

    // 发布前必须再次让用户确认仓库、源分支、目标分支、标题和正文。
    confirmation := RequireUserPublishConfirmation(draft)
    githubResources.PublishPullRequest(confirmation)
    return nil
}

10. 模块间事件

事件 产生模块 消费模块 表达的事实
github.resource_synced GitHub 集成与草稿发布 任务看板、项目上下文 某个远端资源已有新的本地快照
task.resource_linked 任务看板与工作分组 项目上下文 任务已关联一个远端资源
worktree.write_lease_changed 项目与 Git 工作台 任务看板、Agent 编排 Worktree 的写入占用已变化
run.state_changed Agent 编排与会话 任务看板 一次 Agent 运行的状态已变化
approval.required Agent 编排与会话 任务看板 某个运行等待用户审批
task_result.ready 变更归属与任务结果 任务看板、Git 工作台 可审阅变更集与测试结果已形成
git.operation_completed 项目与 Git 工作台 任务看板、GitHub 集成 一次本地 Git 操作已完成
draft.publish_completed GitHub 集成与草稿发布 任务看板 本机草稿已成功发布到 GitHub

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureOverall module split and boundaries

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions