MindsHub Cowork 从源码构建到多分支协作:make 工作流、dev.env 机制与容器部署全景
本文以 MindsHub 仓库的主 README(README.hi.md)为核心骨架,系统讲解 MindsHub Cowork 这款"统一 AI 工作空间"的产品能力边界,并深入剖析其从源码构建(make setup / make dev / make flush)、容器化部署到基于 git submodule 的多分支协作工作流(dev.env + make use / make pin)的完整实操路径。读完本文,你能够在本地从零搭建整套 Cowork 技术栈,理解超级项目(superproject)如何把前端、Agent 后端与数据引擎拼装在一起,并掌握在多开发者场景下不污染 git status 的模块化分支开发方法。
一、MindsHub Cowork 是什么
MindsHub Cowork 是一个"让开源模型真正干活"的统一工作空间(unified workspace):你可以把整个项目交给它——应用开发、网站、研究、分析、报告、定时运营任务——然后直接获得可分享、可发布的成品。官方口号是"随时更换模型——你构建的一切都会保留下来"(Swap the model anytime — keep everything you've built)。它是开源的,可运行在任何地方:你自己的机器、你的 VPC,或者托管应用。
当前仓库是一个平台超级项目(platform superproject):它把桌面/网页应用、Agent 后端和数据引擎聚合在一起,使你可以从源码构建并运行完整的技术栈。从 CLAUDE.md 可以看到,仓库包含 4 个子模块,各自对应一个独立仓库:
| 路径 | 对应仓库 | 跟踪方式 |
|---|---|---|
frontend |
mindsdb/cowork |
tag-pinned |
backend/core_api |
mindsdb/cowork-server |
tag-pinned |
backend/core_agent |
mindsdb/anton |
tag-pinned |
backend/data-vault |
mindsdb/data-vault |
main 分支 |
1.1 核心能力:仓库内置的五大组件
主 README 用 "What's inside" 一节概括了 Cowork 的五大能力,这也是理解整个技术栈的分水岭:
- Connected data(数据连接)。 一个安全的数据保险库(vault)把 BigQuery、Postgres、Gmail、Drive、HubSpot、Notion、Linear 等系统连接起来。凭据按连接范围隔离——Agent 永远看不到原始密钥(raw key)。对应的数据引擎即
backend/data-vault子模块。 - Model Router(模型路由器)。 在前沿模型(Claude、GPT、Gemini)与开源模型(DeepSeek、Qwen、Kimi)之间切换,而不必为每个提供商单独配置密钥。
- Open agents(开放 Agent)。 运行可互换的开源 Agent 框架(harness)——Anton(默认)和 Hermes,可从下拉菜单中随时替换。Anton 对应
backend/core_agent子模块(mindsdb/anton仓库)。 - Artifacts(制品)。 把 Agent 的输出转化为文档、仪表盘、应用和代码,并发布到可访问的 URL 上。
- Memory, skills & scheduling(记忆、技能与调度)。 跨会话记忆、可复用的技能库、以及按计划运行的任务。
面向所有知识工作者——创作者、策略制定者和运营人员——README 归纳了两类典型用法:
- 自动化(Automate):涉及读写的重复性多步骤工作,如报告、监控、周期性工作流和定时运营任务;
- 构建(Build):无需工程背景即可构建内部 AI 工具与制品——应用、仪表盘、演示文稿、文档、分析——并发布到线上 URL 与团队分享。
二、快速开始:四条入门路径
主 README 的 "Get started" 一节给出了四条路径,按"是否愿意从源码构建"来区分:
- Web——零安装。 打开 console.mindshub.ai 并登录即可;
- macOS. 下载桌面应用安装包(
.pkg格式); - Windows. 下载桌面应用安装包(
.exe格式); - Linux. 从源码构建(见下一节)。
免费开始使用;Pro 计划会解锁全部前沿模型与私有制品。
对于开发者,真正有价值的是第四条路径——从源码构建。下一节完整展开。
三、从源码构建完整技术栈
以下三步流程完整继承自主 README 的 "Build from source" 一节,并结合 Makefile 的实现细节补充了每一步到底做了什么。
3.1 第一步:克隆超级项目(含子模块)
git clone --recurse-submodules https://gitcode.com/GitHub_Trending/mi/mindshub.git
cd mindshub
--recurse-submodules 是必须的,因为 frontend、backend/core_api、backend/core_agent、backend/data-vault 都以 git submodule 形式挂载在父仓库中。如果克隆时忘了加该参数,可以事后进子模块目录执行 git submodule update --init --recursive 补齐(见 CLAUDE.md)。
3.2 第二步:安装依赖(make setup)
make setup
从 Makefile 的实现可以看到,make setup 并非一个单条命令,而是由三个"盖章"目标(stamp)驱动的一组依赖安装:
| 目标 | 依据的依赖清单 | 实际执行的命令 |
|---|---|---|
前端 node_modules/.package-lock.json |
frontend/package-lock.json |
npm --prefix frontend ci |
API 后端 .venv |
backend/core_api/uv.lock |
uv sync --directory backend/core_api |
Agent 后端 .venv |
backend/core_agent/uv.lock |
uv sync --directory backend/core_agent |
也就是说:前端走 npm 的 lockfile 精确安装,两个 Python 后端(cowork-server 与 anton)分别用 uv 同步出独立的虚拟环境。Makefile 用"产物文件是否存在"作为缓存判断——只要 stamp 文件存在就跳过对应安装,重复执行 make setup 是幂等且低成本的。
3.3 第三步:选择运行模式
主 README 给出了完整的运行模式与命令对照表,全部通过 make 目标执行:
| 模式 | 命令 |
|---|---|
| 带热重载的桌面应用(Electron) | make dev 或 make watch |
| 浏览器中带热重载的 Web 应用 | make dev-web |
| 生产构建 | make build |
| 打包 macOS 版本 | make dist-mac |
| 打包 Windows 版本 | make dist-win |
从本地未提交的源码构建 macOS .app |
make pack-local |
| 清除全部本地安装与数据(全新开始) | make flush |
结合 Makefile 的源码,各模式的实际行为是:
make dev/make watch(二者等价,watch 是别名):后台用uv run uvicorn cowork.server:app --reload启动 FastAPI 后端,并对backend/core_api/cowork与backend/core_agent/anton两个目录开启--reload-dir热重载;前台运行npm --prefix frontend run dev启动 Electron 开发模式。trap 'kill 0' SIGINT SIGTERM EXIT保证退出时一并清理后台进程。make dev-web:后端部分与dev相同,前端改为BUILD_TARGET=web npm run dev:renderer -- --open,即在浏览器中打开 Web SPA 版本。make build/make dist-mac/make dist-win:分别对应npm run build、npm run dist:mac、npm run dist:win,是纯前端的打包链路。make pack-local:先执行server-local把本地backend/core_api装成桌面服务端,然后npm run build+npx electron-builder --mac --arm64 --dir在/tmp下构建(iCloud 安全,不产出 DMG),最终生成frontend/release/mac-arm64/MindsHub Cowork.app,全程无需 push 任何代码。
此外 Makefile 还提供了 README 表格之外的 Docker 链路:make docker-build / make docker-up / make docker-down,直接委托给 docker compose。
3.4 make flush:破坏性的"全新开始"
全新开始:
make flush会移除本地运行时(cowork-serveruv 工具与backend/*/.venv)并删除应用状态:~/.anton(模型提供商密钥)与~/.cowork(数据库、hermes、项目)。用于测试从零安装流程或从损坏的安装中恢复。它会提示确认——传入FORCE=1可跳过确认。下一次make setup或应用启动会自动重新安装一切。⚠️ 这会删除你的会话(conversations)与已保存的密钥。
从 Makefile 可以看到 flush 的确切删除清单:cowork-server uv 工具(含遗留的 anton-agent 工具)、backend/core_api/.venv 与 backend/core_agent/.venv、~/.anton(提供商密钥/.env)、~/.cowork(数据库、hermes、项目)。Makefile 注释还特意说明:它刻意保留 uv 本身及 uv 托管的 Python 运行时(属于共享基础设施,不属于 anton/cowork 安装的一部分)。CLAUDE.md 补充了一条重要背景:桌面应用与 Makefile 开发流程共享 ~/.cowork/cowork.db,如果两条路径的服务端版本漂移导致数据库迁移不一致,应用会在启动时崩溃(Can't locate revision …),此时用 make flush 复位是最干净的手段。
3.5 本地 Web 开发的补充细节
CLAUDE.md 还给出了浏览器模式的补充实操,值得与 make dev-web 互为参照:
-
初始化子模块后,可
cd frontend && npm install && npm run dev:web,打开http://localhost:5173/,FastAPI 后端会自动在http://127.0.0.1:26866启动; -
跳过 SSO 鉴权(本地开发必需):默认 Web 应用首次加载会重定向到 MindsHub SSO。绕过方式是创建
frontend/src/renderer/.env(Vite 的根是src/renderer而不是frontend/):echo "VITE_SKIP_AUTH=true" > frontend/src/renderer/.env然后重启
npm run dev:web,应用会直接进入 onboarding 页面,可在此录入 BYOK API key。 -
首次运行的符号链接修复:
dev:web脚本期望在~/.local/share/uv/tools/anton/找到 uv 安装的工具,但工具可能实际名为anton-agent。若出现 "Anton Python interpreter not found",执行:ln -s ~/.local/share/uv/tools/anton-agent ~/.local/share/uv/tools/anton
四、容器化部署:docker-compose 双服务栈
仓库根目录的 docker-compose.yml 定义了由 api 与 web 两个服务组成的完整部署栈(构建上下文分别为 docker/api.Dockerfile 与 docker/web.Dockerfile):
- api 服务:对外暴露
26866:26866端口(与本地开发时 FastAPI 的端口一致),环境变量COWORK_SERVER_HOST=0.0.0.0、COWORK_SERVER_PORT=26866、DATABASE_URI=sqlite:////home/cowork/.cowork/cowork.db;数据持久化在命名卷cowork-data(挂载到/home/cowork/.cowork);内置健康检查——每 30 秒用 Python 的urllib请求http://127.0.0.1:26866/health,失败重试 3 次。注释行还预留了ANTHROPIC_API_KEY的注入位。 - web 服务:基于 docker/web.Dockerfile 构建,对外暴露
3000:80端口,通过depends_on: api: condition: service_healthy保证后端健康后才启动(静态资源与反代由 docker/nginx.conf 承担)。
两条服务都设置了 restart: unless-stopped,因此该 compose 栈可以直接作为"自托管一套完整 Cowork"的最小部署单元使用。
五、功能分支开发工作流:dev.env 与 submodule 协同
这是主 README "Working on feature branches (submodules)" 一节的核心内容,也是本仓库工程化设计中最值得细读的部分。
5.1 问题背景:超级项目如何 pin 子模块
该仓库是一个超级项目:父仓库把每个模块(frontend、backend/core_api、backend/core_agent、backend/data-vault)都 pin 到一个具体 commit。如果在子模块里切分支开发,默认情况下父仓库的 git status 会立刻变"脏",多个开发者还会因 pin 值互相打架。
解决方案的两根支柱是:
.gitmodules为每个子模块设置ignore = all。CLAUDE.md 特别强调:这是唯一能完全消除"new commits in<module>"提示的配置(ignore = dirty做不到),因此你在子模块里的日常分支工作永远不会以超级项目变更的形式出现——父仓库的git status始终保持干净;- pin 只通过
make pin移动。这是一个刻意为之的、可评审的提交(commit),杜绝了 pin 值被日常操作悄悄改动。
5.2 第一步:在 gitignored 的 dev.env 里选择分支
cp dev.env.example dev.env # 然后设置 REF=feat/my-thing(或按模块设置 API_REF=…)
dev.env.example 的模板说明了两种写法,且注释明确指出 dev.env 被 gitignore、永不入库——每位开发者各用各的分支,不触碰任何共享文件:
# 所有模块用同一个分支:
# REF=feat/my-thing
# …或按模块单独覆盖(这些值优先于 REF):
# FRONTEND_REF=feat/ui-thing
# API_REF=feat/server-thing
# AGENT_REF=feat/agent-thing
从 Makefile 可以看到解析逻辑:-include dev.env 之后,REF 默认 main,API_REF/AGENT_REF/FRONTEND_REF 均回退到 $(REF)。此外 Makefile 还会把分支选择导出成环境变量 COWORK_SERVER_REF(取自 API_REF)与 ANTON_REF(取自 AGENT_REF)——这是 Electron 桌面服务端安装链路的 key(见 frontend/src/main/server-source.ts)。一个细节:只有当 AGENT_REF 不是 main 时,才会追加 --with "anton-agent @ git+…@$(AGENT_REF)",因为 uv 会拒绝冗余的 --with 覆盖。
5.3 第二步:make 命令如何跟随 dev.env
主 README 给出了完整命令表——"一个旋钮,覆盖两条运行路径":
| 命令 | 作用 |
|---|---|
make use |
在所有子模块中 checkout dev.env 指定的分支 |
make dev / make watch |
以热重载方式运行 Electron 应用,直接跑本地子模块源码 |
make dev-web |
以热重载方式运行 Web SPA,直接跑本地子模块源码 |
make server + make app |
从配置好的分支(重新)安装桌面服务端,然后启动应用 |
make server-local + make app-local |
从本地未提交的源码安装桌面服务端,然后启动应用 |
make pack-local |
从本地未提交源码构建 macOS .app(无需 push) |
make refs |
显示下一次运行将使用哪些 refs |
make baseline |
把所有子模块重置回被 pin 的 commit |
make pin |
把子模块当前 commit 记录为超级项目的 pin(一次刻意的提交) |
结合 Makefile 的实现,两条运行路径的差异值得展开:
- 本地源码路径(
make dev/make dev-web):直接执行子模块里 checkout 出来的源码(uvicorn--reload),所以它天然跟随make use切到的分支,未提交的改动也会即时生效; - 桌面服务端路径(
make server+make app):用uv tool install "git+https://github.com/mindsdb/cowork-server.git@$(API_REF)"从指定分支安装cowork-server,Python 版本锁定>=3.12,<3.14,并使用UV_PYTHON_PREFERENCE=only-managed强制使用 uv 托管的运行时;make app以COWORK_SERVER_DISABLE_AUTOUPDATE=1启动 Electron 应用,确保自动更新机制不会把你分支上的服务端"打回原形"; - 本地未提交源码路径(
make server-local/make app-local/make pack-local):uv tool install直接指向$(CURDIR)/backend/core_api(本地路径而非 git 地址),完全不需要 commit/push。若想同时本地开发core_agent,把backend/core_api/pyproject.toml中的[tool.uv.sources]里anton-agent改为{ path = "../../core_agent" }再重跑make server-local即可(make server-local的 stdout 会打印这条提示)。
make use 的实现(Makefile#L126-L133)是对三个子模块依次 git fetch -q origin <ref> + git checkout <ref>,完成后打印 ✓ on: frontend=… core_api=… core_agent=…;make baseline 则等价于 git submodule update --init --recursive,把一切钉回超级项目 pin 的 commit。由于 ignore = all 不会在 git status 里提醒你"队友的 pin bump 让某模块落后了",CLAUDE.md 的建议是:拉取超级项目更新之后主动跑一次 make baseline 对齐。
make pin(Makefile#L139-L144)执行 git add 四个子模块路径,若无差异则提示 "Nothing to pin",否则自动提交 chore: bump submodule pins,并提醒你把超级项目 push 出去以共享新 pin。
5.4 完整工作流速览
把 CLAUDE.md 与 README 串起来,一个典型的多开发者协作周期是:
cp dev.env.example dev.env,写入自己要跟的分支;make refs确认下一次运行将用的 refs;make use切换子模块分支;make dev(或make dev-web)开发本地路径,或make server && make app(本地路径则make app-local)走桌面路径——CLAUDE.md 特别提醒两条路径必须保持同一 ref,因为它们共享~/.cowork/cowork.db;- 在子模块内按常规流程建分支、commit、push(子模块初始都是 detached HEAD,需先
git checkout main或新建分支); - 子模块 PR 合并后,回到父仓库执行
make pin,产生一次可评审的 pin 提交并 push; - 需要回到基线时执行
make baseline。
六、随处部署:云、VPC 与离线环境
主 README 的 "Deploy anywhere" 一节声明了 Cowork 的部署姿态:面向 云、VPC、on-prem(本地机房)、air-gapped(气隙隔离)、混合 五类基础设施设计,目标是让你对自己的基础设施、模型、权限和数据保持完全控制。结合前文可知,这一姿态在仓库中的落点包括:docker-compose.yml 定义的最小双服务栈(SQLite 持久化于命名卷)、从源码构建后落到任意 Linux 机器的 make 链路,以及模型路由器 + 数据保险库带来的"密钥按连接范围隔离、Agent 不见 raw key"的权限模型——这些正是私有化/气隙部署场景下的关键约束。
七、支持、贡献、安全与许可证
- 提问:加入官方 Discord 社区;
- 报 Bug:带复现步骤在仓库 issues 区开 issue;
- 文档:指南、安装与 API 文档见官方 docs 站点,仓库内亦有本地文档目录 docs/(含 docs/index.html 等页面);
- 企业 SLA / 自定义部署:通过官网联系团队。
Cowork 是开源项目,欢迎代码、集成、文档、bug 报告与功能想法等形式的贡献,贡献规范见 CONTRIBUTING.md。
安全:发现安全漏洞时不要开公开 issue,应通过仓库的安全策略渠道私密上报(仓库内含 SECURITY.md)。
许可证:本仓库以 MIT 许可证 发布(见 LICENSE);各捆绑组件(即各子模块仓库)受其自身许可证约束,细节需查阅对应子模块仓库。
八、关键文件索引
| 文件 | 说明 |
|---|---|
| Makefile | 全部 make 目标的定义:setup / dev / dev-web / flush / use / pin / baseline / server / app-local / pack-local 等 |
| dev.env.example | 模块分支选择的 gitignored 模板(REF / FRONTEND_REF / API_REF / AGENT_REF) |
| CLAUDE.md | 子模块结构、多开发者分支工作流、本地 Web 开发(含跳过 SSO 与符号链接修复)、flush 说明的完整版 |
| docker-compose.yml | api(26866)+ web(3000)双服务栈、健康检查与数据卷定义 |
| docker/api.Dockerfile / docker/web.Dockerfile / docker/nginx.conf | 容器构建与反代配置 |
| LICENSE | MIT 许可证 |
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00