Files
2026-07-13 12:08:46 +08:00

620 lines
28 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Setup — Minds Cowork Docs</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="description" content="Get started with Minds Cowork. Download the pre-built desktop or web app, or build from source with Node.js, Python, and Docker." />
<meta name="keywords" content="Minds Cowork setup, install, get started, download, Electron app, Docker, build from source, Node.js, Python" />
<meta name="robots" content="index, follow" />
<meta name="author" content="Minds Platform" />
<meta property="og:title" content="Setup — Minds Cowork" />
<meta property="og:description" content="Get started with Minds Cowork. Download the pre-built desktop or web app, or build from source with Node.js, Python, and Docker." />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Minds Cowork" />
<meta property="og:image" content="favicon.png" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@MindsDB" />
<meta name="twitter:title" content="Setup — Minds Cowork" />
<meta name="twitter:description" content="Get started with Minds Cowork. Download the pre-built desktop or web app, or build from source with Node.js, Python, and Docker." />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Josefin+Sans:wght@300;400;700&display=swap" rel="stylesheet" />
<style>
:root {
--bg: #080d18;
--surface: #0E1626;
--surface-2: #131D31;
--surface-3: #1A2640;
--line: #1E2A44;
--line-2: #2A3957;
--ink: #F2F6FF;
--ink-2: #C7D2E5;
--ink-3: #8A97AE;
--ink-4: #5C6B85;
--accent: #22D3EE;
--accent-bg: rgba(34,211,238,0.10);
--accent-glow: rgba(34,211,238,0.45);
--success: #4ADE80;
--r: 6px;
--r-lg: 10px;
--r-xl: 16px;
--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
--font-display: 'Josefin Sans', 'Inter', sans-serif;
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { color-scheme: dark; }
body {
background: var(--bg);
color: var(--ink-2);
font-family: var(--font-sans);
font-size: 15px; line-height: 1.65;
-webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-decoration: none; }
a:hover { opacity: 0.8; }
code {
font-family: var(--font-mono);
font-size: 0.88em;
background: var(--surface-3);
border: 1px solid var(--line-2);
border-radius: 4px;
padding: 1px 6px;
color: var(--accent);
}
/* ── Nav ── */
nav {
position: sticky; top: 0; z-index: 40;
background: rgba(8,13,24,0.80);
backdrop-filter: saturate(160%) blur(16px);
-webkit-backdrop-filter: saturate(160%) blur(16px);
border-bottom: 1px solid var(--line);
}
.nav-inner {
max-width: 1100px; margin: 0 auto; padding: 0 24px;
height: 52px; display: flex; align-items: center; gap: 32px;
}
.brand {
font-family: var(--font-mono); font-size: 11px; font-weight: 600;
letter-spacing: 0.18em; text-transform: uppercase;
color: var(--ink-3); display: flex; align-items: center; gap: 8px;
}
.brand-dot {
width: 6px; height: 6px; border-radius: 50%;
background: var(--accent); box-shadow: 0 0 8px var(--accent-glow);
}
.nav-links { display: flex; gap: 24px; margin-left: auto; }
/* ── Mobile nav ── */
.hamburger {
display: none;
flex-direction: column; justify-content: center; gap: 5px;
width: 36px; height: 36px;
background: none; border: none; cursor: pointer;
padding: 4px; margin-left: auto; flex-shrink: 0;
}
.hamburger span {
display: block; width: 20px; height: 1.5px;
background: var(--ink-3); border-radius: 2px;
transition: transform 200ms, opacity 200ms, width 200ms;
transform-origin: center;
}
nav[data-open] .hamburger span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
nav[data-open] .hamburger span:nth-child(2) { opacity: 0; width: 0; }
nav[data-open] .hamburger span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
@media (max-width: 640px) {
.hamburger { display: flex; }
.nav-links {
display: none;
position: absolute; top: 52px; left: 0; right: 0;
flex-direction: column; gap: 0;
background: rgba(8,13,24,0.97);
backdrop-filter: saturate(160%) blur(16px);
-webkit-backdrop-filter: saturate(160%) blur(16px);
border-bottom: 1px solid var(--line);
padding: 8px 0;
z-index: 39;
}
nav[data-open] .nav-links { display: flex; }
.nav-links a {
padding: 12px 24px;
font-size: 14px;
border-left: 2px solid transparent;
}
.nav-links a.active { border-color: var(--accent); background: var(--accent-bg); }
}
.nav-links a { font-size: 13px; color: var(--ink-3); transition: color 120ms; }
.nav-links a:hover { color: var(--ink); opacity: 1; }
.nav-links a.active { color: var(--accent); }
/* ── Layout ── */
.shell {
max-width: 1100px; margin: 0 auto;
padding: 64px 24px 120px;
display: grid; gap: 0;
grid-template-columns: 220px 1fr;
align-items: start;
}
@media (max-width: 768px) { .shell { grid-template-columns: 1fr; } }
/* ── Sidebar ── */
.sidebar {
padding-right: 40px;
padding-top: 4px;
position: sticky;
top: 72px;
}
@media (max-width: 768px) { .sidebar { display: none; } }
.sidebar-label {
font-family: var(--font-mono); font-size: 10px; font-weight: 600;
letter-spacing: 0.16em; text-transform: uppercase;
color: var(--ink-4); margin-bottom: 12px;
}
.sidebar ul { list-style: none; display: flex; flex-direction: column; gap: 2px; }
.sidebar li a {
font-size: 13px; color: var(--ink-3);
display: block; padding: 4px 10px;
border-left: 2px solid transparent;
border-radius: 0 var(--r) var(--r) 0;
transition: color 120ms, border-color 120ms;
}
.sidebar li a:hover { color: var(--ink); opacity: 1; border-color: var(--line-2); }
.sidebar li a.active { color: var(--accent); border-color: var(--accent); }
.sidebar .sub-group { list-style: none; }
.sidebar .sub-group ul { list-style: none; border-left: 1px solid var(--line); margin-left: 10px; padding-left: 0; display: flex; flex-direction: column; gap: 2px; margin-top: 2px; }
.sidebar .sub-group ul li a { font-size: 12.5px; color: var(--ink-4); padding-left: 14px; }
/* ── Content ── */
.content { min-width: 0; }
.eyebrow {
font-family: var(--font-mono); font-size: 11px; font-weight: 600;
letter-spacing: 0.18em; text-transform: uppercase;
color: var(--accent); margin-bottom: 14px;
display: flex; align-items: center; gap: 8px;
}
.eyebrow::before { content: ''; display: block; width: 24px; height: 1px; background: var(--accent); }
h1 {
font-family: var(--font-display);
font-size: clamp(30px, 4vw, 46px); font-weight: 700;
letter-spacing: -0.01em; line-height: 1.08;
color: var(--ink); margin-bottom: 16px;
}
.lede {
font-size: 16px; line-height: 1.65; color: var(--ink-3);
max-width: 60ch; margin-bottom: 52px;
}
/* ── Sections ── */
.section { margin-bottom: 56px; scroll-margin-top: 80px; }
h2 {
font-size: 20px; font-weight: 600; letter-spacing: -0.01em;
color: var(--ink); margin-bottom: 16px;
padding-bottom: 10px; border-bottom: 1px solid var(--line);
display: flex; align-items: center; gap: 10px;
}
h2 .step-badge {
font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
background: var(--accent-bg); color: var(--accent);
border: 1px solid rgba(34,211,238,0.25);
border-radius: 100px; padding: 2px 10px;
letter-spacing: 0.06em;
}
p { color: var(--ink-3); margin-bottom: 12px; }
p:last-child { margin-bottom: 0; }
/* ── Code block ── */
.code-block {
background: var(--surface);
border: 1px solid var(--line);
border-radius: var(--r-lg);
overflow: hidden;
margin: 16px 0;
}
.code-header {
padding: 10px 16px;
border-bottom: 1px solid var(--line);
display: flex; align-items: center; justify-content: space-between;
}
.code-lang {
font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-4);
}
pre {
font-family: var(--font-mono); font-size: 13px; line-height: 1.7;
color: var(--ink-2); padding: 18px 20px;
overflow-x: auto; tab-size: 2;
}
.hl { color: var(--accent); }
.cm { color: var(--ink-4); }
/* ── Prereq chips ── */
.prereq-grid {
display: flex; flex-wrap: wrap; gap: 10px;
margin: 16px 0;
}
.prereq-chip {
background: var(--surface-2);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 10px 16px;
display: flex; flex-direction: column; gap: 3px;
}
.prereq-chip .chip-name {
font-family: var(--font-mono); font-size: 12px; font-weight: 600;
color: var(--ink);
}
.prereq-chip .chip-ver {
font-size: 12px; color: var(--ink-4);
}
/* ── Make table ── */
.make-table {
width: 100%; border-collapse: collapse;
border: 1px solid var(--line);
border-radius: var(--r-lg); overflow: hidden;
margin: 16px 0; font-size: 13.5px;
}
.make-table th {
background: var(--surface-2);
font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
letter-spacing: 0.12em; text-transform: uppercase;
color: var(--ink-4); text-align: left;
padding: 10px 16px; border-bottom: 1px solid var(--line);
}
.make-table td {
padding: 11px 16px; color: var(--ink-3);
border-bottom: 1px solid var(--line);
vertical-align: top;
}
.make-table tr:last-child td { border-bottom: none; }
.make-table td:first-child code {
font-size: 12.5px; font-weight: 500;
background: var(--accent-bg);
border-color: rgba(34,211,238,0.20);
color: var(--accent);
}
.make-table tr:hover td { background: var(--surface-2); }
/* ── Download cards ── */
.download-grid {
display: grid; gap: 12px; grid-template-columns: 1fr;
margin: 16px 0 0;
}
@media (min-width: 600px) { .download-grid { grid-template-columns: repeat(3, 1fr); } }
.download-card {
background: var(--surface);
border: 1px solid var(--line);
border-radius: var(--r-xl);
padding: 18px 20px;
display: flex; align-items: center; gap: 14px;
text-decoration: none;
transition: border-color 150ms, transform 150ms;
color: inherit;
}
.download-card:hover {
border-color: rgba(34,211,238,0.35);
transform: translateY(-2px);
opacity: 1;
}
.dl-icon { font-size: 22px; flex-shrink: 0; line-height: 1; }
.dl-body { flex: 1; }
.dl-name { font-size: 14px; font-weight: 600; color: var(--ink); margin-bottom: 3px; }
.dl-desc { font-size: 12.5px; color: var(--ink-3); line-height: 1.45; }
.dl-arrow { font-size: 16px; color: var(--accent); flex-shrink: 0; }
/* ── Divider ── */
.divider {
display: flex; align-items: center; gap: 16px;
margin: 40px 0 40px;
color: var(--ink-4);
font-family: var(--font-mono); font-size: 11px;
letter-spacing: 0.12em; text-transform: uppercase;
}
.divider::before, .divider::after {
content: ''; flex: 1; height: 1px; background: var(--line);
}
/* ── Note ── */
.note {
background: var(--surface-2);
border: 1px solid var(--line);
border-left: 3px solid var(--accent);
border-radius: 0 var(--r-lg) var(--r-lg) 0;
padding: 14px 18px;
font-size: 13.5px; color: var(--ink-3);
margin: 16px 0;
}
.note strong { color: var(--ink); }
footer {
border-top: 1px solid var(--line); padding: 24px;
text-align: center; font-family: var(--font-mono);
font-size: 11px; color: var(--ink-4); letter-spacing: 0.06em;
}
</style>
</head>
<body>
<nav>
<div class="nav-inner">
<div class="brand"><div class="brand-dot"></div>Minds Cowork</div>
<div class="nav-links">
<a href="index.html">Docs</a>
<a href="setup.html" class="active">Setup</a>
<a href="use-cases.html">Use Cases</a>
<a href="api.html">API</a>
<a href="https://github.com/mindsdb/minds-platform">GitHub ↗</a>
</div>
<button class="hamburger" aria-label="Toggle menu">
<span></span><span></span><span></span>
</button>
</div>
</nav>
<div class="shell">
<aside class="sidebar">
<div class="sidebar-label">On this page</div>
<ul>
<li><a href="#app">Desktop or Web App</a></li>
<li><a href="#source">Build From Source</a></li>
<li class="sub-group">
<ul>
<li><a href="#prereqs">Prerequisites</a></li>
<li><a href="#install">Install</a></li>
<li><a href="#desktop">Dev — desktop</a></li>
<li><a href="#web">Dev — web</a></li>
<li><a href="#docker">Docker</a></li>
<li><a href="#commands">All commands</a></li>
</ul>
</li>
</ul>
</aside>
<main class="content">
<div class="eyebrow">Setup</div>
<h1>Get Started</h1>
<p class="lede">
The simplest way to use Minds Cowork is the pre-built app — available on web and desktop.
</p>
<!-- Desktop App download -->
<section class="section" id="app">
<h2>Desktop or Web App</h2>
<p>Pre-built, packaged and ready — no setup required.</p>
<div class="download-grid">
<a class="download-card" href="https://mindshub.ai" target="_blank">
<div class="dl-icon">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" style="color:var(--ink-2)">
<circle cx="12" cy="12" r="10"/>
<path d="M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>
</svg>
</div>
<div class="dl-body">
<div class="dl-name">Web</div>
<div class="dl-desc">Try it at <span style="color:var(--accent);text-decoration:underline;text-underline-offset:2px;">mindshub.ai</span> — ready in one click.</div>
</div>
<div class="dl-arrow"></div>
</a>
<a class="download-card" href="https://downloads.mindsdb.com/anton/mac/anton-latest.pkg" target="_blank">
<div class="dl-icon">
<svg width="22" height="22" viewBox="0 0 814 1000" fill="currentColor" xmlns="http://www.w3.org/2000/svg" style="color:var(--ink-2)">
<path d="M788.1 340.9c-5.8 4.5-108.2 62.2-108.2 190.5 0 148.4 130.3 200.9 134.2 202.2-.6 3.2-20.7 71.9-68.7 141.9-42.8 61.6-87.5 123.1-155.5 123.1s-85.5-39.5-164-39.5c-76 0-103.7 40.8-165.9 40.8s-105-43.4-150.3-116.6c-52.1-83.6-94.1-208.7-94.1-328.2 0-191.3 124.1-292.5 246.9-292.5 66.1 0 121.2 43.4 162.7 43.4 39.5 0 101.1-46 176.3-46 28.5 0 130.9 2.6 198.3 99.2zm-234-181.5c31.1-36.9 53.1-88.1 53.1-139.3 0-7.1-.6-14.3-1.9-20.1-50.6 1.9-110.8 33.7-147.1 75.8-28.5 32.4-55.1 83.6-55.1 135.5 0 7.8 1.3 15.6 1.9 18.1 3.2.6 8.4 1.3 13.6 1.3 45.4 0 102.5-30.4 135.5-71.3z"/>
</svg>
</div>
<div class="dl-body">
<div class="dl-name">macOS</div>
<div class="dl-desc">Download the <code>.pkg</code> installer for macOS.</div>
</div>
<div class="dl-arrow">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" style="color:var(--accent)">
<path d="M12 3v13M6 11l6 6 6-6M3 21h18"/>
</svg>
</div>
</a>
<a class="download-card" href="https://downloads.mindsdb.com/anton/windows/anton-latest.exe" target="_blank">
<div class="dl-icon">
<svg width="22" height="22" viewBox="0 0 88 88" fill="currentColor" xmlns="http://www.w3.org/2000/svg" style="color:var(--ink-2)">
<path d="M0 12.402l35.687-4.86.016 34.423-35.67.203zm35.67 33.529l.028 34.453L.028 75.48.026 45.7zm4.326-39.025L87.314 0v41.527l-47.318.376zm47.329 39.349l-.015 41.344-47.318-6.63-.066-34.893z"/>
</svg>
</div>
<div class="dl-body">
<div class="dl-name">Windows</div>
<div class="dl-desc">Download the <code>.exe</code> installer for Windows.</div>
</div>
<div class="dl-arrow">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" style="color:var(--accent)">
<path d="M12 3v13M6 11l6 6 6-6M3 21h18"/>
</svg>
</div>
</a>
</div>
</section>
<div class="divider"></div>
<section class="section" id="source">
<h2>Build From Source</h2>
<p>Or build from source if you want to hack the code ;)</p>
</section>
<!-- Prerequisites -->
<section class="section" id="prereqs">
<h2><span class="step-badge">01</span> Prerequisites</h2>
<p>Make sure the following are installed on your machine before starting.</p>
<div class="prereq-grid">
<div class="prereq-chip">
<div class="chip-name">Node.js</div>
<div class="chip-ver">v20 or later</div>
</div>
<div class="prereq-chip">
<div class="chip-name">Python</div>
<div class="chip-ver">3.12 or later</div>
</div>
<div class="prereq-chip">
<div class="chip-name">uv</div>
<div class="chip-ver">Python package manager</div>
</div>
<div class="prereq-chip">
<div class="chip-name">make</div>
<div class="chip-ver">pre-installed on macOS / Linux</div>
</div>
</div>
<p>Install <code>uv</code> if you don't have it:</p>
<div class="code-block">
<div class="code-header"><span class="code-lang">bash</span></div>
<pre><span class="hl">curl</span> -LsSf https://astral.sh/uv/install.sh | sh</pre>
</div>
</section>
<!-- Install -->
<section class="section" id="install">
<h2><span class="step-badge">02</span> Clone &amp; install</h2>
<p>Clone with <code>--recurse-submodules</code> to pull <code>frontend</code>, <code>backend/core_api</code>, and <code>backend/core_agent</code> in one shot.</p>
<div class="code-block">
<div class="code-header"><span class="code-lang">bash</span></div>
<pre><span class="hl">git</span> clone --recurse-submodules https://github.com/mindsdb/minds-platform.git
<span class="hl">cd</span> minds-platform
<span class="hl">make</span> setup</pre>
</div>
<p><code>make setup</code> runs <code>npm ci</code> for the frontend and <code>uv sync</code> for both Python backends. It is automatically skipped on subsequent runs if nothing changed in the lock files.</p>
</section>
<!-- Desktop -->
<section class="section" id="desktop">
<h2>Desktop app</h2>
<p>Starts the FastAPI backend (with hot reload) and the Electron renderer (TypeScript watch + Vite HMR) in parallel.</p>
<div class="code-block">
<div class="code-header"><span class="code-lang">bash</span></div>
<pre><span class="hl">make</span> dev</pre>
</div>
<p>Press <code>Ctrl-C</code> once to shut down all processes cleanly.</p>
<p>To open DevTools, set <code>ANTON_OPEN_DEVTOOLS=1</code> before running:</p>
<div class="code-block">
<div class="code-header"><span class="code-lang">bash</span></div>
<pre>ANTON_OPEN_DEVTOOLS=1 <span class="hl">make</span> dev</pre>
</div>
</section>
<!-- Web -->
<section class="section" id="web">
<h2>Web app</h2>
<p>Starts the FastAPI backend and the Vite dev server with <code>BUILD_TARGET=web</code>. Opens the browser automatically.</p>
<div class="code-block">
<div class="code-header"><span class="code-lang">bash</span></div>
<pre><span class="hl">make</span> dev-web</pre>
</div>
<p>The app is served at <a href="http://localhost:5173">http://localhost:5173</a>. The API runs on <a href="http://localhost:26866">http://localhost:26866</a>.</p>
<div class="note">
<strong>API key required.</strong> Set <code>ANTON_ANTHROPIC_API_KEY=sk-ant-...</code> in a <code>.env</code> file inside <code>backend/core_api/</code> before running.
</div>
</section>
<!-- Docker -->
<section class="section" id="docker">
<h2>Docker</h2>
<p>Run the full stack in containers — the web SPA served by nginx on port 3000, the API on port 26866.</p>
<div class="code-block">
<div class="code-header"><span class="code-lang">bash</span></div>
<pre><span class="hl">make</span> docker-build <span class="cm"># build both images</span>
<span class="hl">make</span> docker-up <span class="cm"># start everything</span></pre>
</div>
<p>Or pass your API key inline:</p>
<div class="code-block">
<div class="code-header"><span class="code-lang">bash</span></div>
<pre>ANTON_ANTHROPIC_API_KEY=sk-ant-... <span class="hl">docker</span> compose up --build</pre>
</div>
<p>Open <a href="http://localhost:3000">http://localhost:3000</a> when the health check turns green.</p>
</section>
<!-- All commands -->
<section class="section" id="commands">
<h2>All make commands</h2>
<table class="make-table">
<thead>
<tr><th>Command</th><th>What it does</th></tr>
</thead>
<tbody>
<tr><td><code>make</code> / <code>make help</code></td><td>List every target with a one-line description (this is the default goal).</td></tr>
<tr><td><code>make setup</code></td><td>Install all dependencies (npm + uv). Auto-skipped when lock files haven't changed.</td></tr>
<tr><td><code>make dev</code></td><td>Start backend + Electron with full hot reload (local module source).</td></tr>
<tr><td><code>make dev-web</code></td><td>Start backend + Vite web dev server.</td></tr>
<tr><td><code>make build</code></td><td>Production build of the frontend (renderer + main process).</td></tr>
<tr><td><code>make dist-mac</code></td><td>Build and package a macOS <code>.dmg</code>.</td></tr>
<tr><td><code>make dist-win</code></td><td>Build and package a Windows <code>.exe</code>.</td></tr>
<tr><td><code>make docker-build</code></td><td>Build the api and web Docker images.</td></tr>
<tr><td><code>make docker-up</code></td><td>Start the Docker stack (<code>docker compose up</code>).</td></tr>
<tr><td><code>make docker-down</code></td><td>Stop and remove containers.</td></tr>
<tr><td><code>make flush</code></td><td>Wipe all local installs + app data for a fresh start (see below).</td></tr>
<tr><td colspan="2"><em>Module-branch workflow (see below)</em></td></tr>
<tr><td><code>make refs</code></td><td>Print which module branches the next run will use.</td></tr>
<tr><td><code>make use</code></td><td>Check out your <code>dev.env</code> refs across all submodules.</td></tr>
<tr><td><code>make server</code></td><td>(Re)install the Electron desktop server from your branch.</td></tr>
<tr><td><code>make app</code></td><td>Run the desktop app against your branch (auto-update off).</td></tr>
<tr><td><code>make baseline</code></td><td>Reset every submodule to the superproject's pinned commits.</td></tr>
<tr><td><code>make pin</code></td><td>Record the submodules' current commits as the superproject pins (one deliberate commit).</td></tr>
</tbody>
</table>
<h2>Working on module branches</h2>
<p>This repo is a superproject that <strong>pins</strong> each module (<code>frontend</code>, <code>backend/core_api</code>, <code>backend/core_agent</code>, <code>backend/data-vault</code>) to a commit. To let a team work on module branches without polluting <code>git status</code> or fighting over pins:</p>
<p><strong>1. Pick your branches</strong> in a gitignored <code>dev.env</code> (copy the template):</p>
<pre><code>cp dev.env.example dev.env # then set REF=feat/my-thing (or per-module API_REF=…)</code></pre>
<p><strong>2. <code>make</code> follows it</strong> &mdash; one knob, both run paths. <code>make use</code> checks out those refs; <code>make dev</code>/<code>dev-web</code> run the local module source on them, and <code>make server</code> + <code>make app</code> run the desktop app against the matching branch server.</p>
<p>Every submodule is configured with <code>ignore = all</code>, so your branch work never shows up as a superproject change &mdash; the parent <code>git status</code> stays clean. Pins move <strong>only</strong> via <code>make pin</code> (a deliberate, reviewable commit), and <code>make baseline</code> snaps submodules back to the pinned commits when you're not developing a module.</p>
<div class="note">
<strong>One DB, one ref.</strong> <code>make dev</code> (local source) and the desktop app (<code>make app</code>) share <code>~/.cowork/cowork.db</code>, so keep both on the same branch &mdash; a migration applied by one must exist in the other, or the app fails to start with <code>Can't locate revision …</code>. <code>make flush</code> resets if they drift.
</div>
<h2>Reset to a clean slate</h2>
<p><code>make flush</code> returns the machine to a pre-install state. It uninstalls the local runtime &mdash; the <code>cowork-server</code> uv tool <em>and</em> the <code>backend/core_api/.venv</code> + <code>backend/core_agent/.venv</code> &mdash; and deletes all app state: <code>~/.anton</code> (provider keys / <code>.env</code>) and <code>~/.cowork</code> (database, hermes, projects).</p>
<p>Use it to test the from-scratch install flow or to recover from a broken install. It prompts for confirmation before deleting; pass <code>FORCE=1</code> to skip the prompt in scripts/CI. The next <code>make setup</code> (or app launch) reinstalls everything.</p>
<div class="note">
<strong>Destructive.</strong> This permanently deletes your conversations and saved provider keys. There is no undo.
</div>
<pre><code>make flush # prompts before wiping
make flush FORCE=1 # no prompt (CI / scripts)</code></pre>
</section>
</main>
</div>
<footer>
Minds Platform · Open Source · <a href="https://github.com/mindsdb/minds-platform">github.com/mindsdb/minds-platform</a>
</footer>
<script>
document.querySelector('.hamburger').addEventListener('click', function() {
const nav = this.closest('nav');
nav.toggleAttribute('data-open');
});
document.querySelectorAll('.nav-links a').forEach(function(a) {
a.addEventListener('click', function() {
document.querySelector('nav').removeAttribute('data-open');
});
});
// Scroll spy
var sidebarLinks = Array.from(document.querySelectorAll('.sidebar a[href^="#"]'));
var sections = sidebarLinks.map(function(a) {
return document.querySelector(a.getAttribute('href'));
}).filter(Boolean);
function onScroll() {
var scrollY = window.scrollY + 100;
var active = sections[0];
sections.forEach(function(s) {
if (s.getBoundingClientRect().top + window.scrollY <= scrollY) active = s;
});
sidebarLinks.forEach(function(a) {
a.classList.toggle('active', a.getAttribute('href') === '#' + active.id);
});
}
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
</script>
</body>
</html>