ruvector 0.1.50 ā 0.1.52
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 +401 -26
- package/bin/mcp-server.js +768 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -1
- package/dist/core/intelligence-engine.d.ts +206 -0
- package/dist/core/intelligence-engine.d.ts.map +1 -0
- package/dist/core/intelligence-engine.js +822 -0
- package/package.json +2 -1
- package/ruvector.db +0 -0
package/bin/cli.js
CHANGED
|
@@ -2093,14 +2093,98 @@ program
|
|
|
2093
2093
|
|
|
2094
2094
|
// ============================================
|
|
2095
2095
|
// Self-Learning Intelligence Hooks
|
|
2096
|
+
// Full RuVector Stack: VectorDB + SONA + Attention
|
|
2096
2097
|
// ============================================
|
|
2097
2098
|
|
|
2099
|
+
// Try to load the full IntelligenceEngine, fallback to simple implementation
|
|
2100
|
+
let IntelligenceEngine = null;
|
|
2101
|
+
let engineAvailable = false;
|
|
2102
|
+
|
|
2103
|
+
try {
|
|
2104
|
+
const core = require('../dist/core/intelligence-engine.js');
|
|
2105
|
+
IntelligenceEngine = core.IntelligenceEngine || core.default;
|
|
2106
|
+
engineAvailable = true;
|
|
2107
|
+
} catch (e) {
|
|
2108
|
+
// IntelligenceEngine not available, use fallback
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2098
2111
|
class Intelligence {
|
|
2099
2112
|
constructor() {
|
|
2100
2113
|
this.intelPath = this.getIntelPath();
|
|
2101
2114
|
this.data = this.load();
|
|
2102
2115
|
this.alpha = 0.1;
|
|
2103
2116
|
this.lastEditedFile = null;
|
|
2117
|
+
this.sessionStartTime = null;
|
|
2118
|
+
|
|
2119
|
+
// Initialize full RuVector engine if available
|
|
2120
|
+
this.engine = null;
|
|
2121
|
+
if (engineAvailable && IntelligenceEngine) {
|
|
2122
|
+
try {
|
|
2123
|
+
this.engine = new IntelligenceEngine({
|
|
2124
|
+
embeddingDim: 256,
|
|
2125
|
+
maxMemories: 100000,
|
|
2126
|
+
maxEpisodes: 50000,
|
|
2127
|
+
enableSona: true,
|
|
2128
|
+
enableAttention: true,
|
|
2129
|
+
learningRate: this.alpha,
|
|
2130
|
+
});
|
|
2131
|
+
// Import existing data into engine
|
|
2132
|
+
if (this.data) {
|
|
2133
|
+
this.engine.import(this.convertLegacyData(this.data), true);
|
|
2134
|
+
}
|
|
2135
|
+
} catch (e) {
|
|
2136
|
+
// Engine initialization failed, use fallback
|
|
2137
|
+
this.engine = null;
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
// Convert legacy data format to new engine format
|
|
2143
|
+
convertLegacyData(data) {
|
|
2144
|
+
const converted = {
|
|
2145
|
+
memories: [],
|
|
2146
|
+
routingPatterns: {},
|
|
2147
|
+
errorPatterns: data.errors || {},
|
|
2148
|
+
coEditPatterns: {},
|
|
2149
|
+
agentMappings: {},
|
|
2150
|
+
};
|
|
2151
|
+
|
|
2152
|
+
// Convert memories
|
|
2153
|
+
if (data.memories) {
|
|
2154
|
+
converted.memories = data.memories.map(m => ({
|
|
2155
|
+
id: m.id,
|
|
2156
|
+
content: m.content,
|
|
2157
|
+
type: m.memory_type || 'general',
|
|
2158
|
+
embedding: m.embedding || this.embed(m.content),
|
|
2159
|
+
created: m.timestamp ? new Date(m.timestamp * 1000).toISOString() : new Date().toISOString(),
|
|
2160
|
+
accessed: 0,
|
|
2161
|
+
}));
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
// Convert Q-learning patterns to routing patterns
|
|
2165
|
+
if (data.patterns) {
|
|
2166
|
+
for (const [key, value] of Object.entries(data.patterns)) {
|
|
2167
|
+
const [state, action] = key.split('|');
|
|
2168
|
+
if (state && action) {
|
|
2169
|
+
if (!converted.routingPatterns[state]) {
|
|
2170
|
+
converted.routingPatterns[state] = {};
|
|
2171
|
+
}
|
|
2172
|
+
converted.routingPatterns[state][action] = value.q_value || 0.5;
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
// Convert file sequences to co-edit patterns
|
|
2178
|
+
if (data.file_sequences) {
|
|
2179
|
+
for (const seq of data.file_sequences) {
|
|
2180
|
+
if (!converted.coEditPatterns[seq.from_file]) {
|
|
2181
|
+
converted.coEditPatterns[seq.from_file] = {};
|
|
2182
|
+
}
|
|
2183
|
+
converted.coEditPatterns[seq.from_file][seq.to_file] = seq.count;
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
return converted;
|
|
2104
2188
|
}
|
|
2105
2189
|
|
|
2106
2190
|
// Prefer project-local storage, fall back to home directory
|
|
@@ -2108,19 +2192,9 @@ class Intelligence {
|
|
|
2108
2192
|
const projectPath = path.join(process.cwd(), '.ruvector', 'intelligence.json');
|
|
2109
2193
|
const homePath = path.join(require('os').homedir(), '.ruvector', 'intelligence.json');
|
|
2110
2194
|
|
|
2111
|
-
|
|
2112
|
-
if (fs.existsSync(path.
|
|
2113
|
-
|
|
2114
|
-
}
|
|
2115
|
-
// If project .claude exists (hooks initialized), prefer project-local
|
|
2116
|
-
if (fs.existsSync(path.join(process.cwd(), '.claude'))) {
|
|
2117
|
-
return projectPath;
|
|
2118
|
-
}
|
|
2119
|
-
// If home .ruvector exists with data, use it
|
|
2120
|
-
if (fs.existsSync(homePath)) {
|
|
2121
|
-
return homePath;
|
|
2122
|
-
}
|
|
2123
|
-
// Default to project-local for new setups
|
|
2195
|
+
if (fs.existsSync(path.dirname(projectPath))) return projectPath;
|
|
2196
|
+
if (fs.existsSync(path.join(process.cwd(), '.claude'))) return projectPath;
|
|
2197
|
+
if (fs.existsSync(homePath)) return homePath;
|
|
2124
2198
|
return projectPath;
|
|
2125
2199
|
}
|
|
2126
2200
|
|
|
@@ -2145,12 +2219,41 @@ class Intelligence {
|
|
|
2145
2219
|
save() {
|
|
2146
2220
|
const dir = path.dirname(this.intelPath);
|
|
2147
2221
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
2222
|
+
|
|
2223
|
+
// If engine is available, export its data
|
|
2224
|
+
if (this.engine) {
|
|
2225
|
+
try {
|
|
2226
|
+
const engineData = this.engine.export();
|
|
2227
|
+
// Merge engine data with legacy format for compatibility
|
|
2228
|
+
this.data.patterns = {};
|
|
2229
|
+
for (const [state, actions] of Object.entries(engineData.routingPatterns || {})) {
|
|
2230
|
+
for (const [action, value] of Object.entries(actions)) {
|
|
2231
|
+
this.data.patterns[`${state}|${action}`] = { state, action, q_value: value, visits: 1, last_update: this.now() };
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
this.data.stats.total_patterns = Object.keys(this.data.patterns).length;
|
|
2235
|
+
this.data.stats.total_memories = engineData.stats?.totalMemories || this.data.memories.length;
|
|
2236
|
+
|
|
2237
|
+
// Add engine stats
|
|
2238
|
+
this.data.engineStats = engineData.stats;
|
|
2239
|
+
} catch (e) {
|
|
2240
|
+
// Ignore engine export errors
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2148
2244
|
fs.writeFileSync(this.intelPath, JSON.stringify(this.data, null, 2));
|
|
2149
2245
|
}
|
|
2150
2246
|
|
|
2151
2247
|
now() { return Math.floor(Date.now() / 1000); }
|
|
2152
2248
|
|
|
2249
|
+
// Use engine embedding if available (256-dim with attention), otherwise fallback (64-dim hash)
|
|
2153
2250
|
embed(text) {
|
|
2251
|
+
if (this.engine) {
|
|
2252
|
+
try {
|
|
2253
|
+
return this.engine.embed(text);
|
|
2254
|
+
} catch {}
|
|
2255
|
+
}
|
|
2256
|
+
// Fallback: simple 64-dim hash embedding
|
|
2154
2257
|
const embedding = new Array(64).fill(0);
|
|
2155
2258
|
for (let i = 0; i < text.length; i++) {
|
|
2156
2259
|
const idx = (text.charCodeAt(i) + i * 7) % 64;
|
|
@@ -2162,21 +2265,68 @@ class Intelligence {
|
|
|
2162
2265
|
}
|
|
2163
2266
|
|
|
2164
2267
|
similarity(a, b) {
|
|
2165
|
-
if (a.length !== b.length) return 0;
|
|
2268
|
+
if (!a || !b || a.length !== b.length) return 0;
|
|
2166
2269
|
const dot = a.reduce((sum, v, i) => sum + v * b[i], 0);
|
|
2167
2270
|
const normA = Math.sqrt(a.reduce((sum, v) => sum + v * v, 0));
|
|
2168
2271
|
const normB = Math.sqrt(b.reduce((sum, v) => sum + v * v, 0));
|
|
2169
2272
|
return normA > 0 && normB > 0 ? dot / (normA * normB) : 0;
|
|
2170
2273
|
}
|
|
2171
2274
|
|
|
2275
|
+
// Memory operations - use engine's VectorDB for semantic search
|
|
2276
|
+
async rememberAsync(memoryType, content, metadata = {}) {
|
|
2277
|
+
if (this.engine) {
|
|
2278
|
+
try {
|
|
2279
|
+
const entry = await this.engine.remember(content, memoryType);
|
|
2280
|
+
// Also store in legacy format for compatibility
|
|
2281
|
+
this.data.memories.push({
|
|
2282
|
+
id: entry.id,
|
|
2283
|
+
memory_type: memoryType,
|
|
2284
|
+
content,
|
|
2285
|
+
embedding: entry.embedding,
|
|
2286
|
+
metadata,
|
|
2287
|
+
timestamp: this.now()
|
|
2288
|
+
});
|
|
2289
|
+
if (this.data.memories.length > 5000) this.data.memories.splice(0, 1000);
|
|
2290
|
+
this.data.stats.total_memories = this.data.memories.length;
|
|
2291
|
+
return entry.id;
|
|
2292
|
+
} catch {}
|
|
2293
|
+
}
|
|
2294
|
+
return this.remember(memoryType, content, metadata);
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2172
2297
|
remember(memoryType, content, metadata = {}) {
|
|
2173
2298
|
const id = `mem_${this.now()}`;
|
|
2174
|
-
|
|
2299
|
+
const embedding = this.embed(content);
|
|
2300
|
+
this.data.memories.push({ id, memory_type: memoryType, content, embedding, metadata, timestamp: this.now() });
|
|
2175
2301
|
if (this.data.memories.length > 5000) this.data.memories.splice(0, 1000);
|
|
2176
2302
|
this.data.stats.total_memories = this.data.memories.length;
|
|
2303
|
+
|
|
2304
|
+
// Also store in engine if available
|
|
2305
|
+
if (this.engine) {
|
|
2306
|
+
this.engine.remember(content, memoryType).catch(() => {});
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2177
2309
|
return id;
|
|
2178
2310
|
}
|
|
2179
2311
|
|
|
2312
|
+
async recallAsync(query, topK = 5) {
|
|
2313
|
+
if (this.engine) {
|
|
2314
|
+
try {
|
|
2315
|
+
const results = await this.engine.recall(query, topK);
|
|
2316
|
+
return results.map(r => ({
|
|
2317
|
+
score: r.score || 0,
|
|
2318
|
+
memory: {
|
|
2319
|
+
id: r.id,
|
|
2320
|
+
content: r.content,
|
|
2321
|
+
memory_type: r.type,
|
|
2322
|
+
timestamp: r.created
|
|
2323
|
+
}
|
|
2324
|
+
}));
|
|
2325
|
+
} catch {}
|
|
2326
|
+
}
|
|
2327
|
+
return this.recall(query, topK);
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2180
2330
|
recall(query, topK) {
|
|
2181
2331
|
const queryEmbed = this.embed(query);
|
|
2182
2332
|
return this.data.memories
|
|
@@ -2184,6 +2334,7 @@ class Intelligence {
|
|
|
2184
2334
|
.sort((a, b) => b.score - a.score).slice(0, topK).map(r => r.memory);
|
|
2185
2335
|
}
|
|
2186
2336
|
|
|
2337
|
+
// Q-learning operations - enhanced with SONA trajectory tracking
|
|
2187
2338
|
getQ(state, action) {
|
|
2188
2339
|
const key = `${state}|${action}`;
|
|
2189
2340
|
return this.data.patterns[key]?.q_value ?? 0;
|
|
@@ -2191,12 +2342,19 @@ class Intelligence {
|
|
|
2191
2342
|
|
|
2192
2343
|
updateQ(state, action, reward) {
|
|
2193
2344
|
const key = `${state}|${action}`;
|
|
2194
|
-
if (!this.data.patterns[key])
|
|
2345
|
+
if (!this.data.patterns[key]) {
|
|
2346
|
+
this.data.patterns[key] = { state, action, q_value: 0, visits: 0, last_update: 0 };
|
|
2347
|
+
}
|
|
2195
2348
|
const p = this.data.patterns[key];
|
|
2196
2349
|
p.q_value = p.q_value + this.alpha * (reward - p.q_value);
|
|
2197
2350
|
p.visits++;
|
|
2198
2351
|
p.last_update = this.now();
|
|
2199
2352
|
this.data.stats.total_patterns = Object.keys(this.data.patterns).length;
|
|
2353
|
+
|
|
2354
|
+
// Record episode in engine if available
|
|
2355
|
+
if (this.engine) {
|
|
2356
|
+
this.engine.recordEpisode(state, action, reward, state, false).catch(() => {});
|
|
2357
|
+
}
|
|
2200
2358
|
}
|
|
2201
2359
|
|
|
2202
2360
|
learn(state, action, outcome, reward) {
|
|
@@ -2205,6 +2363,12 @@ class Intelligence {
|
|
|
2205
2363
|
this.data.trajectories.push({ id, state, action, outcome, reward, timestamp: this.now() });
|
|
2206
2364
|
if (this.data.trajectories.length > 1000) this.data.trajectories.splice(0, 200);
|
|
2207
2365
|
this.data.stats.total_trajectories = this.data.trajectories.length;
|
|
2366
|
+
|
|
2367
|
+
// End trajectory in engine if available
|
|
2368
|
+
if (this.engine) {
|
|
2369
|
+
this.engine.endTrajectory(reward > 0.5, reward);
|
|
2370
|
+
}
|
|
2371
|
+
|
|
2208
2372
|
return id;
|
|
2209
2373
|
}
|
|
2210
2374
|
|
|
@@ -2218,20 +2382,53 @@ class Intelligence {
|
|
|
2218
2382
|
return { action: bestAction, confidence: bestQ > 0 ? Math.min(bestQ, 1) : 0 };
|
|
2219
2383
|
}
|
|
2220
2384
|
|
|
2385
|
+
// Agent routing - use engine's SONA-enhanced routing
|
|
2386
|
+
async routeAsync(task, file, crateName, operation = 'edit') {
|
|
2387
|
+
if (this.engine) {
|
|
2388
|
+
try {
|
|
2389
|
+
const result = await this.engine.route(task, file);
|
|
2390
|
+
// Begin trajectory for learning
|
|
2391
|
+
this.engine.beginTrajectory(task, file);
|
|
2392
|
+
if (result.agent) {
|
|
2393
|
+
this.engine.setTrajectoryRoute(result.agent);
|
|
2394
|
+
}
|
|
2395
|
+
return {
|
|
2396
|
+
agent: result.agent,
|
|
2397
|
+
confidence: result.confidence,
|
|
2398
|
+
reason: result.reason + (result.patterns?.length ? ` (${result.patterns.length} SONA patterns)` : ''),
|
|
2399
|
+
alternates: result.alternates,
|
|
2400
|
+
patterns: result.patterns
|
|
2401
|
+
};
|
|
2402
|
+
} catch {}
|
|
2403
|
+
}
|
|
2404
|
+
return this.route(task, file, crateName, operation);
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2221
2407
|
route(task, file, crateName, operation = 'edit') {
|
|
2222
2408
|
const fileType = file ? path.extname(file).slice(1) : 'unknown';
|
|
2223
2409
|
const state = `${operation}_${fileType}_in_${crateName ?? 'project'}`;
|
|
2224
2410
|
const agentMap = {
|
|
2225
2411
|
rs: ['rust-developer', 'coder', 'reviewer', 'tester'],
|
|
2226
2412
|
ts: ['typescript-developer', 'coder', 'frontend-dev'],
|
|
2227
|
-
tsx: ['
|
|
2228
|
-
js: ['coder', 'frontend-dev'],
|
|
2413
|
+
tsx: ['react-developer', 'typescript-developer', 'coder'],
|
|
2414
|
+
js: ['javascript-developer', 'coder', 'frontend-dev'],
|
|
2415
|
+
jsx: ['react-developer', 'coder'],
|
|
2229
2416
|
py: ['python-developer', 'coder', 'ml-developer'],
|
|
2230
|
-
|
|
2417
|
+
go: ['go-developer', 'coder'],
|
|
2418
|
+
sql: ['database-specialist', 'coder'],
|
|
2419
|
+
md: ['documentation-specialist', 'coder'],
|
|
2420
|
+
yml: ['devops-engineer', 'coder'],
|
|
2421
|
+
yaml: ['devops-engineer', 'coder']
|
|
2231
2422
|
};
|
|
2232
2423
|
const agents = agentMap[fileType] ?? ['coder', 'reviewer'];
|
|
2233
2424
|
const { action, confidence } = this.suggest(state, agents);
|
|
2234
2425
|
const reason = confidence > 0.5 ? 'learned from past success' : confidence > 0 ? 'based on patterns' : `default for ${fileType} files`;
|
|
2426
|
+
|
|
2427
|
+
// Begin trajectory in engine
|
|
2428
|
+
if (this.engine) {
|
|
2429
|
+
this.engine.beginTrajectory(task || operation, file);
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2235
2432
|
return { agent: action, confidence, reason };
|
|
2236
2433
|
}
|
|
2237
2434
|
|
|
@@ -2244,27 +2441,77 @@ class Intelligence {
|
|
|
2244
2441
|
}
|
|
2245
2442
|
case 'ts': case 'tsx': case 'js': case 'jsx': return { suggest: true, command: 'npm test' };
|
|
2246
2443
|
case 'py': return { suggest: true, command: 'pytest' };
|
|
2444
|
+
case 'go': return { suggest: true, command: 'go test ./...' };
|
|
2247
2445
|
default: return { suggest: false, command: '' };
|
|
2248
2446
|
}
|
|
2249
2447
|
}
|
|
2250
2448
|
|
|
2449
|
+
// Co-edit pattern tracking - use engine's co-edit patterns
|
|
2251
2450
|
recordFileSequence(fromFile, toFile) {
|
|
2252
2451
|
const existing = this.data.file_sequences.find(s => s.from_file === fromFile && s.to_file === toFile);
|
|
2253
2452
|
if (existing) existing.count++;
|
|
2254
2453
|
else this.data.file_sequences.push({ from_file: fromFile, to_file: toFile, count: 1 });
|
|
2255
2454
|
this.lastEditedFile = toFile;
|
|
2455
|
+
|
|
2456
|
+
// Record in engine
|
|
2457
|
+
if (this.engine) {
|
|
2458
|
+
this.engine.recordCoEdit(fromFile, toFile);
|
|
2459
|
+
}
|
|
2256
2460
|
}
|
|
2257
2461
|
|
|
2258
2462
|
suggestNext(file, limit = 3) {
|
|
2259
|
-
|
|
2463
|
+
// Try engine first
|
|
2464
|
+
if (this.engine) {
|
|
2465
|
+
try {
|
|
2466
|
+
const results = this.engine.getLikelyNextFiles(file, limit);
|
|
2467
|
+
if (results.length > 0) {
|
|
2468
|
+
return results.map(r => ({ file: r.file, score: r.count }));
|
|
2469
|
+
}
|
|
2470
|
+
} catch {}
|
|
2471
|
+
}
|
|
2472
|
+
return this.data.file_sequences
|
|
2473
|
+
.filter(s => s.from_file === file)
|
|
2474
|
+
.sort((a, b) => b.count - a.count)
|
|
2475
|
+
.slice(0, limit)
|
|
2476
|
+
.map(s => ({ file: s.to_file, score: s.count }));
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
// Error pattern learning
|
|
2480
|
+
recordErrorFix(errorPattern, fix) {
|
|
2481
|
+
if (!this.data.errors[errorPattern]) {
|
|
2482
|
+
this.data.errors[errorPattern] = [];
|
|
2483
|
+
}
|
|
2484
|
+
if (!this.data.errors[errorPattern].includes(fix)) {
|
|
2485
|
+
this.data.errors[errorPattern].push(fix);
|
|
2486
|
+
}
|
|
2487
|
+
this.data.stats.total_errors = Object.keys(this.data.errors).length;
|
|
2488
|
+
|
|
2489
|
+
if (this.engine) {
|
|
2490
|
+
this.engine.recordErrorFix(errorPattern, fix);
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2494
|
+
getSuggestedFixes(error) {
|
|
2495
|
+
// Try engine first (uses embedding similarity)
|
|
2496
|
+
if (this.engine) {
|
|
2497
|
+
try {
|
|
2498
|
+
const fixes = this.engine.getSuggestedFixes(error);
|
|
2499
|
+
if (fixes.length > 0) return fixes;
|
|
2500
|
+
} catch {}
|
|
2501
|
+
}
|
|
2502
|
+
return this.data.errors[error] || [];
|
|
2260
2503
|
}
|
|
2261
2504
|
|
|
2262
2505
|
classifyCommand(command) {
|
|
2263
2506
|
const cmd = command.toLowerCase();
|
|
2264
2507
|
if (cmd.includes('cargo') || cmd.includes('rustc')) return { category: 'rust', subcategory: cmd.includes('test') ? 'test' : 'build', risk: 'low' };
|
|
2265
|
-
if (cmd.includes('npm') || cmd.includes('node')) return { category: 'javascript', subcategory: cmd.includes('test') ? 'test' : 'build', risk: 'low' };
|
|
2266
|
-
if (cmd.includes('
|
|
2267
|
-
if (cmd.includes('
|
|
2508
|
+
if (cmd.includes('npm') || cmd.includes('node') || cmd.includes('yarn') || cmd.includes('pnpm')) return { category: 'javascript', subcategory: cmd.includes('test') ? 'test' : 'build', risk: 'low' };
|
|
2509
|
+
if (cmd.includes('python') || cmd.includes('pip') || cmd.includes('pytest')) return { category: 'python', subcategory: cmd.includes('test') ? 'test' : 'run', risk: 'low' };
|
|
2510
|
+
if (cmd.includes('go ')) return { category: 'go', subcategory: cmd.includes('test') ? 'test' : 'build', risk: 'low' };
|
|
2511
|
+
if (cmd.includes('git')) return { category: 'git', subcategory: 'vcs', risk: cmd.includes('push') || cmd.includes('force') ? 'medium' : 'low' };
|
|
2512
|
+
if (cmd.includes('rm ') || cmd.includes('delete') || cmd.includes('rmdir')) return { category: 'filesystem', subcategory: 'destructive', risk: 'high' };
|
|
2513
|
+
if (cmd.includes('sudo') || cmd.includes('chmod') || cmd.includes('chown')) return { category: 'system', subcategory: 'privileged', risk: 'high' };
|
|
2514
|
+
if (cmd.includes('docker') || cmd.includes('kubectl')) return { category: 'container', subcategory: 'orchestration', risk: 'medium' };
|
|
2268
2515
|
return { category: 'shell', subcategory: 'general', risk: 'low' };
|
|
2269
2516
|
}
|
|
2270
2517
|
|
|
@@ -2274,14 +2521,87 @@ class Intelligence {
|
|
|
2274
2521
|
return { agents, edges };
|
|
2275
2522
|
}
|
|
2276
2523
|
|
|
2277
|
-
stats
|
|
2278
|
-
|
|
2524
|
+
// Enhanced stats with engine metrics
|
|
2525
|
+
stats() {
|
|
2526
|
+
const baseStats = this.data.stats;
|
|
2527
|
+
|
|
2528
|
+
if (this.engine) {
|
|
2529
|
+
try {
|
|
2530
|
+
const engineStats = this.engine.getStats();
|
|
2531
|
+
return {
|
|
2532
|
+
...baseStats,
|
|
2533
|
+
// Engine stats
|
|
2534
|
+
engineEnabled: true,
|
|
2535
|
+
sonaEnabled: engineStats.sonaEnabled,
|
|
2536
|
+
attentionEnabled: engineStats.attentionEnabled,
|
|
2537
|
+
embeddingDim: engineStats.memoryDimensions,
|
|
2538
|
+
totalMemories: engineStats.totalMemories,
|
|
2539
|
+
totalEpisodes: engineStats.totalEpisodes,
|
|
2540
|
+
trajectoriesRecorded: engineStats.trajectoriesRecorded,
|
|
2541
|
+
patternsLearned: engineStats.patternsLearned,
|
|
2542
|
+
microLoraUpdates: engineStats.microLoraUpdates,
|
|
2543
|
+
baseLoraUpdates: engineStats.baseLoraUpdates,
|
|
2544
|
+
ewcConsolidations: engineStats.ewcConsolidations,
|
|
2545
|
+
};
|
|
2546
|
+
} catch {}
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
return { ...baseStats, engineEnabled: false };
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2552
|
+
sessionStart() {
|
|
2553
|
+
this.data.stats.session_count++;
|
|
2554
|
+
this.data.stats.last_session = this.now();
|
|
2555
|
+
this.sessionStartTime = this.now();
|
|
2556
|
+
|
|
2557
|
+
// Tick engine for background learning
|
|
2558
|
+
if (this.engine) {
|
|
2559
|
+
this.engine.tick();
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2279
2563
|
sessionEnd() {
|
|
2280
|
-
const duration = this.now() - this.data.stats.last_session;
|
|
2564
|
+
const duration = this.now() - (this.sessionStartTime || this.data.stats.last_session);
|
|
2281
2565
|
const actions = this.data.trajectories.filter(t => t.timestamp >= this.data.stats.last_session).length;
|
|
2566
|
+
|
|
2567
|
+
// Force learning cycle
|
|
2568
|
+
if (this.engine) {
|
|
2569
|
+
this.engine.forceLearn();
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
// Save all data
|
|
2573
|
+
this.save();
|
|
2574
|
+
|
|
2282
2575
|
return { duration, actions };
|
|
2283
2576
|
}
|
|
2577
|
+
|
|
2284
2578
|
getLastEditedFile() { return this.lastEditedFile; }
|
|
2579
|
+
|
|
2580
|
+
// New: Check if full engine is available
|
|
2581
|
+
isEngineEnabled() {
|
|
2582
|
+
return this.engine !== null;
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
// New: Get engine capabilities
|
|
2586
|
+
getCapabilities() {
|
|
2587
|
+
if (!this.engine) {
|
|
2588
|
+
return {
|
|
2589
|
+
engine: false,
|
|
2590
|
+
vectorDb: false,
|
|
2591
|
+
sona: false,
|
|
2592
|
+
attention: false,
|
|
2593
|
+
embeddingDim: 64,
|
|
2594
|
+
};
|
|
2595
|
+
}
|
|
2596
|
+
const stats = this.engine.getStats();
|
|
2597
|
+
return {
|
|
2598
|
+
engine: true,
|
|
2599
|
+
vectorDb: true,
|
|
2600
|
+
sona: stats.sonaEnabled,
|
|
2601
|
+
attention: stats.attentionEnabled,
|
|
2602
|
+
embeddingDim: stats.memoryDimensions,
|
|
2603
|
+
};
|
|
2604
|
+
}
|
|
2285
2605
|
}
|
|
2286
2606
|
|
|
2287
2607
|
// Hooks command group
|
|
@@ -3628,4 +3948,59 @@ ${focus.description}` : null
|
|
|
3628
3948
|
console.log(chalk.dim(`\nFocus mode "${opts.focus}": ${focus.description}`));
|
|
3629
3949
|
});
|
|
3630
3950
|
|
|
3951
|
+
// MCP Server command
|
|
3952
|
+
const mcpCmd = program.command('mcp').description('MCP (Model Context Protocol) server for Claude Code integration');
|
|
3953
|
+
|
|
3954
|
+
mcpCmd.command('start')
|
|
3955
|
+
.description('Start the RuVector MCP server')
|
|
3956
|
+
.action(() => {
|
|
3957
|
+
// Execute the mcp-server.js directly
|
|
3958
|
+
const mcpServerPath = path.join(__dirname, 'mcp-server.js');
|
|
3959
|
+
if (!fs.existsSync(mcpServerPath)) {
|
|
3960
|
+
console.error(chalk.red('Error: MCP server not found at'), mcpServerPath);
|
|
3961
|
+
process.exit(1);
|
|
3962
|
+
}
|
|
3963
|
+
require(mcpServerPath);
|
|
3964
|
+
});
|
|
3965
|
+
|
|
3966
|
+
mcpCmd.command('info')
|
|
3967
|
+
.description('Show MCP server information and setup instructions')
|
|
3968
|
+
.action(() => {
|
|
3969
|
+
console.log(chalk.bold.cyan('\nš RuVector MCP Server\n'));
|
|
3970
|
+
console.log(chalk.white('The RuVector MCP server provides self-learning intelligence'));
|
|
3971
|
+
console.log(chalk.white('tools to Claude Code via the Model Context Protocol.\n'));
|
|
3972
|
+
|
|
3973
|
+
console.log(chalk.bold('Available Tools:'));
|
|
3974
|
+
console.log(chalk.dim(' hooks_stats - Get intelligence statistics'));
|
|
3975
|
+
console.log(chalk.dim(' hooks_route - Route task to best agent'));
|
|
3976
|
+
console.log(chalk.dim(' hooks_remember - Store context in vector memory'));
|
|
3977
|
+
console.log(chalk.dim(' hooks_recall - Search vector memory'));
|
|
3978
|
+
console.log(chalk.dim(' hooks_init - Initialize hooks in project'));
|
|
3979
|
+
console.log(chalk.dim(' hooks_pretrain - Pretrain from repository'));
|
|
3980
|
+
console.log(chalk.dim(' hooks_build_agents - Generate agent configs'));
|
|
3981
|
+
console.log(chalk.dim(' hooks_verify - Verify hooks configuration'));
|
|
3982
|
+
console.log(chalk.dim(' hooks_doctor - Diagnose setup issues'));
|
|
3983
|
+
console.log(chalk.dim(' hooks_export - Export intelligence data'));
|
|
3984
|
+
|
|
3985
|
+
console.log(chalk.bold('\nš¦ Resources:'));
|
|
3986
|
+
console.log(chalk.dim(' ruvector://intelligence/stats - Current statistics'));
|
|
3987
|
+
console.log(chalk.dim(' ruvector://intelligence/patterns - Learned patterns'));
|
|
3988
|
+
console.log(chalk.dim(' ruvector://intelligence/memories - Vector memories'));
|
|
3989
|
+
|
|
3990
|
+
console.log(chalk.bold.yellow('\nāļø Setup Instructions:\n'));
|
|
3991
|
+
console.log(chalk.white('Add to Claude Code:'));
|
|
3992
|
+
console.log(chalk.cyan(' claude mcp add ruvector npx ruvector mcp start\n'));
|
|
3993
|
+
|
|
3994
|
+
console.log(chalk.white('Or add to .claude/settings.json:'));
|
|
3995
|
+
console.log(chalk.dim(` {
|
|
3996
|
+
"mcpServers": {
|
|
3997
|
+
"ruvector": {
|
|
3998
|
+
"command": "npx",
|
|
3999
|
+
"args": ["ruvector", "mcp", "start"]
|
|
4000
|
+
}
|
|
4001
|
+
}
|
|
4002
|
+
}`));
|
|
4003
|
+
console.log();
|
|
4004
|
+
});
|
|
4005
|
+
|
|
3631
4006
|
program.parse();
|