UNPKG

locker-mcp

Version:

MCP server for file locking and access control for AI code tools

163 lines 5.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Locker = void 0; const crypto_1 = require("crypto"); const metadata_1 = require("./metadata"); const file_manager_1 = require("./file-manager"); class Locker { constructor(projectRoot) { this.metadataManager = new metadata_1.MetadataManager(projectRoot); } getFileState(params) { const { filePath } = params; const entry = this.metadataManager.getEntry(filePath); if (!entry) { return { filePath, state: 'unlocked', context: '', id: '', history: [] }; } return { filePath: entry.filePath, state: entry.state, context: entry.context, id: entry.id, history: [...entry.history] }; } lockFile(params) { const { filePath, context } = params; if (!context.trim()) { throw new Error('Context cannot be empty'); } const existingEntry = this.metadataManager.getEntry(filePath); if (existingEntry) { throw new Error(`File is already tracked: ${filePath}`); } const id = (0, crypto_1.randomUUID)(); const state = 'locked-context'; try { // Add lock comment to file file_manager_1.FileManager.addLockComment(filePath, id, state); // Create metadata entry const entry = this.metadataManager.createEntry(filePath, id, context, state); return { filePath: entry.filePath, state: entry.state, context: entry.context, id: entry.id, history: [...entry.history] }; } catch (error) { // Cleanup on failure try { file_manager_1.FileManager.removeLockComment(filePath); } catch { // Ignore cleanup errors } throw error; } } unlockFile(params) { const { filePath } = params; const existingEntry = this.metadataManager.getEntry(filePath); if (!existingEntry) { throw new Error(`File is not tracked: ${filePath}`); } try { // Remove lock comment from file file_manager_1.FileManager.removeLockComment(filePath); // Remove entry from metadata completely this.metadataManager.removeEntry(filePath); return { filePath: existingEntry.filePath, state: 'unlocked', context: existingEntry.context, id: existingEntry.id, history: [...existingEntry.history, { state: 'unlocked', timestamp: new Date().toISOString() }] }; } catch (error) { throw new Error(`Failed to unlock file: ${error instanceof Error ? error.message : 'Unknown error'}`); } } updateFile(params) { const { filePath, context, state } = params; if (!context.trim()) { throw new Error('Context cannot be empty'); } const existingEntry = this.metadataManager.getEntry(filePath); if (!existingEntry) { throw new Error(`File is not tracked: ${filePath}`); } try { // Update file comment if state changed if (state !== existingEntry.state) { file_manager_1.FileManager.updateLockComment(filePath, existingEntry.id, state); } // Update metadata const updatedEntry = this.metadataManager.updateEntry(filePath, { state, context }); return { filePath: updatedEntry.filePath, state: updatedEntry.state, context: updatedEntry.context, id: updatedEntry.id, history: [...updatedEntry.history] }; } catch (error) { throw new Error(`Failed to update file: ${error instanceof Error ? error.message : 'Unknown error'}`); } } finalizeFile(filePath) { const existingEntry = this.metadataManager.getEntry(filePath); if (!existingEntry) { throw new Error(`File is not tracked: ${filePath}`); } if (existingEntry.state === 'locked') { return { filePath: existingEntry.filePath, state: existingEntry.state, context: existingEntry.context, id: existingEntry.id, history: [...existingEntry.history] }; } try { // Update file comment to locked state file_manager_1.FileManager.updateLockComment(filePath, existingEntry.id, 'locked'); // Update metadata to locked state const updatedEntry = this.metadataManager.updateEntry(filePath, { state: 'locked' }); return { filePath: updatedEntry.filePath, state: updatedEntry.state, context: updatedEntry.context, id: updatedEntry.id, history: [...updatedEntry.history] }; } catch (error) { throw new Error(`Failed to finalize file: ${error instanceof Error ? error.message : 'Unknown error'}`); } } getAllTrackedFiles() { const entries = this.metadataManager.getAllEntries(); return entries.map(entry => ({ filePath: entry.filePath, state: entry.state, context: entry.context, id: entry.id, history: [...entry.history] })); } } exports.Locker = Locker; //# sourceMappingURL=locker.js.map