From 6763d3298d875ee7790d535a8f924418ccec3463 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 13 Dec 2025 19:09:42 +0000 Subject: [PATCH 1/3] feat: Implement YAML-to-Production microservice Add a complete microservice for transforming YAML specifications into production-ready applications. The system enables users to: - Upload YAML specs defining app features and integrations - Auto-generate code using Claude AI - Run automated security audits before deployment - Deploy to Vercel with one click - Manage custom domains and project settings Backend (Cloudflare Workers): - Hono-based API with Privy JWT authentication - D1 database for projects, deployments, and domains - YAML parser with Zod validation - Code generator using Anthropic Claude API - Security auditor for vulnerability detection - Vercel deployment orchestration - Durable Objects for real-time progress - Encrypted API key storage Frontend (React + Vite): - Multi-step deployment wizard UI - Real-time deployment progress via WebSocket - Project dashboard with domain management - Settings page for API key management - Privy passwordless authentication - TanStack Query for data fetching - Zustand state management - Tailwind CSS styling --- yaml-to-production/README.md | 252 +++++ yaml-to-production/frontend/.env.example | 5 + yaml-to-production/frontend/index.html | 17 + yaml-to-production/frontend/package.json | 43 + yaml-to-production/frontend/postcss.config.js | 6 + yaml-to-production/frontend/src/App.tsx | 93 ++ .../components/deploy/DeploymentComplete.tsx | 199 ++++ .../components/deploy/DeploymentPreview.tsx | 163 ++++ .../components/deploy/DeploymentProgress.tsx | 191 ++++ .../components/deploy/DeploymentReview.tsx | 255 +++++ .../src/components/deploy/MCPServerConfig.tsx | 297 ++++++ .../src/components/deploy/MCPServerSelect.tsx | 165 ++++ .../src/components/deploy/SecurityReview.tsx | 250 +++++ .../src/components/deploy/YamlUpload.tsx | 257 +++++ .../frontend/src/components/ui/Layout.tsx | 126 +++ .../src/components/ui/LoadingSpinner.tsx | 25 + .../frontend/src/hooks/useAuth.ts | 47 + .../frontend/src/hooks/useDeployment.ts | 117 +++ yaml-to-production/frontend/src/index.css | 183 ++++ yaml-to-production/frontend/src/main.tsx | 54 ++ .../frontend/src/pages/Dashboard.tsx | 295 ++++++ .../frontend/src/pages/Deploy.tsx | 85 ++ .../frontend/src/pages/Landing.tsx | 300 ++++++ .../frontend/src/pages/Project.tsx | 456 +++++++++ .../frontend/src/pages/Settings.tsx | 364 +++++++ .../frontend/src/services/api.ts | 219 +++++ .../frontend/src/stores/deploy.ts | 201 ++++ .../frontend/src/types/index.ts | 152 +++ yaml-to-production/frontend/src/vite-env.d.ts | 10 + .../frontend/tailwind.config.js | 48 + yaml-to-production/frontend/tsconfig.json | 25 + .../frontend/tsconfig.node.json | 11 + yaml-to-production/frontend/vite.config.ts | 21 + .../worker/migrations/0001_schema.sql | 179 ++++ yaml-to-production/worker/package.json | 29 + yaml-to-production/worker/src/index.ts | 75 ++ .../worker/src/middleware/auth.ts | 104 ++ .../worker/src/routes/deployments.ts | 392 ++++++++ .../worker/src/routes/domains.ts | 320 +++++++ yaml-to-production/worker/src/routes/mcp.ts | 398 ++++++++ .../worker/src/routes/projects.ts | 196 ++++ yaml-to-production/worker/src/routes/yaml.ts | 226 +++++ .../worker/src/services/code-generator.ts | 893 ++++++++++++++++++ .../worker/src/services/database.ts | 344 +++++++ .../worker/src/services/deployment-session.ts | 300 ++++++ yaml-to-production/worker/src/services/mcp.ts | 352 +++++++ .../worker/src/services/security-auditor.ts | 308 ++++++ .../worker/src/services/vercel-deployer.ts | 400 ++++++++ .../worker/src/services/yaml-parser.ts | 401 ++++++++ yaml-to-production/worker/src/types/env.ts | 142 +++ .../worker/src/utils/encryption.ts | 127 +++ yaml-to-production/worker/tsconfig.json | 23 + yaml-to-production/worker/wrangler.toml | 43 + 53 files changed, 10184 insertions(+) create mode 100644 yaml-to-production/README.md create mode 100644 yaml-to-production/frontend/.env.example create mode 100644 yaml-to-production/frontend/index.html create mode 100644 yaml-to-production/frontend/package.json create mode 100644 yaml-to-production/frontend/postcss.config.js create mode 100644 yaml-to-production/frontend/src/App.tsx create mode 100644 yaml-to-production/frontend/src/components/deploy/DeploymentComplete.tsx create mode 100644 yaml-to-production/frontend/src/components/deploy/DeploymentPreview.tsx create mode 100644 yaml-to-production/frontend/src/components/deploy/DeploymentProgress.tsx create mode 100644 yaml-to-production/frontend/src/components/deploy/DeploymentReview.tsx create mode 100644 yaml-to-production/frontend/src/components/deploy/MCPServerConfig.tsx create mode 100644 yaml-to-production/frontend/src/components/deploy/MCPServerSelect.tsx create mode 100644 yaml-to-production/frontend/src/components/deploy/SecurityReview.tsx create mode 100644 yaml-to-production/frontend/src/components/deploy/YamlUpload.tsx create mode 100644 yaml-to-production/frontend/src/components/ui/Layout.tsx create mode 100644 yaml-to-production/frontend/src/components/ui/LoadingSpinner.tsx create mode 100644 yaml-to-production/frontend/src/hooks/useAuth.ts create mode 100644 yaml-to-production/frontend/src/hooks/useDeployment.ts create mode 100644 yaml-to-production/frontend/src/index.css create mode 100644 yaml-to-production/frontend/src/main.tsx create mode 100644 yaml-to-production/frontend/src/pages/Dashboard.tsx create mode 100644 yaml-to-production/frontend/src/pages/Deploy.tsx create mode 100644 yaml-to-production/frontend/src/pages/Landing.tsx create mode 100644 yaml-to-production/frontend/src/pages/Project.tsx create mode 100644 yaml-to-production/frontend/src/pages/Settings.tsx create mode 100644 yaml-to-production/frontend/src/services/api.ts create mode 100644 yaml-to-production/frontend/src/stores/deploy.ts create mode 100644 yaml-to-production/frontend/src/types/index.ts create mode 100644 yaml-to-production/frontend/src/vite-env.d.ts create mode 100644 yaml-to-production/frontend/tailwind.config.js create mode 100644 yaml-to-production/frontend/tsconfig.json create mode 100644 yaml-to-production/frontend/tsconfig.node.json create mode 100644 yaml-to-production/frontend/vite.config.ts create mode 100644 yaml-to-production/worker/migrations/0001_schema.sql create mode 100644 yaml-to-production/worker/package.json create mode 100644 yaml-to-production/worker/src/index.ts create mode 100644 yaml-to-production/worker/src/middleware/auth.ts create mode 100644 yaml-to-production/worker/src/routes/deployments.ts create mode 100644 yaml-to-production/worker/src/routes/domains.ts create mode 100644 yaml-to-production/worker/src/routes/mcp.ts create mode 100644 yaml-to-production/worker/src/routes/projects.ts create mode 100644 yaml-to-production/worker/src/routes/yaml.ts create mode 100644 yaml-to-production/worker/src/services/code-generator.ts create mode 100644 yaml-to-production/worker/src/services/database.ts create mode 100644 yaml-to-production/worker/src/services/deployment-session.ts create mode 100644 yaml-to-production/worker/src/services/mcp.ts create mode 100644 yaml-to-production/worker/src/services/security-auditor.ts create mode 100644 yaml-to-production/worker/src/services/vercel-deployer.ts create mode 100644 yaml-to-production/worker/src/services/yaml-parser.ts create mode 100644 yaml-to-production/worker/src/types/env.ts create mode 100644 yaml-to-production/worker/src/utils/encryption.ts create mode 100644 yaml-to-production/worker/tsconfig.json create mode 100644 yaml-to-production/worker/wrangler.toml diff --git a/yaml-to-production/README.md b/yaml-to-production/README.md new file mode 100644 index 0000000..1e8dc24 --- /dev/null +++ b/yaml-to-production/README.md @@ -0,0 +1,252 @@ +# YAML-to-Production Microservice + +Transform YAML specifications into production-ready applications instantly. This microservice eliminates technical gatekeeping and human error in the software deployment pipeline by providing a simple, actionable, and secure path from a YAML-defined idea to a live, deployed application. + +## Features + +- **YAML Specification Input**: Upload or paste YAML specifications defining your application +- **AI-Powered Code Generation**: Claude AI analyzes requirements and generates production-ready code +- **Automated Security Auditing**: Every deployment is scanned for vulnerabilities with a security score +- **One-Click Deployment**: Deploy to Vercel with automatic SSL, global CDN, and instant rollbacks +- **Custom Domain Management**: Add, verify, and manage custom domains for your applications +- **Project Dashboard**: Manage and redeploy projects with saved configurations + +## Architecture + +``` +yaml-to-production/ +├── worker/ # Cloudflare Workers backend +│ ├── src/ +│ │ ├── index.ts # Main entry point (Hono app) +│ │ ├── middleware/ # Auth middleware (Privy JWT) +│ │ ├── routes/ # API route handlers +│ │ ├── services/ # Core services +│ │ │ ├── database.ts # D1 database operations +│ │ │ ├── yaml-parser.ts # YAML validation +│ │ │ ├── code-generator.ts # Claude AI integration +│ │ │ ├── security-auditor.ts # Security scanning +│ │ │ ├── vercel-deployer.ts # Vercel API +│ │ │ └── deployment-session.ts # Durable Object +│ │ ├── types/ # TypeScript types +│ │ └── utils/ # Encryption utilities +│ ├── migrations/ # D1 database migrations +│ ├── wrangler.toml # Cloudflare configuration +│ └── package.json +│ +└── frontend/ # React + Vite frontend + ├── src/ + │ ├── components/ # React components + │ │ ├── ui/ # Shared UI components + │ │ ├── deploy/ # Deployment wizard components + │ │ └── dashboard/ # Dashboard components + │ ├── pages/ # Page components + │ ├── services/ # API client + │ ├── hooks/ # Custom React hooks + │ ├── stores/ # Zustand state management + │ └── types/ # TypeScript types + ├── tailwind.config.js + ├── vite.config.ts + └── package.json +``` + +## Tech Stack + +### Backend (Cloudflare Workers) +- **Runtime**: Cloudflare Workers with Durable Objects +- **Framework**: Hono (fast, lightweight web framework) +- **Database**: D1 (SQLite at the edge) +- **Storage**: R2 (object storage for generated files) +- **Caching**: KV (key-value storage) +- **AI**: Anthropic Claude API + +### Frontend (React + Vite) +- **Framework**: React 18 with TypeScript +- **Build Tool**: Vite +- **Styling**: Tailwind CSS +- **State**: Zustand +- **Data Fetching**: TanStack Query +- **Auth**: Privy (passwordless + crypto wallets) +- **UI**: Lucide icons, Sonner toasts, Framer Motion + +## Getting Started + +### Prerequisites + +- Node.js 18+ +- npm or pnpm +- Cloudflare account +- Vercel account +- Anthropic API key +- Privy account + +### Backend Setup + +```bash +cd yaml-to-production/worker + +# Install dependencies +npm install + +# Create D1 database +wrangler d1 create yaml-to-production-db + +# Update wrangler.toml with your database ID + +# Run migrations +wrangler d1 execute yaml-to-production-db --file=./migrations/0001_schema.sql + +# Create KV namespaces +wrangler kv:namespace create CACHE +wrangler kv:namespace create SECRETS + +# Create R2 bucket +wrangler r2 bucket create yaml-to-production-projects + +# Set secrets +wrangler secret put ANTHROPIC_API_KEY +wrangler secret put VERCEL_API_TOKEN +wrangler secret put PRIVY_APP_ID +wrangler secret put PRIVY_APP_SECRET +wrangler secret put ENCRYPTION_KEY + +# Start development server +npm run dev +``` + +### Frontend Setup + +```bash +cd yaml-to-production/frontend + +# Install dependencies +npm install + +# Create .env file +cp .env.example .env + +# Edit .env with your Privy App ID +# VITE_PRIVY_APP_ID=your-privy-app-id + +# Start development server +npm run dev +``` + +### Environment Variables + +#### Worker (Cloudflare Secrets) +- `ANTHROPIC_API_KEY` - Your Anthropic API key +- `VERCEL_API_TOKEN` - Default Vercel API token +- `PRIVY_APP_ID` - Privy application ID +- `PRIVY_APP_SECRET` - Privy application secret +- `ENCRYPTION_KEY` - 256-bit hex key for encrypting user secrets + +#### Frontend +- `VITE_PRIVY_APP_ID` - Privy application ID + +## API Endpoints + +### Projects +- `GET /api/v1/projects` - List user projects +- `GET /api/v1/projects/:id` - Get project details +- `POST /api/v1/projects` - Create a new project +- `PATCH /api/v1/projects/:id` - Update project +- `DELETE /api/v1/projects/:id` - Delete project +- `POST /api/v1/projects/:id/redeploy` - Trigger redeployment + +### Deployments +- `GET /api/v1/deployments` - List deployments +- `GET /api/v1/deployments/:id` - Get deployment details +- `POST /api/v1/deployments` - Create deployment +- `GET /api/v1/deployments/:id/ws` - WebSocket for real-time updates +- `POST /api/v1/deployments/:id/cancel` - Cancel deployment + +### YAML +- `POST /api/v1/yaml/validate` - Validate YAML syntax +- `POST /api/v1/yaml/analyze` - Analyze YAML for dependencies +- `GET /api/v1/yaml/sample/:type` - Get sample YAML +- `POST /api/v1/yaml/preview` - Preview project structure + +### Domains +- `GET /api/v1/domains` - List custom domains +- `POST /api/v1/domains` - Add custom domain +- `POST /api/v1/domains/:id/verify` - Verify DNS +- `DELETE /api/v1/domains/:id` - Remove domain + +### MCP Servers +- `GET /api/v1/mcp/servers` - List available MCP servers +- `POST /api/v1/mcp/configure` - Configure MCP server +- `GET /api/v1/mcp/keys` - List stored API keys +- `POST /api/v1/mcp/keys` - Store API key + +## YAML Specification Format + +```yaml +name: my-app +description: A sample application +version: 1.0.0 +type: web-app # web-app, api, static, fullstack + +framework: react-vite # react-vite, nextjs, cloudflare-workers, static + +features: + - name: Landing Page + type: page + description: Hero section with call-to-action + + - name: Dashboard + type: page + description: User analytics dashboard + + - name: Navigation + type: component + description: Header navigation bar + +integrations: + - name: Authentication + type: auth + provider: privy + + - name: Database + type: database + provider: supabase + + - name: Payments + type: payment + provider: stripe + +environment: + VITE_APP_NAME: My App + +mcp_servers: + - github + - supabase +``` + +## Deployment + +### Deploy Worker to Cloudflare +```bash +cd worker +npm run deploy:production +``` + +### Deploy Frontend +The frontend can be deployed to any static hosting: + +```bash +cd frontend +npm run build +# Deploy the dist/ folder to Vercel, Netlify, or Cloudflare Pages +``` + +## Security + +- All API keys are encrypted with AES-256-GCM before storage +- Privy JWT tokens are verified on every request +- Row-level security enforced at the database level +- Automated security scanning before every deployment +- No secrets are ever logged or exposed in errors + +## License + +MIT diff --git a/yaml-to-production/frontend/.env.example b/yaml-to-production/frontend/.env.example new file mode 100644 index 0000000..e562e24 --- /dev/null +++ b/yaml-to-production/frontend/.env.example @@ -0,0 +1,5 @@ +# Privy Authentication +VITE_PRIVY_APP_ID=your-privy-app-id + +# API URL (optional, defaults to same origin) +# VITE_API_URL=http://localhost:8787 diff --git a/yaml-to-production/frontend/index.html b/yaml-to-production/frontend/index.html new file mode 100644 index 0000000..90c3efa --- /dev/null +++ b/yaml-to-production/frontend/index.html @@ -0,0 +1,17 @@ + + + + + + + + Prototype Cafe - YAML to Production + + + + + +
+ + + diff --git a/yaml-to-production/frontend/package.json b/yaml-to-production/frontend/package.json new file mode 100644 index 0000000..988d03b --- /dev/null +++ b/yaml-to-production/frontend/package.json @@ -0,0 +1,43 @@ +{ + "name": "yaml-to-production-frontend", + "private": true, + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0" + }, + "dependencies": { + "@privy-io/react-auth": "^1.72.0", + "@tanstack/react-query": "^5.32.0", + "canvas-confetti": "^1.9.0", + "clsx": "^2.1.1", + "framer-motion": "^11.1.0", + "lucide-react": "^0.379.0", + "react": "^18.3.0", + "react-dom": "^18.3.0", + "react-dropzone": "^14.2.3", + "react-router-dom": "^6.23.0", + "sonner": "^1.4.41", + "yaml": "^2.4.0", + "zustand": "^4.5.2" + }, + "devDependencies": { + "@types/canvas-confetti": "^1.6.0", + "@types/react": "^18.3.0", + "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^7.8.0", + "@typescript-eslint/parser": "^7.8.0", + "@vitejs/plugin-react": "^4.2.1", + "autoprefixer": "^10.4.19", + "eslint": "^8.57.0", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.6", + "postcss": "^8.4.38", + "tailwindcss": "^3.4.3", + "typescript": "^5.4.5", + "vite": "^5.2.10" + } +} diff --git a/yaml-to-production/frontend/postcss.config.js b/yaml-to-production/frontend/postcss.config.js new file mode 100644 index 0000000..2aa7205 --- /dev/null +++ b/yaml-to-production/frontend/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/yaml-to-production/frontend/src/App.tsx b/yaml-to-production/frontend/src/App.tsx new file mode 100644 index 0000000..24935ea --- /dev/null +++ b/yaml-to-production/frontend/src/App.tsx @@ -0,0 +1,93 @@ +import { Routes, Route, Navigate } from 'react-router-dom'; +import { useAuth } from '@/hooks/useAuth'; +import Layout from '@/components/ui/Layout'; +import LandingPage from '@/pages/Landing'; +import DashboardPage from '@/pages/Dashboard'; +import DeployPage from '@/pages/Deploy'; +import ProjectPage from '@/pages/Project'; +import SettingsPage from '@/pages/Settings'; +import LoadingSpinner from '@/components/ui/LoadingSpinner'; + +function ProtectedRoute({ children }: { children: React.ReactNode }) { + const { isLoading, isAuthenticated, login } = useAuth(); + + if (isLoading) { + return ( +
+ +
+ ); + } + + if (!isAuthenticated) { + return ( +
+
+

Sign in required

+

Please sign in to access this page

+ +
+
+ ); + } + + return <>{children}; +} + +function App() { + return ( + + } /> + + + + + + + } + /> + + + + + + + } + /> + + + + + + + } + /> + + + + + + + } + /> + + } /> + + ); +} + +export default App; diff --git a/yaml-to-production/frontend/src/components/deploy/DeploymentComplete.tsx b/yaml-to-production/frontend/src/components/deploy/DeploymentComplete.tsx new file mode 100644 index 0000000..c8c253f --- /dev/null +++ b/yaml-to-production/frontend/src/components/deploy/DeploymentComplete.tsx @@ -0,0 +1,199 @@ +import { Link } from 'react-router-dom'; +import { useDeployStore } from '@/stores/deploy'; +import { + CheckCircle, + ExternalLink, + Globe, + BarChart, + Settings, + Copy, + ArrowRight, +} from 'lucide-react'; +import { toast } from 'sonner'; +import confetti from 'canvas-confetti'; +import { useEffect } from 'react'; + +export default function DeploymentComplete() { + const { productionUrl, previewUrl, projectName, project, securityScore, reset } = + useDeployStore(); + + useEffect(() => { + // Celebrate! + confetti({ + particleCount: 100, + spread: 70, + origin: { y: 0.6 }, + }); + }, []); + + const copyUrl = (url: string) => { + navigator.clipboard.writeText(url); + toast.success('URL copied to clipboard!'); + }; + + const handleNewDeployment = () => { + reset(); + }; + + return ( +
+ {/* Success Icon */} +
+ +
+ +
+

+ Deployment Complete! 🎉 +

+

+ Your application {projectName} is now live. +

+
+ + {/* URLs */} +
+ {productionUrl && ( +
+ +
+
+ {productionUrl} +
+ + + + +
+
+ )} + + {previewUrl && previewUrl !== productionUrl && ( +
+ +
+
+ {previewUrl} +
+ +
+
+ )} +
+ + {/* Stats */} +
+
+
+ {securityScore || 95} +
+
Security Score
+
+
+
~2min
+
Build Time
+
+
+
Live
+
Status
+
+
+ + {/* Next Steps */} +
+

Next Steps

+
+ + + +
+
+ + {/* Actions */} +
+ + Go to Dashboard + + + +
+
+ ); +} + +function NextStepItem({ + icon: Icon, + title, + description, + href, + external, +}: { + icon: React.ElementType; + title: string; + description: string; + href: string; + external?: boolean; +}) { + const content = ( +
+
+ +
+
+

{title}

+

{description}

+
+ +
+ ); + + if (external) { + return ( + + {content} + + ); + } + + return {content}; +} diff --git a/yaml-to-production/frontend/src/components/deploy/DeploymentPreview.tsx b/yaml-to-production/frontend/src/components/deploy/DeploymentPreview.tsx new file mode 100644 index 0000000..179ee6d --- /dev/null +++ b/yaml-to-production/frontend/src/components/deploy/DeploymentPreview.tsx @@ -0,0 +1,163 @@ +import { useState } from 'react'; +import { useDeployStore } from '@/stores/deploy'; +import { + ExternalLink, + RefreshCw, + Smartphone, + Monitor, + Tablet, + ChevronRight, +} from 'lucide-react'; + +type DeviceSize = 'mobile' | 'tablet' | 'desktop'; + +const deviceSizes: Record = { + mobile: { width: 375, height: 667, label: 'Mobile', icon: Smartphone }, + tablet: { width: 768, height: 1024, label: 'Tablet', icon: Tablet }, + desktop: { width: 1280, height: 800, label: 'Desktop', icon: Monitor }, +}; + +export default function DeploymentPreview() { + const { previewUrl, productionUrl, projectName, setStep } = useDeployStore(); + const [deviceSize, setDeviceSize] = useState('desktop'); + const [isRefreshing, setIsRefreshing] = useState(false); + const [iframeKey, setIframeKey] = useState(0); + + const handleRefresh = () => { + setIsRefreshing(true); + setIframeKey((prev) => prev + 1); + setTimeout(() => setIsRefreshing(false), 1000); + }; + + const handleFinalize = () => { + setStep('complete'); + }; + + const device = deviceSizes[deviceSize]; + + return ( +
+
+

+ Preview Your App +

+

+ Review your deployed application before finalizing. +

+
+ + {/* URL Bar */} +
+
+ {previewUrl || productionUrl || 'https://your-app.vercel.app'} +
+ + + + +
+ + {/* Device Selector */} +
+ {(Object.entries(deviceSizes) as [DeviceSize, typeof device][]).map( + ([key, { label, icon: Icon }]) => ( + + ) + )} +
+ + {/* Preview Frame */} +
+
+ {/* Browser Chrome */} +
+
+
+
+
+
+
+ + {projectName || 'Preview'} + +
+
+ + {/* Iframe */} +
+ {previewUrl || productionUrl ? ( +