Merge branch 'main' into morph-fast-apply

This commit is contained in:
Bekbol Bolatov
2025-09-12 05:41:03 +05:00
committed by GitHub
317 changed files with 35816 additions and 7580 deletions
+115 -31
View File
@@ -129,6 +129,7 @@ function parseAIResponse(response: string): ParsedResponse {
declare global {
var activeSandbox: any;
var activeSandboxProvider: any;
var existingFiles: Set<string>;
var sandboxState: SandboxState;
}
@@ -157,8 +158,11 @@ export async function POST(request: NextRequest) {
global.existingFiles = new Set<string>();
}
// Get the active sandbox or provider
const sandbox = global.activeSandbox || global.activeSandboxProvider;
// If no active sandbox, just return parsed results
if (!global.activeSandbox) {
if (!sandbox) {
return NextResponse.json({
success: true,
results: {
@@ -174,6 +178,30 @@ export async function POST(request: NextRequest) {
});
}
// Verify sandbox is ready before applying code
console.log('[apply-ai-code] Verifying sandbox is ready...');
// For Vercel sandboxes, check if Vite is running
if (sandbox.constructor?.name === 'VercelProvider' || sandbox.getSandboxInfo?.()?.provider === 'vercel') {
console.log('[apply-ai-code] Detected Vercel sandbox, checking Vite status...');
try {
// Check if Vite process is running
const checkResult = await sandbox.runCommand('pgrep -f vite');
if (!checkResult || !checkResult.stdout) {
console.log('[apply-ai-code] Vite not running, starting it...');
// Start Vite if not running
await sandbox.runCommand('sh -c "cd /vercel/sandbox && nohup npm run dev > /tmp/vite.log 2>&1 &"');
// Wait for Vite to start
await new Promise(resolve => setTimeout(resolve, 5000));
console.log('[apply-ai-code] Vite started, proceeding with code application');
} else {
console.log('[apply-ai-code] Vite is already running');
}
} catch (e) {
console.log('[apply-ai-code] Could not check Vite status, proceeding anyway:', e);
}
}
// Apply to active sandbox
console.log('[apply-ai-code] Applying code to sandbox...');
console.log('[apply-ai-code] Is edit mode:', isEdit);
@@ -403,11 +431,28 @@ export async function POST(request: NextRequest) {
fileContent = fileContent.replace(/import\s+['"]\.\/[^'"]+\.css['"];?\s*\n?/g, '');
}
// Fix common Tailwind CSS errors in CSS files
if (file.path.endsWith('.css')) {
// Replace shadow-3xl with shadow-2xl (shadow-3xl doesn't exist)
fileContent = fileContent.replace(/shadow-3xl/g, 'shadow-2xl');
// Replace any other non-existent shadow utilities
fileContent = fileContent.replace(/shadow-4xl/g, 'shadow-2xl');
fileContent = fileContent.replace(/shadow-5xl/g, 'shadow-2xl');
}
console.log(`[apply-ai-code] Writing file using E2B files API: ${fullPath}`);
try {
// Use the correct E2B API - sandbox.files.write()
await global.activeSandbox.files.write(fullPath, fileContent);
// Check if we're using provider pattern (v2) or direct sandbox (v1)
if (sandbox.writeFile) {
// V2: Provider pattern (Vercel/E2B provider)
await sandbox.writeFile(file.path, fileContent);
} else if (sandbox.files?.write) {
// V1: Direct E2B sandbox
await sandbox.files.write(fullPath, fileContent);
} else {
throw new Error('Unsupported sandbox type');
}
console.log(`[apply-ai-code] Successfully wrote file: ${fullPath}`);
// Update file cache
@@ -499,15 +544,17 @@ function App() {
export default App;`;
try {
await global.activeSandbox.runCode(`
file_path = "/home/user/app/src/App.jsx"
file_content = """${appContent.replace(/"/g, '\\"').replace(/\n/g, '\\n')}"""
with open(file_path, 'w') as f:
f.write(file_content)
print(f"Auto-generated: {file_path}")
`);
// Use provider pattern if available
if (sandbox.writeFile) {
await sandbox.writeFile('src/App.jsx', appContent);
} else if (sandbox.writeFiles) {
await sandbox.writeFiles([{
path: 'src/App.jsx',
content: Buffer.from(appContent)
}]);
}
console.log('Auto-generated: src/App.jsx');
results.filesCreated.push('src/App.jsx (auto-generated)');
} catch (error) {
results.errors.push(`Failed to create App.jsx: ${(error as Error).message}`);
@@ -526,9 +573,7 @@ print(f"Auto-generated: {file_path}")
if (!isEdit && !indexCssInParsed && !indexCssExists) {
try {
await global.activeSandbox.runCode(`
file_path = "/home/user/app/src/index.css"
file_content = """@tailwind base;
const indexCssContent = `@tailwind base;
@tailwind components;
@tailwind utilities;
@@ -550,15 +595,22 @@ body {
margin: 0;
min-width: 320px;
min-height: 100vh;
}"""
}`;
with open(file_path, 'w') as f:
f.write(file_content)
print(f"Auto-generated: {file_path}")
`);
// Use provider pattern if available
if (sandbox.writeFile) {
await sandbox.writeFile('src/index.css', indexCssContent);
} else if (sandbox.writeFiles) {
await sandbox.writeFiles([{
path: 'src/index.css',
content: Buffer.from(indexCssContent)
}]);
}
console.log('Auto-generated: src/index.css');
results.filesCreated.push('src/index.css (with Tailwind)');
} catch {
} catch (error) {
console.error('Failed to create index.css:', error);
results.errors.push('Failed to create index.css with Tailwind');
}
}
@@ -567,15 +619,47 @@ print(f"Auto-generated: {file_path}")
// Execute commands
for (const cmd of parsed.commands) {
try {
await global.activeSandbox.runCode(`
import subprocess
os.chdir('/home/user/app')
result = subprocess.run(${JSON.stringify(cmd.split(' '))}, capture_output=True, text=True)
print(f"Executed: ${cmd}")
print(result.stdout)
if result.stderr:
print(f"Errors: {result.stderr}")
`);
// Parse command and arguments
const commandParts = cmd.trim().split(/\s+/);
const cmdName = commandParts[0];
const args = commandParts.slice(1);
// Execute command using sandbox
let result;
if (sandbox.runCommand && typeof sandbox.runCommand === 'function') {
// Check if this is a provider pattern sandbox
const testResult = await sandbox.runCommand(cmd);
if (testResult && typeof testResult === 'object' && 'stdout' in testResult) {
// Provider returns CommandResult directly
result = testResult;
} else {
// Direct sandbox - expects object with cmd and args
result = await sandbox.runCommand({
cmd: cmdName,
args
});
}
}
console.log(`Executed: ${cmd}`);
// Handle result based on type
let stdout = '';
let stderr = '';
if (result) {
if (typeof result.stdout === 'string') {
stdout = result.stdout;
stderr = result.stderr || '';
} else if (typeof result.stdout === 'function') {
stdout = await result.stdout();
stderr = await result.stderr();
}
}
if (stdout) console.log(stdout);
if (stderr) console.log(`Errors: ${stderr}`);
results.commandsExecuted.push(cmd);
} catch (error) {
results.errors.push(`Failed to execute ${cmd}: ${(error as Error).message}`);