@notbnull/mcp-cursor-taskmaster
Version:
A project-scoped MCP server requiring explicit --project-dir configuration for task management, memory retrieval, and agentic workflows
122 lines • 4.97 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VectorStore = void 0;
const vectra_1 = require("vectra");
const path_1 = __importDefault(require("path"));
const promises_1 = __importDefault(require("fs/promises"));
class VectorStore {
index;
embedder;
dataDir;
indexPath;
initialized = false;
constructor(dataDir) {
// Use the provided data directory directly - it's validated upstream
this.dataDir = path_1.default.resolve(dataDir);
this.indexPath = path_1.default.join(this.dataDir, "vectors.index");
}
async initialize() {
try {
// Ensure data directory exists
console.error(`VectorStore: Creating directory ${this.dataDir}`);
await promises_1.default.mkdir(this.dataDir, { recursive: true });
console.error(`VectorStore: Loading transformer model (this may take a moment)...`);
// Initialize the embedding model using dynamic import with timeout
const modelPromise = (async () => {
const { pipeline } = await import("@xenova/transformers");
return await pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2");
})();
// Add timeout for model loading
const timeoutPromise = new Promise((_, reject) => globalThis.setTimeout(() => reject(new Error("Model loading timeout")), 25000));
this.embedder = await Promise.race([modelPromise, timeoutPromise]);
console.error(`VectorStore: Transformer model loaded successfully`);
// Check if index exists
try {
await promises_1.default.access(this.indexPath);
// Load existing index
this.index = new vectra_1.LocalIndex(this.indexPath);
console.error(`VectorStore: Loaded existing index`);
}
catch {
// Create new index
this.index = new vectra_1.LocalIndex(this.indexPath);
await this.index.createIndex();
console.error(`VectorStore: Created new index`);
}
this.initialized = true;
console.error(`VectorStore: Successfully initialized in ${this.dataDir}`);
}
catch (error) {
console.error(`VectorStore: Failed to initialize in ${this.dataDir}:`, error instanceof Error ? error.message : "Unknown error");
throw new Error(`Failed to initialize VectorStore: ${error instanceof Error ? error.message : "Unknown error"}`);
}
}
async add(document) {
if (!this.initialized) {
throw new Error("VectorStore not initialized");
}
// Generate embedding for the content
const embedding = await this.generateEmbedding(document.content);
// Add to index
await this.index.insertItem({
vector: embedding,
metadata: {
id: document.id,
...document.metadata,
},
});
}
async search(query, limit = 5, threshold = 0.7) {
if (!this.initialized) {
throw new Error("VectorStore not initialized");
}
// Generate embedding for the query
const queryEmbedding = await this.generateEmbedding(query);
// Search the index - updated API call
const results = await this.index.queryItems(queryEmbedding, query, limit);
// Filter by threshold and format results
return results
.filter((result) => result.score >= threshold)
.map((result) => ({
id: result.item.metadata.id,
score: result.score,
metadata: result.item.metadata,
}));
}
async delete(id) {
if (!this.initialized) {
throw new Error("VectorStore not initialized");
}
// Find the item by id in metadata
const allItems = await this.index.listItems();
const itemToDelete = allItems.find((item) => item.metadata?.id === id);
if (itemToDelete) {
await this.index.deleteItem(itemToDelete.id);
return true;
}
return false;
}
async update(document) {
// Delete existing and add new
await this.delete(document.id);
await this.add(document);
}
async generateEmbedding(text) {
// Generate embeddings using the model
const output = await this.embedder(text, {
pooling: "mean",
normalize: true,
});
// Convert to array
return Array.from(output.data);
}
async close() {
// Vectra handles cleanup automatically
this.initialized = false;
}
}
exports.VectorStore = VectorStore;
//# sourceMappingURL=vector-store.js.map