windsurf-memory-optimization
Version:
Memory optimization tools for Windsurf AI
254 lines • 12 kB
JavaScript
;
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