ruvector 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +49 -6
- package/bin/mcp-server.js +15 -3
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -3551,15 +3551,29 @@ hooksCmd.command('init')
|
|
|
3551
3551
|
}
|
|
3552
3552
|
|
|
3553
3553
|
// MCP server configuration (unless --minimal or --no-mcp)
|
|
3554
|
+
// Note: We only use enabledMcpjsonServers (not mcpServers) to avoid
|
|
3555
|
+
// Claude Code regenerating .mcp.json and stripping user-added fields
|
|
3556
|
+
// like autoStart. See: https://github.com/ruvnet/RuVector/issues/250
|
|
3554
3557
|
if (!opts.minimal && opts.mcp !== false) {
|
|
3555
|
-
|
|
3556
|
-
//
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3558
|
+
// Only reference servers via enabledMcpjsonServers — never write mcpServers: {}
|
|
3559
|
+
// which can trigger Claude Code to regenerate .mcp.json
|
|
3560
|
+
const mcpJsonPath = path.join(process.cwd(), '.mcp.json');
|
|
3561
|
+
let mcpJson = {};
|
|
3562
|
+
if (fs.existsSync(mcpJsonPath)) {
|
|
3563
|
+
try { mcpJson = JSON.parse(fs.readFileSync(mcpJsonPath, 'utf-8')); } catch {}
|
|
3564
|
+
}
|
|
3565
|
+
// Only add to enabledMcpjsonServers if the server is defined in .mcp.json
|
|
3566
|
+
if (mcpJson.mcpServers?.['claude-flow'] || mcpJson.mcpServers?.['ruvector']) {
|
|
3567
|
+
const serverName = mcpJson.mcpServers['ruvector'] ? 'ruvector' : 'claude-flow';
|
|
3568
|
+
if (!settings.enabledMcpjsonServers?.includes(serverName)) {
|
|
3569
|
+
settings.enabledMcpjsonServers = settings.enabledMcpjsonServers || [];
|
|
3570
|
+
settings.enabledMcpjsonServers.push(serverName);
|
|
3561
3571
|
}
|
|
3562
3572
|
}
|
|
3573
|
+
// Remove stale mcpServers: {} that could trigger .mcp.json regeneration
|
|
3574
|
+
if (settings.mcpServers && Object.keys(settings.mcpServers).length === 0) {
|
|
3575
|
+
delete settings.mcpServers;
|
|
3576
|
+
}
|
|
3563
3577
|
console.log(chalk.blue(' ✓ MCP servers configured'));
|
|
3564
3578
|
}
|
|
3565
3579
|
|
|
@@ -5769,6 +5783,16 @@ hooksCmd.command('doctor')
|
|
|
5769
5783
|
};
|
|
5770
5784
|
Object.values(settings.hooks || {}).forEach(checkCommands);
|
|
5771
5785
|
|
|
5786
|
+
// Remove empty mcpServers that can cause .mcp.json overwrites (#250)
|
|
5787
|
+
if (settings.mcpServers && Object.keys(settings.mcpServers).length === 0) {
|
|
5788
|
+
if (opts.fix) {
|
|
5789
|
+
delete settings.mcpServers;
|
|
5790
|
+
fixes.push('Removed empty mcpServers to prevent .mcp.json overwrites');
|
|
5791
|
+
} else {
|
|
5792
|
+
issues.push({ severity: 'warning', message: 'Empty mcpServers in settings.json can cause .mcp.json overwrites', fix: 'Will remove empty mcpServers' });
|
|
5793
|
+
}
|
|
5794
|
+
}
|
|
5795
|
+
|
|
5772
5796
|
// Save fixes
|
|
5773
5797
|
if (opts.fix && fixes.length > 0) {
|
|
5774
5798
|
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
@@ -8171,6 +8195,25 @@ brainCmd.command('transfer <source> <target>')
|
|
|
8171
8195
|
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8172
8196
|
});
|
|
8173
8197
|
|
|
8198
|
+
brainCmd.command('train')
|
|
8199
|
+
.description('Trigger a training cycle (SONA pattern learning + domain evolution)')
|
|
8200
|
+
.option('--url <url>', 'Brain server URL')
|
|
8201
|
+
.option('--key <key>', 'Pi key')
|
|
8202
|
+
.option('--json', 'Output as JSON')
|
|
8203
|
+
.action(async (opts) => {
|
|
8204
|
+
const config = getBrainConfig(opts);
|
|
8205
|
+
try {
|
|
8206
|
+
const result = await brainFetch(config, '/v1/train', { method: 'POST', body: {} });
|
|
8207
|
+
if (opts.json || !process.stdout.isTTY) { console.log(JSON.stringify(result, null, 2)); return; }
|
|
8208
|
+
console.log(chalk.bold.cyan('\nTraining Cycle Complete\n'));
|
|
8209
|
+
console.log(` ${chalk.bold('SONA:')} ${result.sona_message}`);
|
|
8210
|
+
console.log(` ${chalk.bold('Patterns:')} ${result.sona_patterns}`);
|
|
8211
|
+
console.log(` ${chalk.bold('Pareto:')} ${result.pareto_before} → ${result.pareto_after}`);
|
|
8212
|
+
console.log(` ${chalk.bold('Memories:')} ${result.memory_count}`);
|
|
8213
|
+
console.log(` ${chalk.bold('Votes:')} ${result.vote_count}`);
|
|
8214
|
+
} catch (e) { console.error(chalk.red(`Error: ${e.message}`)); process.exit(1); }
|
|
8215
|
+
});
|
|
8216
|
+
|
|
8174
8217
|
brainCmd.command('sync [direction]')
|
|
8175
8218
|
.description('Synchronize LoRA weights (pull, push, or both)')
|
|
8176
8219
|
.option('--url <url>', 'Brain server URL')
|
package/bin/mcp-server.js
CHANGED
|
@@ -428,7 +428,7 @@ class Intelligence {
|
|
|
428
428
|
const server = new Server(
|
|
429
429
|
{
|
|
430
430
|
name: 'ruvector',
|
|
431
|
-
version: '0.2.
|
|
431
|
+
version: '0.2.12',
|
|
432
432
|
},
|
|
433
433
|
{
|
|
434
434
|
capabilities: {
|
|
@@ -1464,6 +1464,11 @@ const TOOLS = [
|
|
|
1464
1464
|
}
|
|
1465
1465
|
}
|
|
1466
1466
|
},
|
|
1467
|
+
{
|
|
1468
|
+
name: 'brain_train',
|
|
1469
|
+
description: 'Trigger a training cycle — runs SONA pattern learning and domain evolution on accumulated data',
|
|
1470
|
+
inputSchema: { type: 'object', properties: {} }
|
|
1471
|
+
},
|
|
1467
1472
|
// ── Brain AGI Tools (6) ── AGI subsystem diagnostics via direct fetch ──
|
|
1468
1473
|
{
|
|
1469
1474
|
name: 'brain_agi_status',
|
|
@@ -3466,7 +3471,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3466
3471
|
case 'brain_drift':
|
|
3467
3472
|
case 'brain_partition':
|
|
3468
3473
|
case 'brain_transfer':
|
|
3469
|
-
case 'brain_sync':
|
|
3474
|
+
case 'brain_sync':
|
|
3475
|
+
case 'brain_train': {
|
|
3470
3476
|
try {
|
|
3471
3477
|
const brainUrl = process.env.BRAIN_URL || 'https://pi.ruv.io';
|
|
3472
3478
|
const brainKey = process.env.PI;
|
|
@@ -3536,6 +3542,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3536
3542
|
url = `${brainUrl}/v1/lora/latest${p.toString() ? '?' + p : ''}`;
|
|
3537
3543
|
break;
|
|
3538
3544
|
}
|
|
3545
|
+
case 'train': {
|
|
3546
|
+
url = `${brainUrl}/v1/train`;
|
|
3547
|
+
fetchOpts.method = 'POST';
|
|
3548
|
+
fetchOpts.body = JSON.stringify({});
|
|
3549
|
+
break;
|
|
3550
|
+
}
|
|
3539
3551
|
}
|
|
3540
3552
|
const resp = await proxyFetch(url, fetchOpts);
|
|
3541
3553
|
if (!resp.ok) {
|
|
@@ -4120,7 +4132,7 @@ async function main() {
|
|
|
4120
4132
|
transport: 'sse',
|
|
4121
4133
|
sessions: sessions.size,
|
|
4122
4134
|
tools: 91,
|
|
4123
|
-
version: '0.2.
|
|
4135
|
+
version: '0.2.12'
|
|
4124
4136
|
}));
|
|
4125
4137
|
|
|
4126
4138
|
} else {
|