import { existsSync, statSync } from "fs"; import { resolve } from "path"; import { homedir } from "os"; import { StoreProvider } from "./state/store.tsx"; import { Layout } from "./components/Layout.tsx"; import { useUnifiedRepos } from "./hooks/useUnifiedRepos.ts"; import { useKeyBindings } from "./hooks/useKeyBindings.ts"; import { useBackgroundFetch } from "./hooks/useBackgroundFetch.ts"; import { saveConfig, findConfigPath } from "./config/loader.ts"; import type { GitforestConfig, UnifiedRepo } from "./types/index.ts"; interface AppContentProps { config: GitforestConfig; } function AppContent({ config }: AppContentProps) { const { loadUnifiedRepos, batchClone } = useUnifiedRepos(config); // Clone handler for Layout const handleClone = async (repos: UnifiedRepo[], targetDir: string, useSSH: boolean) => { await batchClone(repos, targetDir, useSSH); }; // Add directory handler for Layout const handleAddDirectory = async ( rawPath: string, maxDepth: number, label: string, ): Promise<{ success: boolean; error?: string }> => { const expanded = rawPath.replace(/^~/, homedir()); const absPath = resolve(expanded); if (!existsSync(absPath)) { return { success: false, error: `Directory does not exist: ${absPath}` }; } if (!statSync(absPath).isDirectory()) { return { success: false, error: `Not a directory: ${absPath}` }; } // Check for duplicates const exists = config.directories.some((d) => { const dPath = d.path.replace(/^~/, homedir()); return resolve(dPath) === absPath; }); if (exists) { return { success: false, error: "Directory already configured" }; } // Add to the config object (mutation - stays in memory for this session) const newDir: { path: string; maxDepth: number; label?: string } = { path: absPath, maxDepth, }; if (label) newDir.label = label; config.directories.push(newDir); // Persist to disk try { const configPath = findConfigPath() ?? undefined; await saveConfig(config, configPath); return { success: true }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error) }; } }; // Set up keyboard bindings useKeyBindings({ config, onRefresh: loadUnifiedRepos, }); // Set up background fetch useBackgroundFetch(config); return ( ); } interface AppProps { config: GitforestConfig; } export function App({ config }: AppProps) { return ( ); }