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
196 changes: 188 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,196 @@
</tr>
</table>

https://github.com/user-attachments/assets/403225b6-0665-4dea-b33c-2f49552d5031
## Overview

NeoCode is an AI-powered website builder that generates complete Next.js applications from single prompts using a multi-agent architecture. The system orchestrates specialized AI agents to handle code generation, task summarization, and user response creation in isolated sandbox environments.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add article for grammatical correctness.

The phrase "from single prompts" needs an article.

📝 Proposed fix
-NeoCode is an AI-powered website builder that generates complete Next.js applications from single prompts using a multi-agent architecture. The system orchestrates specialized AI agents to handle code generation, task summarization, and user response creation in isolated sandbox environments. 
+NeoCode is an AI-powered website builder that generates complete Next.js applications from a single prompt using a multi-agent architecture. The system orchestrates specialized AI agents to handle code generation, task summarization, and user response creation in isolated sandbox environments.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
NeoCode is an AI-powered website builder that generates complete Next.js applications from single prompts using a multi-agent architecture. The system orchestrates specialized AI agents to handle code generation, task summarization, and user response creation in isolated sandbox environments.
NeoCode is an AI-powered website builder that generates complete Next.js applications from a single prompt using a multi-agent architecture. The system orchestrates specialized AI agents to handle code generation, task summarization, and user response creation in isolated sandbox environments.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` at line 34, Replace the phrase "from single prompts" in the README
sentence with "from a single prompt" so the line reads "...that generates
complete Next.js applications from a single prompt..." to correct the grammar;
locate the sentence containing "NeoCode is an AI-powered website builder..." and
update that fragment accordingly.


## Quick Start

## Get started
### Prerequisites
- git
- recent version of NodeJS and NPM
- E2B
- Gemini API key
- Neon URL
- Clerk secrets (for billing)

Before you begin, ensure you have the following:

- **Development Tools**: git, recent Node.js and NPM
- **API Keys & Services**:
- E2B API key for sandbox environments
- Gemini API key for AI model access
- Neon database URL for PostgreSQL
- Clerk secrets for authentication and billing

### Installation

1. Clone the repository:
```bash
git clone <repository-url>
cd neocode
```

2. Install dependencies:
```bash
npm install
```

3. Configure environment variables:
```bash
# Copy the example environment file
cp .env.example .env.local

# Edit with your API keys and configuration
```

4. Set up the database:
```bash
npx prisma migrate dev
npx prisma generate
```

5. Start the development server:
```bash
npm run dev
```

## Usage Guide

### Basic Usage

1. **Access the Application**: Navigate to `http://localhost:3000`
2. **Enter Your Prompt**: Describe the website you want to build in natural language
3. **Wait for Generation**: The AI agents will create your application in the sandbox
4. **Preview Results**: View the generated application with the provided preview URL

## Development Guide

### Architecture Overview

NeoCode uses a multi-agent system with the following key components:

```mermaid
graph TB
User["User Prompt"]
Trigger["tRPC API"]
Inngest["Inngest Event System"]
CodeAgent["codeAgent (gemini-2.5-flash)"]
Sandbox["E2B Sandbox"]
Database["Prisma/PostgreSQL"]

User --> Trigger
Trigger --> Inngest
Inngest --> CodeAgent
CodeAgent --> Sandbox
CodeAgent --> Database
Sandbox --> CodeAgent
```

### Core Components

**1. Agent System** (`src/inngest/functions.ts`)
- `codeAgentFunction`: Main orchestrator that handles the entire workflow.
- `codeAgent`: Primary AI agent for code generation using Gemini 2.5 Flash.
- `createNetwork`: Manages iterative execution with router logic.

**2. State Management**
The system maintains state through the `AgentState` interface:
```typescript
interface AgentState {
summary: string,
files: { [path: string]: string }
}
```

**3. Tool System**
The agent interacts with the sandbox through three main tools:
- `terminal`: Execute shell commands (npm install, etc.)
- `createOrUpdateFiles`: Write files to the sandbox
- `readFiles`: Read file contents for verification

