import { GitProject, IProjectManager, IWorktreeService, MenuMode, RecentProject } from '../types/index.js'; import { Effect } from 'effect'; import { FileSystemError, ConfigError } from '../types/errors.js'; export declare class ProjectManager implements IProjectManager { currentMode: MenuMode; currentProject?: GitProject; projects: GitProject[]; private worktreeServiceCache; private projectsDir?; private projectCache; private discoveryWorkers; private static readonly MAX_RECENT_PROJECTS; private recentProjects; private dataPath; private configDir; constructor(); setMode(mode: MenuMode): void; selectProject(project: GitProject): void; getWorktreeService(projectPath?: string): IWorktreeService; isMultiProjectEnabled(): boolean; getProjectsDir(): string | undefined; getCurrentProjectPath(): string; clearWorktreeServiceCache(projectPath?: string): void; getCachedServices(): Map; private loadRecentProjects; private saveRecentProjects; getRecentProjects(limit?: number): RecentProject[]; addRecentProject(project: GitProject): void; clearRecentProjects(): void; /** * Fast directory discovery - similar to ghq's approach */ private discoverDirectories; /** * Quick check for .git presence (directory or file) without running git commands. * Returns true for both main repositories and worktrees. */ private hasGitDirectory; /** * Check if a directory is a main git repository (not a worktree). * Main repositories have .git as a directory; worktrees have .git as a file. */ private isMainGitRepository; /** * Process directories in parallel using worker pool pattern */ private processDirectoriesInParallel; /** * Process a single directory to check if it's a valid git repo * @param task - The discovery task containing path information * @param _rootDir - The root directory (unused) * @returns A DiscoveryResult object if the directory is a valid git repository, * or null if it's not a valid git repository (will be filtered out) */ private processDirectory; validateGitRepository(projectPath: string): Promise; getCachedProject(projectPath: string): GitProject | undefined; refreshProject(projectPath: string): Promise; /** * Discover Git projects in the specified directory using Effect * * Recursively scans the directory for Git repositories with parallel processing. * Caches results for improved performance. * * @param {string} projectsDir - Root directory to search for Git projects * @returns {Effect.Effect} Effect containing discovered projects or FileSystemError * * @example * ```typescript * import {Effect} from 'effect'; * import {projectManager} from './services/projectManager.js'; * * // Discover projects with error handling * const projects = await Effect.runPromise( * Effect.catchAll( * projectManager.instance.discoverProjectsEffect('/home/user/projects'), * (error) => { * console.error(`Discovery failed: ${error.cause}`); * return Effect.succeed([]); // Return empty array on error * } * ) * ); * * console.log(`Found ${projects.length} git repositories`); * ``` */ discoverProjectsEffect(projectsDir: string): Effect.Effect; /** * Load recent projects from cache using Effect * * Reads and parses the recent projects JSON file. Returns empty array if file doesn't exist. * * @returns {Effect.Effect} Effect containing recent projects or error * * @example * ```typescript * import {Effect} from 'effect'; * import {projectManager} from './services/projectManager.js'; * * // Load recent projects with error handling * const recent = await Effect.runPromise( * Effect.match( * projectManager.instance.loadRecentProjectsEffect(), * { * onFailure: (error) => { * if (error._tag === 'ConfigError') { * console.error(`Parse error: ${error.details}`); * } else { * console.error(`File error: ${error.cause}`); * } * return []; * }, * onSuccess: (projects) => projects * } * ) * ); * ``` */ loadRecentProjectsEffect(): Effect.Effect; /** * Save recent projects to cache using Effect * * Writes the recent projects array to JSON file. * * @param {RecentProject[]} projects - Recent projects to save * @returns {Effect.Effect} Effect that succeeds or fails with FileSystemError * * @example * ```typescript * import {Effect} from 'effect'; * import {projectManager} from './services/projectManager.js'; * * const recentProjects = [ * { path: '/home/user/project1', name: 'project1', lastAccessed: Date.now() } * ]; * * // Save with error recovery * await Effect.runPromise( * Effect.catchAll( * projectManager.instance.saveRecentProjectsEffect(recentProjects), * (error) => { * console.error(`Failed to save: ${error.cause}`); * return Effect.void; // Continue despite error * } * ) * ); * ``` */ saveRecentProjectsEffect(projects: RecentProject[]): Effect.Effect; /** * Refresh projects list (Effect version) * @returns Effect with void or FileSystemError */ refreshProjectsEffect(): Effect.Effect; } export declare const projectManager: { readonly instance: ProjectManager; getRecentProjects(limit?: number): RecentProject[]; addRecentProject(project: GitProject): void; clearRecentProjects(): void; _resetForTesting(): void; };