feat: add Turborepo per-project monorepo scaffold and project API

- Add Turborepo scaffold templates (apps: product, website, admin, storybook; packages: ui, tokens, types, config)
- Add ProjectRecord and AppRecord types to control plane
- Add Gitea integration service (repo creation, scaffold push, webhooks)
- Add Coolify integration service (project + per-app service provisioning with turbo --filter)
- Add project routes: GET/POST /projects, GET /projects/:id/apps, POST /projects/:id/deploy
- Update chat route to inject project/monorepo context into AI requests
- Add deploy_app and scaffold_app tools to Gemini tool set
- Update deploy executor with monorepo-aware /execute/deploy endpoint
- Add TURBOREPO_MIGRATION_PLAN.md documenting rationale and scope

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-21 15:07:35 -08:00
parent 57b9ce2f1a
commit 2c3e7f9dfb
40 changed files with 1625 additions and 33 deletions

View File

@@ -0,0 +1,10 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
transpilePackages: [
"@{{project-slug}}/ui",
"@{{project-slug}}/tokens",
],
};
export default nextConfig;

View File

@@ -0,0 +1,27 @@
{
"name": "@{{project-slug}}/admin",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --port 3002",
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit"
},
"dependencies": {
"@{{project-slug}}/ui": "workspace:*",
"@{{project-slug}}/tokens": "workspace:*",
"@{{project-slug}}/types": "workspace:*",
"next": "^15.1.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@{{project-slug}}/config": "workspace:*",
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"typescript": "^5.7.0"
}
}

View File

@@ -0,0 +1,11 @@
{
"extends": "@{{project-slug}}/config/tsconfig.base.json",
"compilerOptions": {
"plugins": [{ "name": "next" }],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}

View File

@@ -0,0 +1,10 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
transpilePackages: [
"@{{project-slug}}/ui",
"@{{project-slug}}/tokens",
],
};
export default nextConfig;

View File

@@ -0,0 +1,27 @@
{
"name": "@{{project-slug}}/product",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --port 3000",
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit"
},
"dependencies": {
"@{{project-slug}}/ui": "workspace:*",
"@{{project-slug}}/tokens": "workspace:*",
"@{{project-slug}}/types": "workspace:*",
"next": "^15.1.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@{{project-slug}}/config": "workspace:*",
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"typescript": "^5.7.0"
}
}

View File

@@ -0,0 +1,11 @@
{
"extends": "@{{project-slug}}/config/tsconfig.base.json",
"compilerOptions": {
"plugins": [{ "name": "next" }],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}

View File

@@ -0,0 +1,32 @@
{
"name": "@{{project-slug}}/storybook",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "storybook dev --port 6006",
"build": "storybook build --output-dir storybook-static",
"type-check": "tsc --noEmit"
},
"dependencies": {
"@{{project-slug}}/ui": "workspace:*",
"@{{project-slug}}/tokens": "workspace:*",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@{{project-slug}}/config": "workspace:*",
"@chromatic-com/storybook": "^3.0.0",
"@storybook/addon-essentials": "^8.5.0",
"@storybook/addon-interactions": "^8.5.0",
"@storybook/addon-links": "^8.5.0",
"@storybook/blocks": "^8.5.0",
"@storybook/react": "^8.5.0",
"@storybook/react-vite": "^8.5.0",
"@storybook/test": "^8.5.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"storybook": "^8.5.0",
"typescript": "^5.7.0",
"vite": "^6.0.0"
}
}

View File

@@ -0,0 +1,10 @@
{
"extends": "@{{project-slug}}/config/tsconfig.base.json",
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["node_modules", "storybook-static"]
}

View File

@@ -0,0 +1,10 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
transpilePackages: [
"@{{project-slug}}/ui",
"@{{project-slug}}/tokens",
],
};
export default nextConfig;

View File

@@ -0,0 +1,27 @@
{
"name": "@{{project-slug}}/website",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --port 3001",
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit"
},
"dependencies": {
"@{{project-slug}}/ui": "workspace:*",
"@{{project-slug}}/tokens": "workspace:*",
"@{{project-slug}}/types": "workspace:*",
"next": "^15.1.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@{{project-slug}}/config": "workspace:*",
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"typescript": "^5.7.0"
}
}

View File

@@ -0,0 +1,11 @@
{
"extends": "@{{project-slug}}/config/tsconfig.base.json",
"compilerOptions": {
"plugins": [{ "name": "next" }],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}