export class GitAgentSyncError extends Error { constructor( message: string, public readonly code: string = 'GIT_AGENT_SYNC_ERROR', public readonly details?: Record ) { super(message); this.name = 'GitAgentSyncError'; } } export class WorkspaceExistsError extends GitAgentSyncError { constructor(agentName: string, workspacePath: string) { super( `Workspace for agent '${agentName}' already exists at ${workspacePath}`, 'WORKSPACE_EXISTS', { agentName, workspacePath } ); } } export class WorkspaceNotFoundError extends GitAgentSyncError { constructor(agentName: string) { super( `Workspace for agent '${agentName}' not found`, 'WORKSPACE_NOT_FOUND', { agentName } ); } } export class NotGitRepositoryError extends GitAgentSyncError { constructor(path: string) { super( `Not a git repository: ${path}`, 'NOT_GIT_REPOSITORY', { path } ); } } export class InvalidAgentNameError extends GitAgentSyncError { constructor(name: string, reason?: string) { super( `Invalid agent name '${name}': ${reason || 'must contain only alphanumeric characters and hyphens'}`, 'INVALID_AGENT_NAME', { name } ); } } export class MergeConflictError extends GitAgentSyncError { constructor(conflicts: string[]) { super( `Merge conflicts detected in ${conflicts.length} file(s): ${conflicts.join(', ')}`, 'MERGE_CONFLICT', { conflicts } ); } } export class MergeFailedError extends GitAgentSyncError { constructor(agentName: string, reason: string) { super( `Failed to merge agent '${agentName}': ${reason}`, 'MERGE_FAILED', { agentName, reason } ); } } export class ConfigurationError extends GitAgentSyncError { constructor(message: string, details?: Record) { super(message, 'CONFIGURATION_ERROR', details); } } export class PermissionDeniedError extends GitAgentSyncError { constructor(path: string) { super( `Permission denied for path: ${path}`, 'PERMISSION_DENIED', { path } ); } } export class CommandFailedError extends GitAgentSyncError { constructor(command: string, exitCode: number, stderr: string) { super( `Command '${command}' failed with exit code ${exitCode}: ${stderr}`, 'COMMAND_FAILED', { command, exitCode, stderr } ); } } export function handleError(error: unknown): GitAgentSyncError { if (error instanceof GitAgentSyncError) { return error; } if (error instanceof Error) { return new GitAgentSyncError(error.message, 'UNKNOWN_ERROR'); } if (typeof error === 'string') { return new GitAgentSyncError(error, 'UNKNOWN_ERROR'); } return new GitAgentSyncError('An unknown error occurred', 'UNKNOWN_ERROR'); } export function formatError(error: GitAgentSyncError): string { const lines: string[] = []; lines.push(`\x1b[31mError: ${error.message}\x1b[0m`); lines.push(`Code: ${error.code}`); if (error.details && Object.keys(error.details).length > 0) { lines.push(''); lines.push('Details:'); for (const [key, value] of Object.entries(error.details)) { lines.push(` ${key}: ${JSON.stringify(value)}`); } } return lines.join('\n'); }