Developer Guide
This guide covers development setup and contribution guidelines for Mindwtr.
Product Philosophy
Mindwtr is built to be simple by default and powerful when you need it. We focus on reducing cognitive load, cutting the fat, and keeping users in flow. Every contribution is weighed against these tenets:
- Progressive disclosure: advanced options stay hidden until they matter.
- Less by default: fewer fields, fewer knobs, fewer distractions.
- Avoid feature creep: we prioritize clarity over clutter.
- Automatic beats manual: if the right outcome can be inferred or predicted — from the platform, the install channel, existing data, or context — the app should just do it. That applies everywhere, not only to settings: no knob to configure, no prompt asking what the app can answer itself, no extra tap or manual step in a workflow, no UI the user must operate to get the obvious result. Every manual step moves cognitive load from us (once) onto every user (forever). The update checker is the model: instead of a "disable update checks" toggle, the app detects how it was installed and behaves correctly per channel — package-manager installs go quiet on their own, with no setting shipped. When the right behavior genuinely can't be inferred and demand is real, gate the feature behind an existing switch or affordance before minting a new one.
Don't show me a cockpit when I just want to ride a bike.
See Engineering Principles for the data-safety and sync guardrails that sit underneath these.
Quick Start
# Clone repository
git clone https://github.com/dongdongbh/Mindwtr.git
cd Mindwtr
# Install dependencies
bun install
# Run desktop app (dev mode)
bun desktop:dev
# Run mobile app
bun mobile:startPrerequisites
All Platforms
Desktop Development
- Rust — Required for Tauri
Linux (Arch):
sudo pacman -S rust webkit2gtk-4.1 base-devel cmake alsa-lib libayatana-appindicatorLinux (Debian/Ubuntu):
sudo apt install libwebkit2gtk-4.1-dev build-essential libssl-dev libgtk-3-dev \
cmake perl libasound2-dev libayatana-appindicator3-dev
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shFor minimal build environments (containers, Nix) the full native set beyond the WebKitGTK/GTK3 stack is: cmake plus a C/C++ toolchain with bindgen support (local Whisper transcription), perl (OpenSSL's build), ALSA headers (audio), and libayatana-appindicator (tray icon).
macOS:
xcode-select --install
brew install rustWindows: Install Rust and Visual Studio Build Tools.
Mobile Development
- Expo Go app (for testing)
- Android Studio (for emulator/device builds)
- Xcode (for iOS development)
Project Structure
Mindwtr/
├── apps/
│ ├── cloud/ # Sync server (Bun)
│ ├── desktop/ # Tauri v2 + React + Vite
│ │ ├── src/ # React source
│ │ │ ├── components/
│ │ │ ├── contexts/
│ │ │ ├── lib/
│ │ │ └── App.tsx
│ │ ├── src-tauri/ # Rust backend
│ │ └── package.json
│ │
│ └── mobile/ # Expo + React Native
│ ├── app/ # Expo Router pages
│ ├── components/
│ ├── contexts/
│ ├── lib/
│ └── package.json
│
├── packages/
│ └── core/ # Shared business logic
│ └── src/
│ ├── store.ts # Zustand store
│ ├── types.ts # TypeScript types
│ ├── i18n/ # Translation loader and locales
│ └── ...
│
├── scripts/ # Utility scripts (CLI, API, release)
├── docs/ # Repository-local docs: ADRs, release notes, contribution docs
├── wiki/ # Retired GitHub Wiki landing page (points to the docs site)
├── .github/ # CI/CD workflows
└── package.json # Monorepo rootThe mindwtr-web/docs tree is the canonical source for public user and developer documentation and publishes to https://docs.mindwtr.app/. The app repository's docs/ directory contains engineering and release artifacts such as ADRs, contribution/process guides, and release notes.
Available Scripts
Root Level
| Command | Description |
|---|---|
bun install | Install all dependencies |
bun desktop:dev | Run desktop in dev mode |
bun mobile:start | Start Expo dev server |
bun mobile:android | Run on Android |
bun mobile:ios | Run on iOS |
bun run test | Run all tests |
bun mindwtr:cli | Run CLI tool |
bun mindwtr:api | Run local API server |
Desktop (apps/desktop)
| Command | Description |
|---|---|
bun dev | Dev mode with hot reload |
bun build | Build for production |
bun run test | Run tests |
Mobile (apps/mobile)
| Command | Description |
|---|---|
bun start | Start Expo server |
bun android | Run on Android |
bun ios | Run on iOS |
ARCHS=arm64-v8a bash ./scripts/android_build.sh | Build Android APK |
Cloud (apps/cloud)
| Command | Description |
|---|---|
bun dev | Run sync server |
Core (packages/core)
| Command | Description |
|---|---|
bun run test | Run unit tests |
bun build | Build package |
Tech Stack
| Layer | Desktop | Mobile | Cloud |
|---|---|---|---|
| Framework | React + Vite | React Native + Expo | Bun (Native HTTP) |
| Styling | Tailwind CSS | NativeWind (Tailwind) | N/A |
| State | Zustand (shared) | Zustand (shared) | N/A |
| Platform | Tauri v2 (Rust) | Expo (iOS/Android) | Bun |
| Router | Internal view state | Expo Router | N/A |
| Language | TypeScript | TypeScript | TypeScript |
Architecture Decisions
We track key technical decisions as ADRs under docs/adr/. See:
docs/adr/README.md
Current sync ADRs to know before changing merge or transport behavior:
- ADR 0003 defines revision-aware sync metadata (
rev,revBy) and deterministic tombstone-aware merge. - ADR 0007 defines the shipped live-wins rule for ambiguous delete-vs-live conflicts.
- ADR 0008 records that Mindwtr intentionally stays on snapshot-based sync for now instead of adding a delta log.
Contributors should treat the snapshot transport as a deliberate product choice, not missing infrastructure. Revisit ADR 0008 only if snapshot files regularly exceed 5 MB, sync round-trips exceed 5 seconds on typical networks, or Mindwtr needs real-time multi-device streaming.
Development Workflow
Making Changes
- Create a feature branch
- Make changes in the relevant package
- Run tests:
bun run test - Test on desktop:
bun desktop:dev - Test on mobile:
bun mobile:start - Commit with descriptive message
- Open a pull request
When adding a new top-level entity type, update the full persistence and sync surface in the same change: core AppData types and normalization, desktop SQLite schema/storage round-trip tests, mobile SQLite schema/backup restore, cloud validation/normalization, MCP tools if exposed, and the Core API docs source at https://github.com/dongdongbh/mindwtr-web/tree/main/docs.
Code Style
- TypeScript for all code
- Functional React components
- Named exports preferred
- JSDoc comments for public APIs
Testing
# Run all tests
bun run test
# Run desktop tests
cd apps/desktop && bun run test
# Run core tests
cd packages/core && bun run testBuilding for Production
Desktop
cd apps/desktop
bun run build
# Output: src-tauri/target/release/Desktop (diagnostics build)
Release builds disable devtools by default. To enable diagnostics/devtools, build with the diagnostics feature and opt-in at runtime:
cd apps/desktop
cargo tauri build --features diagnostics
MINDWTR_DIAGNOSTICS=1 ./src-tauri/target/release/mindwtrMobile (Android APK)
cd apps/mobile
ARCHS=arm64-v8a bash ./scripts/android_build.shSee Mobile Installation for detailed build instructions.
Architecture Overview
See Architecture for detailed technical design.
Key Concepts
- Monorepo: Single repo with shared dependencies
- Shared Core: Business logic in
@mindwtr/core - Platform Apps: Desktop and Mobile use the shared core
- Local Storage: Data persisted locally
- Multiple Sync: File, WebDAV, or Cloud sync
CLI Tool
Command-line interface for scripting and automation:
# Add a task
bun mindwtr:cli -- add "Call mom @phone #family"
# List active tasks
bun mindwtr:cli -- list
# List with filters
bun mindwtr:cli -- list --status next --query "due:<=7d"
# Read or update a task
bun mindwtr:cli -- get <taskId>
bun mindwtr:cli -- update <taskId> '{"status":"next"}'
# Complete a task
bun mindwtr:cli -- complete <taskId>
# Archive, delete, or restore
bun mindwtr:cli -- archive <taskId>
bun mindwtr:cli -- delete <taskId>
bun mindwtr:cli -- restore <taskId>
# Search
bun mindwtr:cli -- search "@work"
# List projects
bun mindwtr:cli -- projectsOptions:
--data <path>— Override data.json location--db <path>— Override mindwtr.db locationMINDWTR_DATA— Environment variable for data pathMINDWTR_DB_PATH— Environment variable for DB path
On desktop-compatible paths, the CLI keeps mindwtr.db and data.json aligned so changes remain visible before and after the app starts.
Local REST API
Run a local API server for scripting and integrations:
# Start API server
bun mindwtr:api -- --port 4317
# With auth token
MINDWTR_API_TOKEN=secret bun mindwtr:api -- --port 4317The local API uses the same storage contract as the CLI, keeping mindwtr.db and data.json in sync on desktop-compatible paths.
Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /health | Health check |
GET | /tasks | List tasks |
GET | /tasks?status=next | Filter by status |
GET | /tasks?query=@work | Search tasks |
POST | /tasks | Create task |
PATCH | /tasks/:id | Update task |
DELETE | /tasks/:id | Soft delete task |
POST | /tasks/:id/complete | Mark task done |
POST | /tasks/:id/archive | Mark task archived |
POST | /tasks/:id/restore | Restore deleted task |
GET | /projects | List projects |
GET | /search?query=... | Search tasks+projects |
Example:
# Add task via API
curl -X POST http://localhost:4317/tasks \
-H "Content-Type: application/json" \
-d '{"input": "Review PR @work /due:tomorrow"}'
# Complete task
curl -X POST http://localhost:4317/tasks/<id>/completeCloud Server
Self-hosted cloud sync backend:
# From monorepo root
bun run --filter mindwtr-cloud dev -- --port 8787Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /health | Health check |
HEAD | /v1/data | Get snapshot metadata |
GET | /v1/data | Get user data |
PUT | /v1/data | Merge and save user data; returns merge stats |
GET, POST | /v1/tasks | List or create tasks |
GET, PATCH, DELETE | /v1/tasks/:id | Read, update, or soft-delete a task |
POST | /v1/tasks/:id/complete | Mark a task done |
POST | /v1/tasks/:id/archive | Archive a task |
GET, POST | /v1/projects | List or create projects |
GET, PATCH, DELETE | /v1/projects/:id | Read, update, or soft-delete a project |
GET, POST | /v1/sections | List or create sections |
GET, PATCH, DELETE | /v1/sections/:id | Read, update, or soft-delete a section |
GET, POST | /v1/areas | List or create areas |
GET, PATCH, DELETE | /v1/areas/:id | Read, update, or soft-delete an area |
GET | /v1/search | Search tasks and projects |
GET, PUT, DELETE | /v1/attachments/* | Download, upload, or delete attachment files |
POST, DELETE | /v1/attachments/orphans | Scan or remove orphan attachment files |
Authentication: Authorization: Bearer <token>
Each token gets its own data file (SHA-256 hashed filename).
Environment:
PORT— Server port (default 8787)HOST— Bind address (default 0.0.0.0)MINDWTR_CLOUD_DATA_DIR— Data directory
Web App (PWA)
Run the desktop UI in a browser with PWA support:
# Development
bun desktop:web
# Production build
bun desktop:web:buildUses localStorage for data storage and includes offline support via service worker.