UNPKG

@memory-bank/mcp

Version:

Memory-enabled Co-Pilot (MCP) server for managing project documentation and context

134 lines 6.78 kB
import { BranchInfo } from "../../../domain/entities/BranchInfo.js"; import { DocumentPath } from "../../../domain/entities/DocumentPath.js"; import { DomainError, DomainErrorCodes } from "../../../shared/errors/DomainError.js"; import { ApplicationError, ApplicationErrors } from "../../../shared/errors/ApplicationError.js"; // Import ApplicationError class and ApplicationErrors factory import { logger } from "../../../shared/utils/logger.js"; /** * Context Reading Use Case */ export class ReadContextUseCase { branchRepository; globalRepository; gitService; configProvider; constructor(branchRepository, globalRepository, // --- Add dependencies to constructor --- gitService, configProvider // --- End added dependencies --- ) { this.branchRepository = branchRepository; this.globalRepository = globalRepository; this.gitService = gitService; this.configProvider = configProvider; } async execute(request) { // 内部実装ではbranchがオプショナルですが、外部からは必須です // ここではオプショナルとして扱い、空の場合は自動検出を行います let branchNameToUse = request.branch; // この時点ではlanguageは使用しないが、将来的に使う可能性もある // const { language } = request; // --- Branch Auto-Detection Logic --- if (!branchNameToUse) { const config = this.configProvider.getConfig(); if (config.isProjectMode) { logger.info('[ReadContextUseCase] Branch name omitted in project mode, detecting...'); try { branchNameToUse = await this.gitService.getCurrentBranchName(); logger.info(`[ReadContextUseCase] Detected branch: ${branchNameToUse}`); } catch (gitError) { logger.error('[ReadContextUseCase] Failed to detect branch', { gitError }); throw ApplicationErrors.executionFailed('Branch name is required but could not be automatically determined. Please provide it explicitly or ensure you are in a Git repository.', gitError instanceof Error ? gitError : undefined); } } else { // Not in project mode, branch is required logger.warn('[ReadContextUseCase] Branch name omitted outside project mode.'); throw ApplicationErrors.invalidInput('Branch name is required when not running in project mode.'); } } // --- End Branch Auto-Detection Logic --- // --- Validate final branch name --- if (!branchNameToUse || typeof branchNameToUse !== 'string' || branchNameToUse.trim() === '') { // This case should ideally not be reached if auto-detection or initial validation works, but as a safeguard: throw ApplicationErrors.invalidInput('Invalid branch name determined.'); } // --- End Validation --- const branch = branchNameToUse; // Use the determined name const result = { branchMemory: { coreFiles: { 'branchContext.json': {}, 'activeContext.json': {}, 'progress.json': {}, 'systemPatterns.json': {} }, availableFiles: [] }, globalMemory: { coreFiles: {}, availableFiles: [] } }; try { // Check branch existence const branchExists = await this.branchRepository.exists(branch); if (!branchExists) { try { const branchInfo = BranchInfo.create(branch); await this.branchRepository.initialize(branchInfo); logger.info(`[ReadContextUseCase] Auto-initialized branch: ${branch}`); } catch (initError) { logger.error(`[ReadContextUseCase] Failed to auto-initialize branch: ${branch}`, { initError }); throw new DomainError(DomainErrorCodes.BRANCH_INITIALIZATION_FAILED, `Failed to auto-initialize branch: ${branch}`); } } // Read branch memory const branchInfo = BranchInfo.create(branch); const branchPaths = await this.branchRepository.listDocuments(branchInfo); result.branchMemory.availableFiles = branchPaths.map(p => p.value); // Read core branch files const coreBranchFiles = ['branchContext.json', 'activeContext.json', 'progress.json', 'systemPatterns.json']; for (const file of coreBranchFiles) { const path = DocumentPath.create(file); try { const doc = await this.branchRepository.getDocument(branchInfo, path); if (doc) { result.branchMemory.coreFiles[file] = JSON.parse(doc.content); } } catch (error) { // Log error but continue, as some core files might be optional or missing initially logger.warn(`[ReadContextUseCase] Error reading core branch file ${file}: ${error}`); } } // Read global memory const globalPaths = await this.globalRepository.listDocuments(); result.globalMemory.availableFiles = globalPaths.map(p => p.value); const coreGlobalPaths = globalPaths.filter(p => p.value.startsWith('core/')); for (const path of coreGlobalPaths) { try { const doc = await this.globalRepository.getDocument(path); if (doc) { result.globalMemory.coreFiles[path.value] = JSON.parse(doc.content); } } catch (error) { logger.warn(`[ReadContextUseCase] Error reading core global file ${path.value}: ${error}`); } } return result; } catch (error) { logger.error(`ReadContextUseCase error: ${error}`); // Re-throw application or domain errors directly, wrap others if (error instanceof DomainError || error instanceof ApplicationError) { // Use ApplicationError class here throw error; } throw ApplicationErrors.executionFailed(`Unexpected error in ReadContextUseCase: ${error.message}`, error instanceof Error ? error : undefined); } } } //# sourceMappingURL=ReadContextUseCase.js.map