load_data
Restore saved lines, loops, vibes, and contexts from persistent storage to resume creative work or merge with existing data.
Instructions
Load lines, loops, vibes, and contexts from persistent storage
Input 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:1157-1263 (handler)The main handler function for the 'load_data' tool. It reads data from a JSON file, optionally merges with existing in-memory data (lines, loops, vibes, contexts), regenerates rhythms, and returns a formatted result. Called from the CallToolRequestSchema switch statement.
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:1123-1155 (helper)Internal helper method loadData() used to load data on server startup. It replaces all in-memory data with file contents and regenerates rhythms. Does not accept merge or return user-facing messages.
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); } } } - index.js:306-323 (schema)Input schema registration for the 'load_data' tool within ListToolsRequestSchema. Defines the 'filename' (optional string) and 'merge' (optional boolean, default false) parameters.
{ 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)Routes the 'load_data' tool name to the loadDataTool handler method in the CallToolRequestSchema switch statement.
case 'load_data': return this.loadDataTool(args); - index.js:36-39 (registration)Calls loadData() on startup when persistence is enabled, to restore previous session data.
// Load data on startup if persistence is enabled if (this.persistenceEnabled) { this.loadData().catch(console.error); }