### Adding New Features

**1. Extending the Agent Tools**
To add new capabilities, modify the tools array in `src/inngest/functions.ts`:

```typescript
tools: [
// Existing tools...
createTool({
name: "your-new-tool",
description: "Description of what it does",
parameters: z.object({
// Define your parameters
}),
handler: async ({ parameters, step, network }) => {
// Implementation
}
})
]
```

**2. Modifying the System Prompt**
Update `src/prompt.ts` to:
- Add new coding standards
- Include additional component libraries
- Modify workflow instructions
- Update success criteria

**3. Customizing the Sandbox**
Modify the sandbox configuration in the agent function:
```typescript
const sandbox = await Sandbox.create("neo-test-1");
await sandbox.setTimeout(SANDBOX_TIMEOUT);
```

### Development Workflow

**1. Local Development**
- Use `npm run dev` for the main application
- Test prompts through the web interface
- Monitor agent execution in the console

**2. Debugging Agent Execution**
- Check Inngest dashboard for function execution
- Review sandbox logs for file operations
- Examine database records for generated content

**3. Testing Changes**
- Test with various prompt types
- Verify component imports and usage
- Check responsive design output
- Validate TypeScript compilation

## Deployment

### Environment Setup

1. **Production Database**: Configure Neon PostgreSQL
2. **API Keys**: Set up production API keys for all services
3. **Environment Variables**: Configure all required environment variables

### Deployment Steps

1. **Build the Application**:
```bash
npm run build
```

2. **Deploy to Vercel**:
```bash
vercel --prod
```

3. **Configure Inngest**: Set up production Inngest functions

## Contributing

### Submitting Changes

1. Fork the repository
2. Create a feature branch
3. Implement your changes
4. Test it
5. Submit a pull request with detailed description






3 changes: 2 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint",
"lint": "next lint",
"postinstall": "prisma generate"
},
"dependencies": {
Expand Down Expand Up @@ -88,6 +88,6 @@
"tailwindcss": "^4",
"tsx": "^4.20.3",
"tw-animate-css": "^1.3.4",
"typescript": "^5"
"typescript": "^5.8.3"
}
}
4 changes: 2 additions & 2 deletions src/app/projects/[projectId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ export default async function Page({
// PREFETCH
void queryClient.prefetchQuery(trpc.messages.getMany.queryOptions({
projectId: projectId
}))
}));
void queryClient.prefetchQuery(trpc.projects.getOne.queryOptions({
id: projectId
}))
}));
Comment on lines 17 to +22

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Find fire-and-forget prefetch calls:"
rg -nP --type=tsx '\bvoid\s+queryClient\.prefetchQuery\('

echo
echo "Find dehydration call sites:"
rg -nP --type=tsx '\bdehydrate\s*\(\s*queryClient\s*\)'

Repository: devdezzies/neocode

Length of output: 143


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the file mentioned in the review
echo "Locating file: src/app/projects/[projectId]/page.tsx"
if [ -f "src/app/projects/[projectId]/page.tsx" ]; then
    echo "File found!"
else
    echo "Checking directory structure..."
    find . -type f -name "page.tsx" | head -20
fi

Repository: devdezzies/neocode

Length of output: 126


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Reading src/app/projects/[projectId]/page.tsx:"
cat -n "src/app/projects/[projectId]/page.tsx"

Repository: devdezzies/neocode

Length of output: 1397


Await prefetches before dehydration.

The void operator on lines 17 and 20 discards the prefetch Promises, allowing dehydrate(queryClient) on line 25 to execute before the prefetches complete. This causes the queryClient cache to be unpopulated during dehydration, resulting in missing prefetched state on first render.

