MindsHub Cowork 全栈源码构建与模块化开发工作流:superproject、Makefile 与子模块分支管理
MindsHub Cowork 是一个"让开源模型替你干完活"的统一工作区:你委托整个项目(应用、网站、调研、分析、报告、定时任务),它产出可直接分享的结果。这个仓库是平台的 superproject——把桌面/网页应用、Agent 后端和数据引擎聚合成一个可以从源码构建、运行的完整技术栈。本文以仓库的葡萄牙语版 README 为主线,结合 Makefile、CLAUDE.md、.gitmodules 与 docker-compose.yml 的实际实现,讲清楚如何从零构建这套全栈,以及多人如何在子模块分支上并行开发而不污染父仓库。
项目定位:一个"可换模型、数据可控"的协作工作台
README 对 Cowork 的定义是:连接数据源、把工作路由到任意模型(开源或闭源)、运行开源 Agent,并把它们的输出变成可以发布的 Web 应用。它开源、可部署在任何位置——你的机器、你的 VPC,或者托管版应用。
平台内部由五大能力构成(README "O que tem por dentro" 章节):
- Connected data(数据连接):一个安全 vault 连接 BigQuery、Postgres、Gmail、Drive、HubSpot、Notion、Linear 等系统。凭据按连接(connection)粒度隔离——Agent 永远看不到裸密钥。
- Model Router(模型路由):在前沿模型(Claude、GPT、Gemini)与开源模型(DeepSeek、Qwen、Kimi)之间切换,无需为每个提供商单独配置 API Key。
- Open agents(开源 Agent):运行可互换的开源 harness——Anton(默认)和 Hermes,通过菜单下拉切换。
- Artifacts(产物):把 Agent 输出变成文档、仪表盘、应用和代码,并发布到一条可访问的 URL 上。
- Memory, skills & scheduling(记忆、技能与调度):跨会话记忆、可复用的技能库、按计划时间运行的任务。
面向的知识工作者场景归纳为两类:Automate——自动化涉及读写的重复性多步骤工作(报告、监控、周期性工作流、定时操作);Build——无需工程背景即可构建内部 AI 工具与产物(应用、仪表盘、演示文稿、文档、分析),并发布到活跃 URL 与团队共享。
Superproject 的模块构成
这个仓库本身不包含各模块的代码,而是用 Git 子模块把四个独立仓库钉(pin)在特定提交上。从 .gitmodules 和 CLAUDE.md 可以看到模块与上游仓库的对应关系:
| 子模块路径 | 上游仓库 | 跟踪方式 |
|---|---|---|
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 分支 |
值得注意的一个细节:.gitmodules 中每个子模块都配置了 ignore = all。这意味着无论子模块当前处于什么分支、工作区有什么改动,父仓库的 git status 始终保持干净——后文分支开发工作流的"无污染"特性正是靠它实现的。
使用方式选择:托管版、桌面版与源码构建
README 给出了四条起步路径,按"安装成本"递增排列:
- Web 版:无需安装,打开官方控制台登录后直接使用;
- macOS:下载桌面应用安装包(
.pkg); - Windows:下载桌面应用安装包(
.exe); - Linux:从源码构建(下节详述)。
README 同时说明商业模式:基础使用免费,Pro 计划解锁全部前沿模型与私有产物(private artifacts)。对于希望完全掌控基础设施、模型与数据的团队,源码构建是核心路径——这也是本文其余部分的主题。
从源码构建:三步完成全栈安装
第 1 步:克隆仓库(含子模块)
git clone --recurse-submodules https://github.com/mindsdb/minds.git
cd minds
--recurse-submodules 会递归初始化四个子模块。如果克隆时忘了加该参数,之后可以用 git submodule update --init --recursive 补上(见 CLAUDE.md 的 "Initialize after cloning without submodules" 小节)。
第 2 步:安装依赖
make setup
从 Makefile 的实现看,setup 并不是单一命令,而是依赖三个"戳文件"(stamp)目标,保证只在实际变更时重跑:
_NPM_STAMP(frontend/node_modules/.package-lock.json):命中变更时执行npm --prefix frontend ci;_API_STAMP(backend/core_api/.venv):命中变更时执行uv sync --directory backend/core_api;_AGENT_STAMP(backend/core_agent/.venv):同理对backend/core_agent执行uv sync。
也就是说,前端走 npm 锁文件安装,两个 Python 模块(core_api 与 core_agent)各自用 uv 管理虚拟环境。README 徽章标明的 Python 版本要求是 3.10–3.13。
第 3 步:选择运行模式
README 给出的运行模式总表如下(完整继承自原文档):
| 模式 | 命令 |
|---|---|
| 桌面应用(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(两者定义一致,后者是别名):后台用uv run --directory backend/core_api uvicorn cowork.server:app --reload启动 FastAPI 后端,--reload-dir同时监视backend/core_api/cowork与backend/core_agent/anton两个目录,然后在前台执行npm --prefix frontend run dev启动 Electron 应用。Python 与前端都具备热重载。make dev-web:后端启动方式相同,前端则执行BUILD_TARGET=web npm run dev:renderer -- --open,以 SPA 形式在浏览器中运行并自动打开页面。make build:npm --prefix frontend run build,只做渲染层生产构建。make dist-mac/make dist-win:分别对应npm run dist:mac/npm run dist:win。make pack-local:先执行make server-local安装本地服务器,再用electron-builder --mac --arm64 --dir构建,输出目录指向/tmp/minds-build(避免把构建产物写进仓库目录,对使用 iCloud 同步的目录更友好),最终产物落在frontend/release/mac-arm64/MindsHub Cowork.app。
此外 Makefile 中还提供了 README 未强调的 Docker 目标:make docker-build、make docker-up、make docker-down,对应下文"部署"一节。
make flush:一键回到安装前的状态
README 对 flush 的说明是完整的操作依据,这里结合 Makefile 中的实现(L100-L113)逐项核对:
make flush # 删除前会提示确认
make flush FORCE=1 # 跳过确认(适合 CI / 脚本)
它会永久删除:
| 被删除的内容 | 说明 |
|---|---|
cowork-server uv tool(含旧版 anton-agent tool) |
Electron 应用通过 uv tool install 安装的运行时 |
backend/core_api/.venv、backend/core_agent/.venv |
Makefile 开发流程通过 uv sync 构建的 venv |
~/.anton |
提供商 API Key / .env |
~/.cowork |
数据库、hermes、项目 |
适用场景是测试全新安装流程,或从损坏的半成品环境中恢复。警告:它会删掉所有对话和已保存的密钥,不可撤销。之后的下一次 make setup(或启动应用)会从 scratch 重新安装一切。CLAUDE.md 补充了一个边界细节:flush 刻意保留 uv 本身和 uv 管理的 Python 运行时,因为它们属于共享基础设施,不是 Cowork 安装的一部分。
功能分支开发工作流:dev.env 是唯一的分支开关
这是本仓库工程实践中最有信息量的部分。superproject 把每个模块钉在某个提交上,多人在各模块分支上开发时,既不想让父仓库 git status 变脏,也不想为"谁更新 pin"争抢提交。仓库给出的方案是:.gitmodules 里 ignore = all 保证日常分支工作对父仓库完全隐形;分支选择集中放在一个被 git 忽略的 dev.env 文件里;make 是所有引用(ref)的唯一事实来源。
第 1 步:在 dev.env 中选择分支
cp dev.env.example dev.env # 然后设置 REF=feat/my-thing(或按模块设置 API_REF=…)
dev.env.example 模板说明了两种写法:
# 所有模块使用同一个分支:
# REF=feat/my-thing
# …或按模块覆盖(这些变量优先于 REF):
# FRONTEND_REF=feat/ui-thing
# API_REF=feat/server-thing
# AGENT_REF=feat/agent-thing
不设置时默认跟踪 main——这一点在 Makefile 中可以直接验证:-include dev.env 之后有 REF ?= main,且 API_REF、AGENT_REF、FRONTEND_REF 在未显式设置时都回落到 $(REF)。
第 2 步: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 |
显示下一次运行将使用哪些 ref |
make baseline |
把子模块重置回父仓库钉住的提交 |
make pin |
把子模块当前提交记录为 superproject 的 pin(一次有意的提交) |
从 Makefile 的实现看,这里有两条并行的"运行路径",但共用同一套 ref:
- 本地源码路径(
make dev/dev-web):直接执行子模块目录里的代码,跟随make usecheckout 出来的分支,未提交的改动也会被热重载即时拾取。 - Electron 桌面服务器路径(
make server/app):桌面应用运行的是一个通过uv tool install安装的cowork-server,安装时按环境变量COWORK_SERVER_REF/ANTON_REF解析 ref。Makefile 显式导出这两个变量(export COWORK_SERVER_REF := $(API_REF)等),所以make server装出来的服务器与dev.env里配置的分支严格一致;make app还设置了COWORK_SERVER_DISABLE_AUTOUPDATE=1,防止自动更新把你的分支"拽回去"。
make use 的实现就是在三个子模块里逐个 git fetch + git checkout 对应 ref(backend/data-vault 不参与 ref 切换)。make refs 只打印三个模块的 ref,用于运行前核对。make baseline 对应 git submodule update --init --recursive,回到钉住的基线;make pin 则 git add 四个子模块路径并产生一条 "chore: bump submodule pins" 提交——pin 的移动只经过这一条有意的、可评审的路径。
CLAUDE.md 还指出了两条运行路径之间一个容易踩的坑:桌面应用与 Web 开发模式共享同一个 ~/.cowork/cowork.db,因此两条路径上应用的数据库迁移必须兼容,否则应用启动时会报 Can't locate revision … 崩溃;两条路径的 ref 发生漂移时用 make flush 重置。对于"有未提交改动还想跑 Electron 应用"的场景,make app-local 直接从 backend/core_api/ 本地目录安装 cowork-server(无需提交);若要连 core_agent 的未提交改动也生效,需临时把 backend/core_api/pyproject.toml 中 [tool.uv.sources] 的 anton-agent 指向 { path = "../../core_agent" },推送前记得还原为 git 源。
部署:容器化与任意环境
README 的"Implante em qualquer lugar"章节说明 Cowork 面向灵活部署设计——云、VPC、on-premises、air-gapped(离线)与混合——让用户完全掌控基础设施、模型、权限和数据。
仓库内的容器化证据在 docker-compose.yml,它定义了一个最小两服务栈:
api服务:基于 docker/api.Dockerfile 构建,环境固定COWORK_SERVER_HOST=0.0.0.0、COWORK_SERVER_PORT=26866,数据库为sqlite:////home/cowork/.cowork/cowork.db,数据落在命名卷cowork-data(映射到/home/cowork/.cowork),对外暴露26866端口,并带/health端点的健康检查(30s 间隔、5s 超时、20s 启动宽限、3 次重试)。文件中还以注释形式留了ANTHROPIC_ANTHROPIC_API_KEY之类的 Key 注入位;web服务:基于 docker/web.Dockerfile 构建,3000:80端口映射,depends_on等待api健康后才启动。
对应的构建与启停命令即前文提到的 make docker-build / make docker-up / make docker-down。对于需要 BYOK 的场景,把提供商 Key 通过环境变量注入 api 服务即可,与桌面模式写入 ~/.anton 的做法相互对应。
本地 Web 模式的两个补充排障点
CLAUDE.md 记录了 Makefile 之外、纯浏览器模式(cd frontend && npm install && npm run dev:web,前端在 http://localhost:5173/,FastAPI 后端自动起在 http://127.0.0.1:26866)下的两个必要操作,对从源码起步的读者有实战价值:
- 跳过 Keycloak SSO(本地开发必需):Web 应用默认首次加载会跳转到 MindsHub SSO。本地开发时在
frontend/src/renderer/.env写入VITE_SKIP_AUTH=true(注意 Vite 的根是src/renderer而不是frontend/),重启npm run dev:web后应用会直接落到引导页,在那里可以填入 BYOK 的 API Key。 - 首次运行符号链接修复:
dev:web脚本期望在~/.local/share/uv/tools/anton/找到 uv 安装的 tool,但它可能被装成anton-agent。若报 "Anton Python interpreter not found",执行ln -s ~/.local/share/uv/tools/anton-agent ~/.local/share/uv/tools/anton即可。
支持、贡献与许可
- 求助与社区:README 指路官方 Discord 社区提问;
- 报 Bug:以复现步骤开 issue;
- 安全漏洞:不要开公开 issue,需通过仓库的私有安全渠道(配套文件为 SECURITY.md)报告;
- 贡献:Cowork 开源,欢迎代码、集成、文档、Bug 报告与功能想法,流程见 CONTRIBUTING.md;
- 许可:本 superproject 仓库在 MIT 许可下分发(见 LICENSE),各打包组件(四个子模块仓库)遵循各自的许可证,细节需查阅对应子模块仓库。
小结
这套工作流的要点可以压缩成三句话:克隆带 --recurse-submodules,依赖一条 make setup,运行模式与平台打包全在 Makefile 的命令表里;多人分支开发用 dev.env 选 ref、make use 切换、make pin 唯一化 pin 更新,父仓库 git status 恒干净;部署侧既有 Docker 双服务栈,也面向 VPC / on-premises / air-gapped 环境设计。读完本文并对照 CLAUDE.md 的完整说明,你可以独立走完"克隆 → 构建 → 分支开发 → 容器部署"的完整闭环。
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