confirm build

This commit is contained in:
Developers Digest
2025-09-10 10:12:06 -04:00
parent 8687860a47
commit 13a4c5e1de
42 changed files with 6151 additions and 439 deletions
+1 -1
View File
@@ -76,7 +76,7 @@ export async function POST(request: NextRequest) {
// Create a summary of available files for the AI
const validFiles = Object.entries(manifest.files as Record<string, any>)
.filter(([path, _info]) => {
.filter(([path]) => {
// Filter out invalid paths
return path.includes('.') && !path.match(/\/\d+$/);
});
+2 -2
View File
@@ -1,10 +1,10 @@
import { NextRequest, NextResponse } from 'next/server';
import { NextResponse } from 'next/server';
declare global {
var activeSandbox: any;
}
export async function POST(_request: NextRequest) {
export async function POST() {
try {
if (!global.activeSandbox) {
return NextResponse.json({
+13 -12
View File
@@ -194,7 +194,7 @@ export async function POST(request: NextRequest) {
if (manifest) {
await sendProgress({ type: 'status', message: '🔍 Creating search plan...' });
const fileContents = global.sandboxState.fileCache.files;
const fileContents = global.sandboxState.fileCache?.files || {};
console.log('[generate-ai-code-stream] Files available for search:', Object.keys(fileContents).length);
// STEP 1: Get search plan from AI
@@ -244,7 +244,7 @@ export async function POST(request: NextRequest) {
console.log('[generate-ai-code-stream] Target selected:', target);
// Create surgical edit context with exact location
const normalizedPath = target.filePath.replace('/home/user/app/', '');
// normalizedPath would be: target.filePath.replace('/home/user/app/', '');
// fileContent available but not used in current implementation
// const fileContent = fileContents[normalizedPath]?.content || '';
@@ -356,7 +356,7 @@ User request: "${prompt}"`;
// For now, fall back to keyword search since we don't have file contents for search execution
// This path happens when no manifest was initially available
let targetFiles = [];
let targetFiles: any[] = [];
if (!searchPlan || searchPlan.searchTerms.length === 0) {
console.warn('[generate-ai-code-stream] No target files after fetch, searching for relevant files');
@@ -985,13 +985,15 @@ CRITICAL: When files are provided in the context:
// Store files in cache
for (const [path, content] of Object.entries(filesData.files)) {
const normalizedPath = path.replace('/home/user/app/', '');
global.sandboxState.fileCache.files[normalizedPath] = {
content: content as string,
lastModified: Date.now()
};
if (global.sandboxState.fileCache) {
global.sandboxState.fileCache.files[normalizedPath] = {
content: content as string,
lastModified: Date.now()
};
}
}
if (filesData.manifest) {
if (filesData.manifest && global.sandboxState.fileCache) {
global.sandboxState.fileCache.manifest = filesData.manifest;
// Now try to analyze edit intent with the fetched manifest
@@ -1023,7 +1025,7 @@ CRITICAL: When files are provided in the context:
}
// Update variables
backendFiles = global.sandboxState.fileCache.files;
backendFiles = global.sandboxState.fileCache?.files || {};
hasBackendFiles = Object.keys(backendFiles).length > 0;
console.log('[generate-ai-code-stream] Updated backend cache with fetched files');
}
@@ -1363,7 +1365,7 @@ It's better to have 3 complete files than 10 incomplete files.`
let tagBuffer = '';
// Stream the response and parse for packages in real-time
for await (const textPart of result.textStream) {
for await (const textPart of result?.textStream || []) {
const text = textPart || '';
generatedCode += text;
currentFile += text;
@@ -1729,8 +1731,7 @@ Provide the complete file content without any truncation. Include all necessary
},
{ role: 'user', content: completionPrompt }
],
temperature: isGPT5 ? undefined : appConfig.ai.defaultTemperature,
maxTokens: appConfig.ai.truncationRecoveryMaxTokens
temperature: model.startsWith('openai/gpt-5') ? undefined : appConfig.ai.defaultTemperature
});
// Get the full text from the stream
+2 -2
View File
@@ -44,7 +44,7 @@ export async function GET() {
throw new Error('Failed to list files');
}
const fileList = (await findResult.stdout()).split('\n').filter(f => f.trim());
const fileList = (await findResult.stdout()).split('\n').filter((f: string) => f.trim());
console.log('[get-sandbox-files] Found', fileList.length, 'files');
// Read content of each file (limit to reasonable sizes)
@@ -91,7 +91,7 @@ export async function GET() {
let structure = '';
if (treeResult.exitCode === 0) {
const dirs = (await treeResult.stdout()).split('\n').filter(d => d.trim());
const dirs = (await treeResult.stdout()).split('\n').filter((d: string) => d.trim());
structure = dirs.slice(0, 50).join('\n'); // Limit to 50 lines
}
+1 -1
View File
@@ -3,7 +3,7 @@ import { SandboxProvider } from '@/lib/sandbox/types';
import { sandboxManager } from '@/lib/sandbox/sandbox-manager';
declare global {
var activeSandboxProvider: SandboxProvider | null;
var activeSandboxProvider: any;
}
export async function POST(request: NextRequest) {
+2 -2
View File
@@ -41,7 +41,7 @@ export async function GET() {
});
if (findResult.exitCode === 0) {
const logFiles = (await findResult.stdout()).split('\n').filter(f => f.trim());
const logFiles = (await findResult.stdout()).split('\n').filter((f: string) => f.trim());
for (const logFile of logFiles.slice(0, 3)) {
try {
@@ -51,7 +51,7 @@ export async function GET() {
});
if (grepResult.exitCode === 0) {
const errorLines = (await grepResult.stdout()).split('\n').filter(line => line.trim());
const errorLines = (await grepResult.stdout()).split('\n').filter((line: string) => line.trim());
for (const line of errorLines) {
// Extract package name from error line
+1 -1
View File
@@ -4,7 +4,7 @@ import { sandboxManager } from '@/lib/sandbox/sandbox-manager';
// Get active sandbox provider from global state
declare global {
var activeSandboxProvider: SandboxProvider | null;
var activeSandboxProvider: any;
}
export async function POST(request: NextRequest) {
+4 -4
View File
@@ -1,10 +1,10 @@
import { NextRequest, NextResponse } from 'next/server';
import { NextResponse } from 'next/server';
declare global {
var activeSandbox: any;
}
export async function GET(_request: NextRequest) {
export async function GET() {
try {
if (!global.activeSandbox) {
return NextResponse.json({
@@ -26,7 +26,7 @@ export async function GET(_request: NextRequest) {
if (psResult.exitCode === 0) {
const psOutput = await psResult.stdout();
const viteProcesses = psOutput.split('\n').filter(line =>
const viteProcesses = psOutput.split('\n').filter((line: string) =>
line.toLowerCase().includes('vite') ||
line.toLowerCase().includes('npm run dev')
);
@@ -49,7 +49,7 @@ export async function GET(_request: NextRequest) {
});
if (findResult.exitCode === 0) {
const logFiles = (await findResult.stdout()).split('\n').filter(f => f.trim());
const logFiles = (await findResult.stdout()).split('\n').filter((f: string) => f.trim());
for (const logFile of logFiles.slice(0, 2)) {
try {
+8 -17
View File
@@ -51,17 +51,17 @@ export async function POST(req: NextRequest) {
screenshot: scrapeResult.screenshot,
metadata: scrapeResult.metadata || {}
});
} else if (scrapeResult?.data?.screenshot) {
} else if ((scrapeResult as any)?.data?.screenshot) {
// Nested data structure
return NextResponse.json({
success: true,
screenshot: scrapeResult.data.screenshot,
metadata: scrapeResult.data.metadata || {}
screenshot: (scrapeResult as any).data.screenshot,
metadata: (scrapeResult as any).data.metadata || {}
});
} else if (scrapeResult?.success === false) {
} else if ((scrapeResult as any)?.success === false) {
// Explicit failure
console.error('[scrape-screenshot] Firecrawl API error:', scrapeResult.error);
throw new Error(scrapeResult.error || 'Failed to capture screenshot');
console.error('[scrape-screenshot] Firecrawl API error:', (scrapeResult as any).error);
throw new Error((scrapeResult as any).error || 'Failed to capture screenshot');
} else {
// No screenshot in response
console.error('[scrape-screenshot] No screenshot in response. Full response:', JSON.stringify(scrapeResult, null, 2));
@@ -72,19 +72,10 @@ export async function POST(req: NextRequest) {
console.error('[scrape-screenshot] Screenshot capture error:', error);
console.error('[scrape-screenshot] Error stack:', error.stack);
// Provide fallback response for development
if (process.env.NODE_ENV === 'development') {
console.warn('[scrape-screenshot] Returning placeholder screenshot for development');
return NextResponse.json({
success: true,
screenshot: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
metadata: { error: 'Screenshot capture failed, using placeholder' }
});
}
// Provide fallback response for development - removed NODE_ENV check as it doesn't work in Next.js production builds
return NextResponse.json({
error: error.message || 'Failed to capture screenshot',
details: process.env.NODE_ENV === 'development' ? error.stack : undefined
error: error.message || 'Failed to capture screenshot'
}, { status: 500 });
}
}
+16 -12
View File
@@ -49,23 +49,27 @@ export async function POST(request: NextRequest) {
});
// Handle the response according to the latest SDK structure
if (!scrapeResult.success) {
throw new Error(scrapeResult.error || "Failed to scrape website");
const result = scrapeResult as any;
if (result.success === false) {
throw new Error(result.error || "Failed to scrape website");
}
// The SDK may return data directly or nested
const data = result.data || result;
return NextResponse.json({
success: true,
data: {
title: scrapeResult.data?.metadata?.title || "Untitled",
content: scrapeResult.data?.markdown || scrapeResult.data?.html || "",
description: scrapeResult.data?.metadata?.description || "",
markdown: scrapeResult.data?.markdown || "",
html: scrapeResult.data?.html || "",
metadata: scrapeResult.data?.metadata || {},
screenshot: scrapeResult.data?.screenshot || null,
links: scrapeResult.data?.links || [],
title: data?.metadata?.title || "Untitled",
content: data?.markdown || data?.html || "",
description: data?.metadata?.description || "",
markdown: data?.markdown || "",
html: data?.html || "",
metadata: data?.metadata || {},
screenshot: data?.screenshot || null,
links: data?.links || [],
// Include raw data for flexibility
raw: scrapeResult.data
raw: data
}
});
@@ -94,7 +98,7 @@ export async function POST(request: NextRequest) {
}
// Optional: Add OPTIONS handler for CORS if needed
export async function OPTIONS(_request: NextRequest) {
export async function OPTIONS() {
return new NextResponse(null, {
status: 200,
headers: {