UNPKG

cortexweaver

Version:

CortexWeaver is a command-line interface (CLI) tool that orchestrates a swarm of specialized AI agents, powered by Claude Code and Gemini CLI, to assist in software development. It transforms a high-level project plan (plan.md) into a series of coordinate

187 lines 7.55 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 () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.Persistence = void 0; const fs = __importStar(require("fs/promises")); const path = __importStar(require("path")); class Persistence { constructor(driver, snapshotsDir = './snapshots') { this.driver = driver; this.snapshotsDir = snapshotsDir; } async saveSnapshot(filepath) { const snapshotDir = path.dirname(filepath); await fs.mkdir(snapshotDir, { recursive: true }); const nodesSession = this.driver.session(); let nodes = []; try { const nodesResult = await nodesSession.run('MATCH (n) RETURN n'); nodes = nodesResult.records.map(record => { const node = record.get('n'); return { id: node.identity.low ? node.identity.low.toString() : Math.random().toString(36).substring(7), labels: node.labels, properties: node.properties }; }); } finally { await nodesSession.close(); } const relsSession = this.driver.session(); let relationships = []; try { const relsResult = await relsSession.run('MATCH ()-[r]->() RETURN startNode(r) as start, endNode(r) as end, type(r) as type, properties(r) as props'); relationships = relsResult.records.map(record => { const startNode = record.get('start'); const endNode = record.get('end'); return { id: Math.random().toString(36).substring(7), // Generate temp ID startNode: startNode.identity.low ? startNode.identity.low.toString() : Math.random().toString(36).substring(7), endNode: endNode.identity.low ? endNode.identity.low.toString() : Math.random().toString(36).substring(7), type: record.get('type'), properties: record.get('props') }; }); } finally { await relsSession.close(); } const nodeTypes = {}; nodes.forEach(node => { node.labels.forEach((label) => { nodeTypes[label] = (nodeTypes[label] || 0) + 1; }); }); const snapshot = { version: '1.0.0', timestamp: new Date().toISOString(), metadata: { totalNodes: nodes.length, totalRelationships: relationships.length, nodeTypes }, nodes, relationships }; await fs.writeFile(filepath, JSON.stringify(snapshot, null, 2), 'utf8'); } async loadSnapshot(filepath) { const data = await fs.readFile(filepath, 'utf8'); const snapshot = JSON.parse(data); this.validateSnapshotFormat(snapshot); // Clear existing data const clearSession = this.driver.session(); try { await clearSession.run('MATCH (n) DETACH DELETE n'); } finally { await clearSession.close(); } // Batch create nodes const batchSize = 100; for (let i = 0; i < snapshot.nodes.length; i += batchSize) { const batch = snapshot.nodes.slice(i, i + batchSize); const nodeSession = this.driver.session(); try { for (const node of batch) { const labels = node.labels.join(':'); const query = `CREATE (n:${labels}) SET n = $properties`; await nodeSession.run(query, { properties: node.properties }); } } finally { await nodeSession.close(); } } // Create relationships using property matching (simpler and more reliable) for (const rel of snapshot.relationships) { const relSession = this.driver.session(); try { const startNodeProps = snapshot.nodes.find(n => n.id === rel.startNode)?.properties; const endNodeProps = snapshot.nodes.find(n => n.id === rel.endNode)?.properties; if (startNodeProps && endNodeProps) { const query = ` MATCH (start), (end) WHERE start = $startProps AND end = $endProps CREATE (start)-[r:${rel.type}]->(end) SET r = $properties `; await relSession.run(query, { startProps: startNodeProps, endProps: endNodeProps, properties: rel.properties }); } } finally { await relSession.close(); } } } async autoSaveSnapshot() { const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const filename = `auto-save-${timestamp}.json`; const filepath = path.join(this.snapshotsDir, filename); await this.saveSnapshot(filepath); } async listSnapshots() { try { const files = await fs.readdir(this.snapshotsDir); return files.filter(file => file.endsWith('.json')); } catch (error) { if (error.code === 'ENOENT') { return []; } throw error; } } async restoreFromSnapshot(filepath) { await this.loadSnapshot(filepath); // Note: Schema initialization should be called separately by the main class } validateSnapshotFormat(snapshot) { const required = ['version', 'timestamp', 'metadata', 'nodes', 'relationships']; if (!required.every(field => snapshot[field] !== undefined)) { throw new Error('Invalid snapshot format: missing required fields'); } if (!Array.isArray(snapshot.nodes) || !Array.isArray(snapshot.relationships)) { throw new Error('Invalid snapshot format: nodes and relationships must be arrays'); } } } exports.Persistence = Persistence; //# sourceMappingURL=persistence.js.map