Development¶
Prerequisites¶
- Node.js >= 20
- Yarn (via corepack —
corepack enable) - Docker and Docker Compose (for PostgreSQL)
Quick start¶
# Clone and install dependencies
git clone https://github.com/Flopsstuff/coqu.git && cd coqu
yarn install
# Create environment file
cp .env.example .env
# Edit .env and set JWT_SECRET and GIT_TOKEN_SECRET (required for the API to start)
# Start everything (postgres in Docker + API + Web locally)
yarn dev
This command:
1. Starts PostgreSQL in a Docker container
2. Generates Prisma Client
3. Starts API at http://localhost:4000
4. Starts Web at http://localhost:3000
On first run, the web UI will show an Initial Setup page where you create the admin account.
Stop PostgreSQL:
Running individual packages¶
Database¶
PostgreSQL runs in Docker even in dev mode.
Environment files¶
There are two .env files relevant to the database:
| File | Read by | Purpose |
|---|---|---|
.env (root) |
Docker Compose | Container settings: POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, POSTGRES_PORT |
packages/api/.env |
Prisma CLI | DATABASE_URL for local dev — connects to localhost:<POSTGRES_PORT> |
localhost vs postgres host¶
The database always runs in Docker. The host in DATABASE_URL depends on where the connecting code runs:
| Who connects | Runs on | Host | Port |
|---|---|---|---|
yarn dev / Prisma CLI / Studio |
Host machine | localhost |
POSTGRES_PORT (forwarded) |
API container (yarn docker:up) |
Inside Docker | postgres |
5432 (internal) |
- Local dev — the API and Prisma run on your machine, outside Docker. They reach the database through the forwarded port:
localhost:<POSTGRES_PORT>→ container's5432. - Production — everything runs inside Docker Compose. Containers share an internal network and find each other by service name, so the API connects to
postgres:5432directly (no port forwarding needed).
First-time setup¶
-
Copy the root env file and adjust values if needed:
-
Create
packages/api/.envwithDATABASE_URLbuilt from the values you set in the root.env:For example, if your rootDATABASE_URL=postgresql://<POSTGRES_USER>:<POSTGRES_PASSWORD>@localhost:<POSTGRES_PORT>/<POSTGRES_DB>.envcontains: Thenpackages/api/.envshould be:
Important: use
localhost(notpostgres) — Prisma runs on the host, not inside Docker.
- Start PostgreSQL and apply migrations:
Day-to-day workflow¶
# Start the database (if not already running)
yarn db:up
# Edit packages/api/prisma/schema.prisma, then:
yarn db:migrate # creates and applies the migration (runs generate automatically)
# Browse/edit data in a GUI
yarn db:studio
# Stop the database
yarn db:stop
All database commands¶
| Command | Description |
|---|---|
yarn db:up |
Start PostgreSQL container |
yarn db:stop |
Stop PostgreSQL container |
yarn db:reset |
Remove PostgreSQL container and volume (destroys all data) |
yarn db:migrate |
Create and apply Prisma migration |
yarn db:generate |
Regenerate Prisma Client |
yarn db:studio |
Open Prisma Studio (visual data editor) |
Changing the DB schema¶
- Edit
packages/api/prisma/schema.prisma yarn db:migrate— creates and applies the migration (generate runs automatically)- Add the type to
@coqu/sharedif needed on the frontend
Project structure¶
coqu/
├── packages/
│ ├── shared/ — shared types
│ │ └── src/index.ts
│ ├── api/ — REST API + MCP server
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ ├── query.ts — shared query execution logic
│ │ │ ├── logger.ts
│ │ │ ├── agents/
│ │ │ │ ├── types.ts — AgentProvider interface
│ │ │ │ ├── registry.ts — provider registry
│ │ │ │ ├── claude-code.ts — ClaudeCodeProvider
│ │ │ │ └── env-loader.ts — .env file/content parser
│ │ │ └── mcp/
│ │ │ ├── index.ts — Express route handler
│ │ │ ├── server.ts — MCP server factory
│ │ │ └── tools/
│ │ │ ├── query.ts — query tool
│ │ │ ├── list-projects.ts — list_projects tool
│ │ │ └── list-agents.ts — list_agents tool
│ │ ├── prisma/
│ │ │ └── schema.prisma
│ │ └── entrypoint.sh — Docker entrypoint (chown + su-exec)
│ └── web/ — React SPA
│ ├── src/
│ │ ├── main.tsx
│ │ ├── App.tsx
│ │ ├── AuthContext.tsx
│ │ ├── Header.tsx
│ │ ├── MinimalHeader.tsx
│ │ ├── api.ts
│ │ ├── index.css
│ │ ├── components/
│ │ │ └── ProjectCard.tsx
│ │ └── pages/
│ │ ├── AboutPage.tsx
│ │ ├── AgentDetailPage.tsx
│ │ ├── AgentsPage.tsx
│ │ ├── EnvPage.tsx
│ │ ├── HomePage.tsx
│ │ ├── LogsPage.tsx
│ │ ├── LoginPage.tsx
│ │ ├── McpInfoPage.tsx
│ │ ├── NewAgentPage.tsx
│ │ ├── NewProjectPage.tsx
│ │ ├── ProjectDetailPage.tsx
│ │ ├── ProjectsPage.tsx
│ │ ├── SettingsPage.tsx
│ │ ├── SetupGuidePage.tsx
│ │ ├── SetupPage.tsx
│ │ └── TokensPage.tsx
│ ├── public/
│ │ └── favicon.svg
│ ├── index.html
│ └── vite.config.ts
├── docs/ — documentation
├── docker-compose.yml
├── tsconfig.base.json
├── .env.example
└── package.json
Ports¶
3000— Web (Vite dev server)4000— API (Express)5432— PostgreSQL (default, configurable viaPOSTGRES_PORTin.env)
Adding a new API route¶
- Add types to
packages/shared/src/index.ts(if needed on the frontend) - Add handler to
packages/api/src/index.ts - Consume on the frontend in
packages/web/src/
Adding a DB model¶
- Define the model in
packages/api/prisma/schema.prisma yarn db:migrate- Add the type to
@coqu/sharedif needed on the frontend