Use await Promise.all([...]) to ensure both prefetches complete before the component returns.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/projects/`[projectId]/page.tsx around lines 17 - 22, The prefetch
Promises started with queryClient.prefetchQuery (using
trpc.messages.getMany.queryOptions and trpc.projects.getOne.queryOptions) are
discarded with the void operator, causing dehydrate(queryClient) to run before
the cache is populated; replace the void calls by awaiting both prefetches
(e.g., await Promise.all([...prefetch calls...])) so both
queryClient.prefetchQuery calls finish before calling dehydrate(queryClient).


return (
<HydrationBoundary state={dehydrate(queryClient)}>
Expand Down
2 changes: 1 addition & 1 deletion src/inngest/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const codeAgentFunction = inngest.createFunction(
name: "terminal",
description: "Use the terminal to run commands",
parameters: z.object({
command: z.string(),
command: z.string()
}),
handler: async ({ command }, { step }) => {
return await step?.run("terminal", async () => {
Expand Down
1 change: 0 additions & 1 deletion src/modules/home/ui/components/project-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export default function ProjectForm() {
router.push('/pricing');
}


toast.error(error.message);
}
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Skeleton } from "@/components/ui/skeleton";

export default function MessageContainerSkeleton() {
return (
<div className="flex flex-col flex-1 min-h-0 px-2">
<div className="w-full h-20 flex flex-col flex-1 min-h-0 px-2 bg-amber-200">

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Skeleton-related components and explicit bg-* classes:"
fd -HI '.*skeleton.*\.tsx$' src | while read -r f; do
  echo "--- $f"
  rg -n 'className=.*bg-' "$f" || true
done

Repository: devdezzies/neocode

Length of output: 447


🏁 Script executed:

cat -n src/modules/projects/ui/components/message-container-skeleton.tsx

Repository: devdezzies/neocode

Length of output: 479


🏁 Script executed:

cat -n src/components/ui/skeleton.tsx

Repository: devdezzies/neocode

Length of output: 428


🏁 Script executed:

cat -n src/modules/projects/ui/components/project-header-skeleton.tsx

Repository: devdezzies/neocode

Length of output: 415


🏁 Script executed:

rg -n 'bg-accent|bg-\[' src/components/ui/skeleton.tsx src/modules/projects/ui/components/

Repository: devdezzies/neocode

Length of output: 164


🏁 Script executed:

fd -HI 'theme|colors|tailwind' src | head -20

Repository: devdezzies/neocode

Length of output: 132


🏁 Script executed:

cat -n src/hooks/use-current-theme.ts

Repository: devdezzies/neocode

Length of output: 367


🏁 Script executed:

cat -n src/components/code-view/code-theme.css

Repository: devdezzies/neocode

Length of output: 3901


🏁 Script executed:

fd -HI 'tailwind|theme' . --max-depth 3 | grep -E '\.(config|json|css)$'

Repository: devdezzies/neocode

Length of output: 44


🏁 Script executed:

find . -name 'tailwind.config.*' -o -name 'globals.css' | head -10

Repository: devdezzies/neocode

Length of output: 83


🏁 Script executed:

rg -n 'bg-accent|--accent|@apply' src/components/ui/ --max-count 5

Repository: devdezzies/neocode

Length of output: 10169


🏁 Script executed:

cat -n src/app/globals.css

Repository: devdezzies/neocode

Length of output: 8665


Replace bg-amber-200 with bg-accent for theme consistency.

The hard-coded amber background won't adapt to light/dark mode switching. The entire codebase uses bg-accent (defined in globals.css as oklch(0.9702 0 0) for light and oklch(0.3715 0 0) for dark), including the Skeleton component that this wrapper contains. Using bg-amber-200 breaks the theme system and creates visual inconsistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/projects/ui/components/message-container-skeleton.tsx` at line 5,
In the MessageContainerSkeleton component replace the hard-coded Tailwind class
bg-amber-200 with bg-accent so the wrapper div (the <div className="w-full h-20
flex flex-col flex-1 min-h-0 px-2 ..."> in message-container-skeleton.tsx) uses
the theme token; update the className to include bg-accent (and remove
bg-amber-200) to match the Skeleton component and global theme colors.

<div className="pt-2 pr-1">
<Skeleton className="w-full h-10" />
</div>
Expand Down