Files
CodePilot/src/app/api/files/preview/route.ts
T
7418andClaude Opus 4.6 ff1fb38735 feat: CodePilot - desktop GUI for Claude Code
Full-featured desktop application built with Next.js + Electron:
- Streaming chat with Claude Code via Agent SDK
- Session management with SQLite persistence
- Project file tree and file preview
- MCP server and custom skills management
- Permission controls with Code/Plan/Ask modes
- Dark/light theme, token tracking
- macOS DMG packaging with electron-builder

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:04:05 +08:00

40 lines
1.3 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { readFilePreview, isPathSafe } from '@/lib/files';
import type { FilePreviewResponse, ErrorResponse } from '@/types';
export async function GET(request: NextRequest) {
const { searchParams } = request.nextUrl;
const filePath = searchParams.get('path');
const maxLines = parseInt(searchParams.get('maxLines') || '200', 10);
if (!filePath) {
return NextResponse.json<ErrorResponse>(
{ error: 'Missing path parameter' },
{ status: 400 }
);
}
const path = require('path');
const resolvedPath = path.resolve(filePath);
// Basic safety: the file must exist under some reasonable base
// We check it resolves to an absolute path and is not a traversal attempt
const dir = path.dirname(resolvedPath);
if (!isPathSafe(dir, resolvedPath)) {
return NextResponse.json<ErrorResponse>(
{ error: 'Invalid file path' },
{ status: 403 }
);
}
try {
const preview = readFilePreview(resolvedPath, Math.min(maxLines, 1000));
return NextResponse.json<FilePreviewResponse>({ preview });
} catch (error) {
return NextResponse.json<ErrorResponse>(
{ error: error instanceof Error ? error.message : 'Failed to read file' },
{ status: 500 }
);
}
}