Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions apps/vibe-coding-platform/ai/tools/generate-files-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,58 @@ Create a set of files based on the current state of the project and conversation
5. Assume any previously generated files already exist in the sandbox — write with compatibility in mind.
6. Favor minimal, functional implementations that demonstrate correctness and are ready to be run, built, or extended.
7. Include configuration, setup, or support files (e.g., \`.env\`, \`tsconfig.json\`, \`vite.config.ts\`) if the task depends on them working.
8. You support deploying generated files to Vercel. If what you are generating is supported by Vercel, then also generate a vercel.json with the fields.
Generate vercel.json with the format of:
{
framework: string
}

Supported frameworks are:
nextjs
nuxtjs
svelte
create-react-app
gatsby
remix
react-router
solidstart
sveltekit
blitzjs
astro
hexo
eleventy
docusaurus-2
docusaurus
preact
solidstart-1
dojo
ember
vue
scully
ionic-angular
angular
polymer
sveltekit-1
ionic-react
gridsome
umijs
sapper
saber
stencil
redwoodjs
hugo
jekyll
brunch
middleman
zola
hydrogen
vite
vitepress
vuepress
parcel
fasthtml
sanity-v3
sanity
storybook
nitro
hono
101 changes: 101 additions & 0 deletions apps/vibe-coding-platform/app/api/deploy/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { Sandbox } from '@vercel/sandbox'
import { Vercel } from '@vercel/sdk'
import { NextResponse } from 'next/server'
import z from 'zod/v4'

const deployRequestSchema = z.object({
paths: z.array(z.string().min(1)),
sandboxId: z.string().min(1),
projectId: z.string().nullable().optional(),
})

const vercelJsonSchema = z.object({
framework: z.string().min(1),
})

const deploymentIdSchema = z.string().min(1)

// VERCEL_TOKEN is the token for the team you want agent generated code to be deployed to

export async function POST(request: Request) {
const body = await request.json()
const { paths, sandboxId, projectId } = deployRequestSchema.parse(body)

const sandbox = await Sandbox.get({ sandboxId })
const readFile = async (path: string) => {
const stream = await sandbox.readFile({ path })
const response = new Response(stream as unknown as ReadableStream)
const text = await response.text()
return {
file: path,
data: text,
}
}

const files = await Promise.all(paths.map(readFile))

const vercel = new Vercel({
bearerToken: process.env.VERCEL_TOKEN,
})

const random4Chars = Math.random().toString(36).substring(2, 6)

const vercelJson = files.find((file) => file.file === 'vercel.json')
let projectSettings: Record<string, unknown> = {}
if (vercelJson) {
const vercelJsonData = vercelJsonSchema.parse(JSON.parse(vercelJson.data))
projectSettings = {
framework: vercelJsonData.framework,
}
}

const deployment = await vercel.deployments.createDeployment({
requestBody: {
name: `oss-vibe-coding-platform-deploy-${random4Chars}`,
files,
target: 'production',
projectSettings,
project: projectId ?? undefined,
},
})

// We don't want protection on deployments as they're public
// Run this logic only once based on if projectId is null
if (!projectId) {
await vercel.projects.updateProject({
requestBody: { ssoProtection: null },
idOrName: deployment.projectId,
})
}

return NextResponse.json({
url: deployment.url,
id: deployment.id,
projectId: deployment.projectId,
})
}

export async function GET(request: Request) {
const { searchParams } = new URL(request.url)
const idParam = searchParams.get('id')
if (!idParam) {
return NextResponse.json(
{ error: 'Missing deployment id' },
{ status: 400 }
)
}

const deploymentId = deploymentIdSchema.parse(idParam)

const vercel = new Vercel({ bearerToken: process.env.VERCEL_TOKEN })

const deployment = await vercel.deployments.getDeployment({
idOrUrl: deploymentId,
})

return NextResponse.json({
readyState: deployment.readyState,
url: deployment.url,
id: deployment.id,
})
}
4 changes: 3 additions & 1 deletion apps/vibe-coding-platform/app/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ interface Props {
}

export function Preview({ className }: Props) {
const { status, url } = useSandboxStore()
const { status, url, paths, sandboxId } = useSandboxStore()
return (
<PreviewComponent
className={className}
disabled={status === 'stopped'}
url={url}
paths={paths}
sandboxId={sandboxId}
/>
)
}
Loading