Contributing
How to contribute to Primitiv.
Local setup
git clone https://github.com/AI-by-design/primitiv.git
cd primitiv
bun install
bun run buildRunning in development
To run the MCP server against local source without a build step, point your MCP config directly at the source file. Bun runs TypeScript directly so changes are picked up on the next server restart:
{
"mcpServers": {
"primitiv": {
"command": "bun",
"args": ["/path/to/primitiv/src/cli.ts", "serve", "./primitiv.config.js"]
}
}
}The MCP server also hot-reloads primitiv.contract.json automatically whenever primitiv build runs.
Build commands
bun run build # Compile TypeScript → dist/
bun run dev # Run src/index.ts directly via ts-node
bun run lint # ESLint on src/**/*.tsArchitecture
src/
├── cli.ts Entry point — routes init / build / serve
├── index.ts Exports build() and serve()
├── types.ts All shared interfaces — define types here, not inline
├── scanner/ CodebaseScanner — extracts tokens and components from the filesystem
├── sources/ Source adapters — Figma (Variables API), Storybook (manifest)
├── contract/ ContractBuilder — merges sources, detects conflicts, applies governance
├── inferrer/ inferRules() — derives design rules from token and component patterns
├── mcp/ PrimitivMCPServer — loads the contract and registers MCP tools
└── init/ init() — detects framework and writes primitiv.config.jsReleases
Releases are managed by Release Please. Commit messages must follow the Conventional Commits format:
| Prefix | Effect |
|---|---|
fix: ... | Patch release (0.1.0 → 0.1.1) |
feat: ... | Minor release (0.1.0 → 0.2.0) |
feat!: ... or BREAKING CHANGE: | Major release |
chore:, docs:, refactor: | No release |
On merge to main, Release Please opens a release PR. Merging that PR tags the release and publishes to the package registry automatically.
License
MIT