diff --git a/ai/src/utils/file-tree-formatter.ts b/ai/src/utils/file-tree-formatter.ts new file mode 100644 index 00000000..35eddbfa --- /dev/null +++ b/ai/src/utils/file-tree-formatter.ts @@ -0,0 +1,62 @@ +/** + * Formats a file tree structure into a visual tree representation using box-drawing characters + * + * @param files - Array of file objects with name and optional children properties + * @param depth - Current depth in the tree (default: 0) + * @param maxDepth - Maximum depth to traverse (default: 3) + * @param isLast - Whether this is the last item in its parent's children array + * @param prefix - Accumulated prefix string for indentation and connectors + * @returns Formatted string representation of the file tree + * + * @example + * ```typescript + * const tree = [ + * { name: "src", children: [ + * { name: "index.ts", children: [] }, + * { name: "utils.ts", children: [] } + * ]}, + * { name: "package.json", children: [] } + * ] + * console.log(formatFileTree(tree)) + * // Output: + * // ├─ src/ + * // │ ├─ index.ts + * // │ └─ utils.ts + * // └─ package.json + * ``` + */ +export function formatFileTree( + files: any[], + depth = 0, + maxDepth = 3, + isLast = true, + prefix = "" +): string { + if (!files || depth > maxDepth) return "" + + return files + .map((file: any, index: number) => { + const isLastItem = index === files.length - 1 + const connector = isLastItem ? "└─ " : "├─ " + const childPrefix = prefix + (isLastItem ? " " : "│ ") + + const hasChildren = + file.children && file.children.length > 0 && depth < maxDepth + let result = `${prefix}${connector}${file.name}${hasChildren ? "/" : ""}` + + if (hasChildren) { + result += + "\n" + + formatFileTree( + file.children, + depth + 1, + maxDepth, + isLastItem, + childPrefix + ) + } + + return result + }) + .join("\n") +} diff --git a/ai/src/utils/prompt-builder.ts b/ai/src/utils/prompt-builder.ts index b6e4de69..60443094 100644 --- a/ai/src/utils/prompt-builder.ts +++ b/ai/src/utils/prompt-builder.ts @@ -1,4 +1,5 @@ import { AIRequest } from "../types" +import { formatFileTree } from "./file-tree-formatter" /** * Prompt builder class that generates context-aware system prompts for AI interactions @@ -53,17 +54,11 @@ export class PromptBuilder { if (templateConfig) { prompt += ` - -Project Template: ${templateConfig.name} +File Tree: +${formatFileTree(context.fileTree || [])} Conventions: ${templateConfig.conventions.join("\n")} - -Dependencies: -${JSON.stringify(templateConfig.dependencies, null, 2)} - -Scripts: -${JSON.stringify(templateConfig.scripts, null, 2)} ` } diff --git a/templates/index.ts b/templates/index.ts index 4614f796..e32d6848 100644 --- a/templates/index.ts +++ b/templates/index.ts @@ -2,19 +2,7 @@ export interface TemplateConfig { id: string name: string runCommand: string - fileStructure: { - [key: string]: { - purpose: string - description: string - } - } conventions: string[] - dependencies?: { - [key: string]: string - } - scripts?: { - [key: string]: string - } } export const templateConfigs: { [key: string]: TemplateConfig } = { @@ -22,270 +10,60 @@ export const templateConfigs: { [key: string]: TemplateConfig } = { id: "reactjs", name: "React", runCommand: "npm run dev", - fileStructure: { - "src/": { - purpose: "source", - description: "Contains all React components and application logic", - }, - "src/components/": { - purpose: "components", - description: "Reusable React components", - }, - "src/lib/": { - purpose: "utilities", - description: "Utility functions and shared code", - }, - "src/App.tsx": { - purpose: "entry", - description: "Main application component", - }, - "src/index.tsx": { - purpose: "entry", - description: "Application entry point", - }, - "src/index.css": { - purpose: "styles", - description: "Global CSS styles", - }, - "public/": { - purpose: "static", - description: "Static assets and index.html", - }, - "tsconfig.json": { - purpose: "config", - description: "TypeScript configuration", - }, - "vite.config.ts": { - purpose: "config", - description: "Vite bundler configuration", - }, - "package.json": { - purpose: "config", - description: "Project dependencies and scripts", - }, - }, conventions: [ "Use functional components with hooks", "Follow React naming conventions (PascalCase for components)", "Keep components small and focused", "Use TypeScript for type safety", ], - dependencies: { - "@radix-ui/react-icons": "^1.3.0", - "@radix-ui/react-slot": "^1.1.0", - "class-variance-authority": "^0.7.0", - clsx: "^2.1.1", - "lucide-react": "^0.441.0", - react: "^18.3.1", - "react-dom": "^18.3.1", - "tailwind-merge": "^2.5.2", - "tailwindcss-animate": "^1.0.7", - }, - scripts: { - dev: "vite", - build: "tsc && vite build", - preview: "vite preview", - }, }, // Next.js template config nextjs: { id: "nextjs", name: "NextJS", runCommand: "npm run dev", - fileStructure: { - "pages/": { - purpose: "routing", - description: "Page components and API routes", - }, - "pages/api/": { - purpose: "api", - description: "API route handlers", - }, - "pages/_app.tsx": { - purpose: "entry", - description: "Application wrapper component", - }, - "pages/index.tsx": { - purpose: "page", - description: "Homepage component", - }, - "public/": { - purpose: "static", - description: "Static assets and files", - }, - "styles/": { - purpose: "styles", - description: "CSS modules and global styles", - }, - "styles/globals.css": { - purpose: "styles", - description: "Global CSS styles", - }, - "styles/Home.module.css": { - purpose: "styles", - description: "Homepage-specific styles", - }, - "next.config.js": { - purpose: "config", - description: "Next.js configuration", - }, - "next-env.d.ts": { - purpose: "types", - description: "Next.js TypeScript declarations", - }, - "tsconfig.json": { - purpose: "config", - description: "TypeScript configuration", - }, - "package.json": { - purpose: "config", - description: "Project dependencies and scripts", - }, - }, conventions: [ "Use file-system based routing", "Keep API routes in pages/api", "Use CSS Modules for component styles", "Follow Next.js data fetching patterns", ], - dependencies: { - next: "^14.1.0", - react: "^18.2.0", - "react-dom": "18.2.0", - tailwindcss: "^3.4.1", - }, - scripts: { - dev: "next dev", - build: "next build", - start: "next start", - lint: "next lint", - }, }, // Streamlit template config streamlit: { id: "streamlit", name: "Streamlit", runCommand: "./venv/bin/streamlit run main.py --server.runOnSave true", - fileStructure: { - "main.py": { - purpose: "entry", - description: "Main Streamlit application file", - }, - "requirements.txt": { - purpose: "dependencies", - description: "Python package dependencies", - }, - Procfile: { - purpose: "deployment", - description: "Deployment configuration for hosting platforms", - }, - "venv/": { - purpose: "environment", - description: "Python virtual environment directory", - }, - }, conventions: [ "Use Streamlit components for UI", "Follow PEP 8 style guide", "Keep dependencies in requirements.txt", "Use virtual environment for isolation", ], - dependencies: { - streamlit: "^1.40.0", - altair: "^5.5.0", - }, - scripts: { - start: "streamlit run main.py", - dev: "./venv/bin/streamlit run main.py --server.runOnSave true", - }, }, // HTML template config vanillajs: { id: "vanillajs", name: "HTML/JS", runCommand: "npm run dev", - fileStructure: { - "index.html": { - purpose: "entry", - description: "Main HTML entry point", - }, - "style.css": { - purpose: "styles", - description: "Global CSS styles", - }, - "script.js": { - purpose: "scripts", - description: "JavaScript application logic", - }, - "package.json": { - purpose: "config", - description: "Project dependencies and scripts", - }, - "package-lock.json": { - purpose: "config", - description: "Locked dependency versions", - }, - "vite.config.js": { - purpose: "config", - description: "Vite bundler configuration", - }, - }, conventions: [ "Use semantic HTML elements", "Keep CSS modular and organized", "Write clean, modular JavaScript", "Follow modern ES6+ practices", ], - dependencies: { - vite: "^5.0.12", - }, - scripts: { - dev: "vite", - build: "vite build", - preview: "vite preview", - }, }, // PHP template config php: { id: "php", name: "PHP", runCommand: "npx vite", - fileStructure: { - "index.php": { - purpose: "entry", - description: "Main PHP entry point", - }, - "package.json": { - purpose: "config", - description: "Frontend dependencies and scripts", - }, - "package-lock.json": { - purpose: "config", - description: "Locked dependency versions", - }, - "vite.config.js": { - purpose: "config", - description: "Vite configuration for frontend assets", - }, - "node_modules/": { - purpose: "dependencies", - description: "Frontend dependency files", - }, - }, conventions: [ "Follow PSR-12 coding standards", "Use modern PHP 8+ features", "Organize assets with Vite", "Keep PHP logic separate from presentation", ], - dependencies: { - vite: "^5.0.0", - }, - scripts: { - dev: "vite", - build: "vite build", - preview: "vite preview", - }, }, }