Thanks for your interest in contributing to Manifold! This guide will help you get started.
- Node.js (v20+)
- npm
- Platform — macOS, or x64 WSL2 with WSLg and native build tools (
build-essential, Python 3) - Git
- At least one supported CLI agent installed (Claude Code, Codex, or Gemini CLI)
git clone https://github.com/vippsas/manifold.git
cd manifold
npm run bootstrap # install deps, verify Electron, rebuild better-sqlite3 for Electron
npm run devnpm run bootstrap is also the one-step setup for a fresh git worktree, where a bare
npm install (or a symlinked node_modules) can leave Electron half-installed. Run
npm run doctor any time to check the environment's health (deps, Electron binary,
better-sqlite3 ABI, and whether out/ is stale).
npm run bootstrap # One-step worktree setup (install + verify Electron + rebuild)
npm run doctor # Report environment health (deps, Electron, ABI, out/ staleness)
npm run dev # Start Electron in dev mode (hot reload)
npm run build # Production build
npm run typecheck # Full typecheck (main + renderer)
npm test # Run all tests
npm run test:watch # Watch modebetter-sqlite3 is a native module, and its compiled binary is valid for exactly one
runtime's ABI at a time. Tests run under system Node; the app runs under Electron,
which has a different ABI. The two entry points therefore rebuild it for opposite runtimes:
npm test→pretestrebuilds for Node (npm run rebuild:node).npm run dev/start/dist→ theirpre*hooks rebuild for Electron (npm run rebuild:electron).
Running the tests leaves the binary built for Node, so the dev app won't load it until it's
rebuilt for Electron — and vice-versa. This is expected: the pre* hooks flip the ABI back
automatically, so just run the command you want (npm run dev after npm test rebuilds
for Electron on its own). If the app is already running when you run tests, or you hit a
NODE_MODULE_VERSION load error, the manual fix is npm run rebuild:electron.
npm run doctor reports which ABI the binary is currently built for.
Manifold follows the standard Electron three-process model:
src/main/— Main process (Node.js). Business logic, PTY management, git worktrees, file system.src/preload/— Bridge layer. Whitelisted IPC channels viacontextBridge.src/renderer/— React UI. No direct Node.js access.src/shared/— Types and defaults shared between main and renderer. Must stay free of Node.js-specific imports.
- TypeScript strict mode everywhere.
- Tests are co-located with source files (
*.test.ts/*.test.tsx). - Component styles are co-located in
*.styles.tsfiles exporting plain objects. - IPC channels follow
domain:actionnaming (e.g.,agent:spawn,files:read). - Worktree branches are prefixed with
manifold/(e.g.,manifold/oslo). - Use relative imports in production code (path aliases like
@sharedare vitest-only).
Update three files:
src/main/ipc-handlers.ts— add the handlersrc/preload/index.ts— whitelist the channel- The renderer hook that calls it
- Fork the repository and create a feature branch.
- Make your changes.
- Run
npm run typecheckandnpm testto verify everything passes. - Submit a pull request with a clear description of the change.
Use GitHub Issues to report bugs or request features. Include steps to reproduce, expected behavior, and your environment details.