load_data
Loads lines, loops, vibes, and contexts from persistent storage to restore creative workflows and strategic flows in the LLV Helix Framework.
Instructions
Load lines, loops, vibes, and contexts from persistent storage
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filename | No | Optional custom filename (without extension) | |
| merge | No | Merge with existing data instead of replacing |
Implementation Reference
- index.js:306-323 (registration)Registration of the 'load_data' tool in the tools array passed to server.setTools, including name, description, and inputSchema.{ name: 'load_data', description: 'Load lines, loops, vibes, and contexts from persistent storage', inputSchema: { type: 'object', properties: { filename: { type: 'string', description: 'Optional custom filename (without extension)', }, merge: { type: 'boolean', description: 'Merge with existing data instead of replacing', default: false, }, }, }, },
- index.js:353-354 (registration)Dispatch/registration in the CallToolRequestHandler switch statement that maps 'load_data' to this.loadDataTool(args).case 'load_data': return this.loadDataTool(args);
- index.js:1157-1263 (handler)The primary handler function for the 'load_data' tool. Loads persistent data from JSON file into lines, loops, vibes, and contexts Maps. Supports optional filename and merge mode. Handles persistence check, file reading, data merging or replacement, rhythm regeneration, and error handling with user-friendly responses.async loadDataTool(args) { if (!this.persistenceEnabled) { return { content: [ { type: 'text', text: `❌ Data persistence is disabled. Set LLV_PERSISTENCE=true to enable.`, }, ], }; } try { const filename = args.filename || 'llv-session'; const filepath = join(this.dataDir, `${filename}.json`); const merge = args.merge || false; let originalCounts = {}; if (merge) { originalCounts = { lines: this.lines.size, loops: this.loops.size, vibes: this.vibes.size, contexts: this.contexts.size, }; } const data = JSON.parse(await fs.readFile(filepath, 'utf8')); if (merge) { // Merge data instead of replacing for (const [name, line] of Object.entries(data.lines || {})) { if (!this.lines.has(name)) { this.lines.set(name, line); this.rhythms.set(`line_${name}`, this.generateRhythm(line.rhythm)); } } for (const [name, loop] of Object.entries(data.loops || {})) { if (!this.loops.has(name)) { this.loops.set(name, loop); this.rhythms.set(`loop_${name}`, this.generateRhythm(loop.rhythm)); } } for (const [name, vibe] of Object.entries(data.vibes || {})) { if (!this.vibes.has(name)) { this.vibes.set(name, vibe); this.rhythms.set(`vibe_${name}`, this.generateRhythm(vibe.rhythm)); } } for (const [name, context] of Object.entries(data.contexts || {})) { if (!this.contexts.has(name)) { this.contexts.set(name, context); } } } else { // Replace all data this.lines = this.objToMap(data.lines); this.loops = this.objToMap(data.loops); this.vibes = this.objToMap(data.vibes); this.contexts = this.objToMap(data.contexts); // Regenerate rhythms this.rhythms.clear(); for (const [name, line] of this.lines) { this.rhythms.set(`line_${name}`, this.generateRhythm(line.rhythm)); } for (const [name, loop] of this.loops) { this.rhythms.set(`loop_${name}`, this.generateRhythm(loop.rhythm)); } for (const [name, vibe] of this.vibes) { this.rhythms.set(`vibe_${name}`, this.generateRhythm(vibe.rhythm)); } } let resultText = `📂 Data loaded successfully!\n\nFile: ${filepath}\nLoaded: ${data.timestamp}\n`; if (merge) { const newCounts = { lines: this.lines.size - originalCounts.lines, loops: this.loops.size - originalCounts.loops, vibes: this.vibes.size - originalCounts.vibes, contexts: this.contexts.size - originalCounts.contexts, }; resultText += `\nMerged:\n• +${newCounts.lines} lines\n• +${newCounts.loops} loops\n• +${newCounts.vibes} vibes\n• +${newCounts.contexts} contexts`; } else { resultText += `\nCurrent state:\n• ${this.lines.size} lines\n• ${this.loops.size} loops\n• ${this.vibes.size} vibes\n• ${this.contexts.size} contexts`; } return { content: [ { type: 'text', text: resultText, }, ], }; } catch (error) { return { content: [ { type: 'text', text: `❌ Failed to load data: ${error.message}`, }, ], }; } }
- index.js:311-321 (schema)Input schema definition for the 'load_data' tool, specifying filename (string, optional) and merge (boolean, optional, default false).properties: { filename: { type: 'string', description: 'Optional custom filename (without extension)', }, merge: { type: 'boolean', description: 'Merge with existing data instead of replacing', default: false, }, },
- index.js:1123-1155 (helper)Internal helper method 'loadData' used for loading data at startup (called on line 38). Similar to loadDataTool but lacks tool args/response format and merge option.async loadData(filename = 'llv-session') { if (!this.persistenceEnabled) { return; } try { const filepath = join(this.dataDir, `${filename}.json`); const data = JSON.parse(await fs.readFile(filepath, 'utf8')); this.lines = this.objToMap(data.lines); this.loops = this.objToMap(data.loops); this.vibes = this.objToMap(data.vibes); this.contexts = this.objToMap(data.contexts); // Regenerate rhythms for loaded data this.rhythms.clear(); for (const [name, line] of this.lines) { this.rhythms.set(`line_${name}`, this.generateRhythm(line.rhythm)); } for (const [name, loop] of this.loops) { this.rhythms.set(`loop_${name}`, this.generateRhythm(loop.rhythm)); } for (const [name, vibe] of this.vibes) { this.rhythms.set(`vibe_${name}`, this.generateRhythm(vibe.rhythm)); } console.error(`Loaded data from ${filepath}: ${this.lines.size} lines, ${this.loops.size} loops, ${this.vibes.size} vibes`); } catch (error) { if (error.code !== 'ENOENT') { console.error('Failed to load data:', error); } } }