Skip to content

Commit 2ae8076

Browse files
drhemaclaude
andcommitted
feat: framework-aware AI prompts for Nuxt/Astro/Next.js
- Convert DIRECT_CODER_PROMPT and MAESTRO_PLANNER_PROMPT from constants to functions that accept framework parameter - Add framework-specific instructions for routing, components, backend APIs, build rules, and dependencies - Update research-plan.ts planner prompt and search queries to be framework-aware - Update ralph-loop.ts fix prompt with framework-specific error handling (Nuxt auto-imports, Astro client directives, Next.js SSG) - Update project creation to use createRepoFromTemplate with template repo lookup - Pass project.framework through entire pipeline: classify → research → plan → generate → fix Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2508529 commit 2ae8076

5 files changed

Lines changed: 344 additions & 201 deletions

File tree

src/app/api/vibecoder/projects/route.ts

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NextRequest, NextResponse } from 'next/server'
22
import { prisma } from '@/lib/db'
33
import { verifyToken, getAuthCookie } from '@/lib/auth'
4-
import { createRepo, scaffoldProjectRepo } from '@/lib/vibecoder/github'
4+
import { createRepo, createRepoFromTemplate } from '@/lib/vibecoder/github'
55
import crypto from 'crypto'
66

77
async function getUser(request: NextRequest) {
@@ -63,23 +63,18 @@ export async function POST(request: NextRequest) {
6363

6464
try {
6565
if (importRepo) {
66-
// Import existing repo — for now just reference it
66+
// Import existing repo — just reference it
6767
githubRepo = importRepo
6868
} else {
69-
// Create new repo
70-
const templateName = template ? `vc-template-${framework}` : undefined
71-
if (templateName) {
72-
// Try template, fallback to empty repo
73-
try {
74-
const { fullName } = await (await import('@/lib/vibecoder/github')).createRepoFromTemplate(
75-
templateName, repoName, description || `VibeCoder project: ${name}`,
76-
)
77-
githubRepo = fullName
78-
} catch {
79-
const { fullName } = await createRepo(repoName, description || `VibeCoder project: ${name}`)
80-
githubRepo = fullName
81-
}
82-
} else {
69+
// Always create from framework template (includes Dockerfile, CI/CD, Prisma, auth, etc.)
70+
try {
71+
const { fullName } = await createRepoFromTemplate(
72+
framework, repoName, description || `VibeCoder project: ${name}`,
73+
)
74+
githubRepo = fullName
75+
} catch (templateErr: any) {
76+
// Fallback to empty repo if template doesn't exist
77+
console.warn(`Template creation failed for ${framework}, falling back to empty repo: ${templateErr.message}`)
8378
const { fullName } = await createRepo(repoName, description || `VibeCoder project: ${name}`)
8479
githubRepo = fullName
8580
}
@@ -143,16 +138,12 @@ async function setupProject(projectId: string) {
143138
const project = await prisma.vcProject.findUnique({ where: { id: projectId } })
144139
if (!project) return
145140

146-
// Scaffold the repo with Dockerfile, GitHub Actions workflow, and starter files
141+
// Template repos already include Dockerfile, GitHub Actions, Prisma, auth, etc.
142+
// No scaffolding needed — repo was created from template in the POST handler.
143+
// Just wait a moment for GitHub to finish generating the repo from template.
147144
if (!project.importedRepo && project.githubRepo) {
148-
try {
149-
console.log(`Scaffolding repo ${project.githubRepo} for ${project.framework}...`)
150-
await scaffoldProjectRepo(project.githubRepo, project.framework, project.name)
151-
console.log(`Scaffold complete for ${project.githubRepo}`)
152-
} catch (err: any) {
153-
console.error(`Scaffold failed for ${project.githubRepo}: ${err.message}`)
154-
// Non-fatal — project can still work, user can add files via AI chat
155-
}
145+
await new Promise(r => setTimeout(r, 3000))
146+
console.log(`Repo ${project.githubRepo} created from ${project.framework} template`)
156147
}
157148

158149
const portainerApiKey = process.env.PORTAINER_API_KEY || ''

src/lib/vibecoder/github.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,31 @@ export interface FileContent {
2727
size: number
2828
}
2929

30-
/** Create a repo from a template */
30+
// Template repos for each framework (must exist under GITHUB_OWNER and be marked as template repos)
31+
const TEMPLATE_REPOS: Record<string, string> = {
32+
nextjs: 'vibecoder-template-nextjs',
33+
nuxt: 'vibecoder-template-nuxt',
34+
astro: 'vibecoder-template-astro',
35+
}
36+
37+
/** Create a repo from a framework template. Includes Dockerfile, GitHub Actions, Prisma, auth, etc. */
3138
export async function createRepoFromTemplate(
32-
templateRepo: string,
39+
framework: string,
3340
newRepoName: string,
3441
description: string,
35-
isPrivate = true,
42+
isPrivate = false,
3643
): Promise<{ fullName: string; htmlUrl: string }> {
44+
const templateRepo = TEMPLATE_REPOS[framework]
45+
if (!templateRepo) {
46+
throw new Error(`No template for framework: ${framework}. Supported: ${Object.keys(TEMPLATE_REPOS).join(', ')}`)
47+
}
48+
3749
const res = await fetch(`${GITHUB_API}/repos/${GITHUB_OWNER}/${templateRepo}/generate`, {
3850
method: 'POST',
39-
headers: getHeaders(),
51+
headers: {
52+
...getHeaders(),
53+
Accept: 'application/vnd.github+json',
54+
},
4055
body: JSON.stringify({
4156
owner: GITHUB_OWNER,
4257
name: newRepoName,
@@ -47,7 +62,7 @@ export async function createRepoFromTemplate(
4762
})
4863
if (!res.ok) {
4964
const err = await res.json()
50-
throw new Error(`Failed to create repo: ${err.message}`)
65+
throw new Error(`Failed to create repo from template ${templateRepo}: ${err.message}`)
5166
}
5267
const data = await res.json()
5368
return { fullName: data.full_name, htmlUrl: data.html_url }

0 commit comments

Comments
 (0)