| |
| |
| |
| |
| |
| |
|
|
| import { createLogger } from '@automaker/utils/logger'; |
| import { getElectronAPI } from './electron'; |
|
|
| const logger = createLogger('ProjectInit'); |
|
|
| export interface ProjectInitResult { |
| success: boolean; |
| isNewProject: boolean; |
| error?: string; |
| createdFiles?: string[]; |
| existingFiles?: string[]; |
| } |
|
|
| |
| |
| |
| |
| const REQUIRED_STRUCTURE: { |
| directories: string[]; |
| files: Record<string, string>; |
| } = { |
| directories: ['.automaker', '.automaker/context', '.automaker/features', '.automaker/images'], |
| files: { |
| '.automaker/categories.json': '[]', |
| }, |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| export async function initializeProject(projectPath: string): Promise<ProjectInitResult> { |
| const api = getElectronAPI(); |
| const createdFiles: string[] = []; |
| const existingFiles: string[] = []; |
|
|
| try { |
| |
| const projectExists = await api.exists(projectPath); |
| if (!projectExists) { |
| return { |
| success: false, |
| isNewProject: false, |
| error: `Project directory does not exist: ${projectPath}. Create it first before initializing.`, |
| }; |
| } |
|
|
| |
| const projectStat = await api.stat(projectPath); |
| if (!projectStat.success) { |
| return { |
| success: false, |
| isNewProject: false, |
| error: projectStat.error || `Failed to stat project directory: ${projectPath}`, |
| }; |
| } |
|
|
| if (projectStat.stats && !projectStat.stats.isDirectory) { |
| return { |
| success: false, |
| isNewProject: false, |
| error: `Project path is not a directory: ${projectPath}`, |
| }; |
| } |
|
|
| |
| const gitDirExists = await api.exists(`${projectPath}/.git`); |
| if (!gitDirExists) { |
| logger.info('Initializing git repository...'); |
| try { |
| |
| const result = await api.worktree?.initGit(projectPath); |
| if (result?.success && result.result?.initialized) { |
| createdFiles.push('.git'); |
| logger.info('Git repository initialized with initial commit'); |
| } else if (result?.success && !result.result?.initialized) { |
| |
| existingFiles.push('.git'); |
| logger.info('Git repository already exists'); |
| } else { |
| logger.warn('Failed to initialize git repository:', result?.error); |
| } |
| } catch (gitError) { |
| logger.warn('Failed to initialize git repository:', gitError); |
| |
| } |
| } else { |
| existingFiles.push('.git'); |
| } |
|
|
| |
| await Promise.all( |
| REQUIRED_STRUCTURE.directories.map((dir) => api.mkdir(`${projectPath}/${dir}`)) |
| ); |
|
|
| |
| await Promise.all( |
| Object.entries(REQUIRED_STRUCTURE.files).map(async ([relativePath, defaultContent]) => { |
| const fullPath = `${projectPath}/${relativePath}`; |
| const exists = await api.exists(fullPath); |
|
|
| if (!exists) { |
| await api.writeFile(fullPath, defaultContent as string); |
| createdFiles.push(relativePath); |
| } else { |
| existingFiles.push(relativePath); |
| } |
| }) |
| ); |
|
|
| |
| const isNewProject = createdFiles.length === 0 && existingFiles.length === 0; |
|
|
| return { |
| success: true, |
| isNewProject, |
| createdFiles, |
| existingFiles, |
| }; |
| } catch (error) { |
| logger.error('Failed to initialize project:', error); |
| return { |
| success: false, |
| isNewProject: false, |
| error: error instanceof Error ? error.message : 'Unknown error occurred', |
| }; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function isProjectInitialized(projectPath: string): Promise<boolean> { |
| const api = getElectronAPI(); |
|
|
| try { |
| |
| for (const dir of REQUIRED_STRUCTURE.directories) { |
| const fullPath = `${projectPath}/${dir}`; |
| const exists = await api.exists(fullPath); |
| if (!exists) { |
| return false; |
| } |
| } |
|
|
| return true; |
| } catch (error) { |
| logger.error('Error checking project initialization:', error); |
| return false; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function getProjectInitStatus(projectPath: string): Promise<{ |
| initialized: boolean; |
| missingFiles: string[]; |
| existingFiles: string[]; |
| }> { |
| const api = getElectronAPI(); |
| const missingFiles: string[] = []; |
| const existingFiles: string[] = []; |
|
|
| try { |
| |
| for (const dir of REQUIRED_STRUCTURE.directories) { |
| const fullPath = `${projectPath}/${dir}`; |
| const exists = await api.exists(fullPath); |
| if (exists) { |
| existingFiles.push(dir); |
| } else { |
| missingFiles.push(dir); |
| } |
| } |
|
|
| return { |
| initialized: missingFiles.length === 0, |
| missingFiles, |
| existingFiles, |
| }; |
| } catch (error) { |
| logger.error('Error getting project status:', error); |
| return { |
| initialized: false, |
| missingFiles: REQUIRED_STRUCTURE.directories, |
| existingFiles: [], |
| }; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function hasAppSpec(projectPath: string): Promise<boolean> { |
| const api = getElectronAPI(); |
| try { |
| const fullPath = `${projectPath}/.automaker/app_spec.txt`; |
| return await api.exists(fullPath); |
| } catch (error) { |
| logger.error('Error checking app_spec.txt:', error); |
| return false; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export async function hasAutomakerDir(projectPath: string): Promise<boolean> { |
| const api = getElectronAPI(); |
| try { |
| const fullPath = `${projectPath}/.automaker`; |
| return await api.exists(fullPath); |
| } catch (error) { |
| logger.error('Error checking .automaker dir:', error); |
| return false; |
| } |
| } |
|
|