const fs = require('fs'); const file = 'vibn-frontend/app/api/mcp/route.ts'; let code = fs.readFileSync(file, 'utf8'); const oldNormalize = `function normalizeFsPath(p: string): string | NextResponse { if (!p || typeof p !== "string") { return NextResponse.json( { error: 'Param "path" is required' }, { status: 400 }, ); } let abs: string; if (p.startsWith("/")) { abs = p; } else { abs = \`\${FS_ROOT}/\${p}\`.replace(/\\/+/g, "/"); } // Disallow .. traversal that escapes /workspace. const norm = abs.replace(/\\/[^/]+\\/\\.\\.(?=\\/|$)/g, "").replace(/\\/+/g, "/"); if (!norm.startsWith(FS_ROOT) && norm !== FS_ROOT) { return NextResponse.json( { error: \`Path "\${p}" is outside \${FS_ROOT}; use shell.exec for system paths.\`, }, { status: 400 }, ); } return norm; }`; const newNormalize = `function normalizeFsPath( p: string, projectSlug?: string, ): string | NextResponse { if (!p || typeof p !== "string") { return NextResponse.json( { error: 'Param "path" is required' }, { status: 400 }, ); } const projectRoot = projectSlug ? \`\${FS_ROOT}/\${projectSlug}\` : FS_ROOT; let abs: string; if (p.startsWith("/")) { abs = p; } else { abs = \`\${projectRoot}/\${p}\`.replace(/\\/+/g, "/"); } const norm = abs.replace(/\\/[^/]+\\/\\.\\.(?=\\/|$)/g, "").replace(/\\/+/g, "/"); // When projectSlug is set, REJECT paths outside the project root. if (projectSlug) { if (!norm.startsWith(projectRoot) && norm !== projectRoot) { return NextResponse.json( { ok: false, error: \`PATH_OUTSIDE_PROJECT: path "\${p}" resolves to "\${norm}" which is outside the active project at "\${projectRoot}". Did you mean "\${projectRoot}/\${p.replace(/^\\/+/, "")}"?\`, }, { status: 400 }, ); } } else { // Workspace-level fallback (legacy behaviour) if (!norm.startsWith(FS_ROOT) && norm !== FS_ROOT) { return NextResponse.json( { error: \`Path "\${p}" is outside \${FS_ROOT}; use shell.exec for system paths.\` }, { status: 400 }, ); } } return norm; }`; code = code.replace(oldNormalize, newNormalize); code = code.replace(/const path = normalizeFsPath\(String\(params\.path \?\? ""\)\);/g, 'const path = normalizeFsPath(String(params.path ?? ""), project.slug);'); code = code.replace(/const path = normalizeFsPath\(String\(params\.path \?\? "\/workspace"\)\);/g, 'const path = normalizeFsPath(String(params.path ?? "/workspace"), project.slug);'); code = code.replace(/const cwd = normalizeFsPath\(String\(params\.cwd \?\? "\/workspace"\)\);/g, 'const cwd = normalizeFsPath(String(params.cwd ?? "/workspace"), project.slug);'); code = code.replace(/const targetPath = normalizeFsPath\(String\(params\.targetPath \?\? ""\)\);/g, 'const targetPath = normalizeFsPath(String(params.targetPath ?? ""), project.slug);'); fs.writeFileSync(file, code); console.log("Patched normalizeFsPath with projectSlug scoping");