UNPKG

windsurf-memory-optimization

Version:

Memory optimization tools for Windsurf AI

254 lines 12 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MemoryManager = void 0; const node_persist_1 = __importDefault(require("node-persist")); const fs = __importStar(require("fs")); const path = __importStar(require("path")); const ts_morph_1 = require("ts-morph"); class MemoryManager { constructor() { this.initialized = false; } extractPins(content, filePath) { const pins = []; try { if (content == null) { console.error(`Empty content in file: ${filePath}`); return []; } if (content === '') { console.log(`Empty content in file: ${filePath}`); return []; } const project = new ts_morph_1.Project(); const sourceFile = project.createSourceFile(filePath, content); const declarations = [ ...sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.VariableStatement), ...sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.FunctionDeclaration), ...sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.ClassDeclaration), ...sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.InterfaceDeclaration) ]; for (const declaration of declarations) { const commentRanges = declaration.getLeadingCommentRanges(); if (commentRanges && commentRanges.length > 0) { const comment = commentRanges[0].getText(); if (comment.includes('@memory')) { const pinContent = comment.replace(/@memory\s*/g, '').trim(); if (pinContent) { const start = declaration.getStart(); const lineAndColumn = sourceFile.getLineAndColumnAtPos(start); const pin = { id: `pin_${Date.now()}_${pins.length}`, content: pinContent, location: { file: filePath, line: lineAndColumn.line + 1, column: lineAndColumn.column }, timestamp: new Date().toISOString(), status: 'active' }; pins.push(pin); } } } } } catch (error) { console.error(`Error extracting pins from file ${filePath}:`, error instanceof Error ? error.message : String(error)); } return pins; } async init() { if (this.initialized) return; try { const baseDir = process.env.WINDSURF_MEMORY_DIR || '.windsurf'; const storageDir = path.join(baseDir, 'memory-storage'); if (!fs.existsSync(baseDir)) { fs.mkdirSync(baseDir, { recursive: true }); } if (!fs.existsSync(storageDir)) { fs.mkdirSync(storageDir, { recursive: true }); } const stats = fs.statSync(storageDir); if (!stats.isDirectory()) { fs.unlinkSync(storageDir); fs.mkdirSync(storageDir, { recursive: true }); } this.storage = await node_persist_1.default.create({ dir: storageDir, logging: true, ttl: true }); await this.storage.init(); this.initialized = true; } catch (error) { console.error('Error initializing storage:', error instanceof Error ? error.message : String(error)); throw error; } } /** * Quét thư mục để tìm các memory pins trong các file * @param directory Đường dẫn thư mục cần quét * @param options Tùy chọn quét (các loại file, độ sâu quét, v.v.) * @returns Danh sách các memory pins tìm thấy */ async scanDirectory(directory, options) { const pins = []; await this.init(); // Các loại file mặc định cần quét const fileTypes = options?.fileTypes || ['.ts', '.js', '.tsx', '.jsx', '.vue']; // Độ sâu quét tối đa (mặc định là không giới hạn) const maxDepth = options?.maxDepth || -1; // Các thư mục bỏ qua const excludeDirs = options?.excludeDirs || ['node_modules', '.git', 'dist', 'build', 'coverage']; // Chế độ hiển thị chi tiết const verbose = options?.verbose || false; // Hàm đệ quy quét thư mục với kiểm soát độ sâu const scanRecursive = async (dirPath, currentDepth) => { const localPins = []; // Kiểm tra độ sâu quét if (maxDepth !== -1 && currentDepth > maxDepth) { return localPins; } try { const absPath = path.isAbsolute(dirPath) ? dirPath : path.join(process.cwd(), dirPath); // Kiểm tra xem thư mục có tồn tại không if (!fs.existsSync(absPath)) { if (verbose) console.log(`Directory does not exist: ${absPath}`); return localPins; } // Kiểm tra xem có phải là thư mục không const stats = await fs.promises.stat(absPath); if (!stats.isDirectory()) { if (verbose) console.log(`Not a directory: ${absPath}`); return localPins; } // Đọc danh sách các mục trong thư mục const items = await fs.promises.readdir(absPath); // Xử lý từng mục for (const fileName of items) { const absFilePath = path.join(absPath, fileName); const baseName = path.basename(fileName); // Bỏ qua các thư mục bị loại trừ if (excludeDirs.includes(baseName)) { if (verbose) console.log(`Skipping excluded directory: ${absFilePath}`); continue; } try { const itemStats = await fs.promises.stat(absFilePath); if (itemStats.isDirectory()) { // Đệ quy quét thư mục con const subPins = await scanRecursive(absFilePath, currentDepth + 1); localPins.push(...subPins); } else if (itemStats.isFile()) { // Kiểm tra xem file có phải là loại cần quét không const ext = path.extname(fileName).toLowerCase(); if (fileTypes.includes(ext)) { try { if (verbose) console.log(`Scanning file: ${absFilePath}`); const content = await fs.promises.readFile(absFilePath, 'utf-8'); // Kiểm tra xem nội dung có trống không if (!content || content.trim() === '') { console.log(`Empty content in file: ${absFilePath}`); continue; } // Trích xuất pins từ nội dung file const pinsInFile = this.extractPins(content, absFilePath); if (pinsInFile.length > 0 && verbose) { console.log(`Found ${pinsInFile.length} pins in ${absFilePath}`); } localPins.push(...pinsInFile); } catch (error) { // Xử lý lỗi đọc file console.error(`Error reading file ${absFilePath}:`, error instanceof Error ? error.message : String(error)); } } else if (verbose) { console.log(`Skipping non-target file type: ${absFilePath}`); } } } catch (error) { // Xử lý lỗi EISDIR (cố gắng đọc thư mục như file) if (error instanceof Error && error.message.includes('EISDIR')) { if (verbose) console.log(`Skipping directory treated as file: ${absFilePath}`); continue; } // Xử lý các lỗi khác console.error(`Error processing item ${absFilePath}:`, error instanceof Error ? error.message : String(error)); } } return localPins; } catch (error) { console.error(`Error scanning directory ${dirPath}:`, error instanceof Error ? error.message : String(error)); return localPins; } }; // Bắt đầu quét từ độ sâu 0 return await scanRecursive(directory, 0); } async createPin(pin) { if (!this.storage) throw new Error('Storage not initialized'); await this.storage.setItem(pin.id, pin); } async getPin(id) { if (!this.storage) throw new Error('Storage not initialized'); return await this.storage.getItem(id); } async listPins() { if (!this.storage) throw new Error('Storage not initialized'); const keys = await this.storage.keys(); const pins = await Promise.all(keys.map(async (key) => { const pin = await this.storage.getItem(key); return pin; })); return pins; } async deletePin(id) { if (!this.storage) throw new Error('Storage not initialized'); await this.storage.removeItem(id); } } exports.MemoryManager = MemoryManager; //# sourceMappingURL=memory-manager.js.map