ruvector 0.1.47 ā 0.1.48
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 +336 -2
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -2311,7 +2311,9 @@ hooksCmd.command('init')
|
|
|
2311
2311
|
.option('--no-gitignore', 'Skip .gitignore update')
|
|
2312
2312
|
.option('--no-mcp', 'Skip MCP server configuration')
|
|
2313
2313
|
.option('--no-statusline', 'Skip statusLine configuration')
|
|
2314
|
-
.
|
|
2314
|
+
.option('--pretrain', 'Run pretrain after init to bootstrap intelligence')
|
|
2315
|
+
.option('--build-agents [focus]', 'Generate optimized agents (quality|speed|security|testing|fullstack)')
|
|
2316
|
+
.action(async (opts) => {
|
|
2315
2317
|
const settingsPath = path.join(process.cwd(), '.claude', 'settings.json');
|
|
2316
2318
|
const settingsDir = path.dirname(settingsPath);
|
|
2317
2319
|
if (!fs.existsSync(settingsDir)) fs.mkdirSync(settingsDir, { recursive: true });
|
|
@@ -2573,7 +2575,35 @@ npx ruvector hooks init --force # Overwrite existing
|
|
|
2573
2575
|
}
|
|
2574
2576
|
|
|
2575
2577
|
console.log(chalk.green('\nā
RuVector hooks initialization complete!'));
|
|
2576
|
-
|
|
2578
|
+
|
|
2579
|
+
// Run pretrain if requested
|
|
2580
|
+
if (opts.pretrain) {
|
|
2581
|
+
console.log(chalk.yellow('\nš Running pretrain to bootstrap intelligence...\n'));
|
|
2582
|
+
const { execSync } = require('child_process');
|
|
2583
|
+
try {
|
|
2584
|
+
execSync('npx ruvector hooks pretrain', { stdio: 'inherit' });
|
|
2585
|
+
} catch (e) {
|
|
2586
|
+
console.log(chalk.yellow('ā ļø Pretrain completed with warnings'));
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
// Build agents if requested
|
|
2591
|
+
if (opts.buildAgents) {
|
|
2592
|
+
const focus = typeof opts.buildAgents === 'string' ? opts.buildAgents : 'quality';
|
|
2593
|
+
console.log(chalk.yellow(`\nšļø Building optimized agents (focus: ${focus})...\n`));
|
|
2594
|
+
const { execSync } = require('child_process');
|
|
2595
|
+
try {
|
|
2596
|
+
execSync(`npx ruvector hooks build-agents --focus ${focus} --include-prompts`, { stdio: 'inherit' });
|
|
2597
|
+
} catch (e) {
|
|
2598
|
+
console.log(chalk.yellow('ā ļø Agent build completed with warnings'));
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2602
|
+
if (!opts.pretrain && !opts.buildAgents) {
|
|
2603
|
+
console.log(chalk.dim(' Run `npx ruvector hooks verify` to test the setup'));
|
|
2604
|
+
console.log(chalk.dim(' Run `npx ruvector hooks pretrain` to bootstrap intelligence'));
|
|
2605
|
+
console.log(chalk.dim(' Run `npx ruvector hooks build-agents` to generate optimized agents'));
|
|
2606
|
+
}
|
|
2577
2607
|
});
|
|
2578
2608
|
|
|
2579
2609
|
hooksCmd.command('stats').description('Show intelligence statistics').action(() => {
|
|
@@ -3274,4 +3304,308 @@ hooksCmd.command('pretrain')
|
|
|
3274
3304
|
console.log(chalk.dim('\nThe intelligence layer will now provide better recommendations.'));
|
|
3275
3305
|
});
|
|
3276
3306
|
|
|
3307
|
+
// Agent Builder - generate optimized agent configs based on pretrain
|
|
3308
|
+
hooksCmd.command('build-agents')
|
|
3309
|
+
.description('Generate optimized agent configurations based on repository analysis')
|
|
3310
|
+
.option('--focus <type>', 'Focus type: quality, speed, security, testing, fullstack', 'quality')
|
|
3311
|
+
.option('--output <dir>', 'Output directory', '.claude/agents')
|
|
3312
|
+
.option('--format <fmt>', 'Format: yaml, json, md', 'yaml')
|
|
3313
|
+
.option('--include-prompts', 'Include detailed system prompts')
|
|
3314
|
+
.action((opts) => {
|
|
3315
|
+
console.log(chalk.bold.cyan('\nšļø RuVector Agent Builder\n'));
|
|
3316
|
+
|
|
3317
|
+
const intel = new Intelligence();
|
|
3318
|
+
const outputDir = path.join(process.cwd(), opts.output);
|
|
3319
|
+
|
|
3320
|
+
// Check if pretrained
|
|
3321
|
+
if (!intel.data.pretrained && Object.keys(intel.data.patterns || {}).length === 0) {
|
|
3322
|
+
console.log(chalk.yellow('ā ļø No pretrain data found. Running quick analysis...\n'));
|
|
3323
|
+
// Quick file analysis
|
|
3324
|
+
try {
|
|
3325
|
+
const { execSync } = require('child_process');
|
|
3326
|
+
const files = execSync('git ls-files 2>/dev/null', { encoding: 'utf-8' }).trim().split('\n');
|
|
3327
|
+
files.forEach(f => {
|
|
3328
|
+
const ext = path.extname(f);
|
|
3329
|
+
intel.data.patterns = intel.data.patterns || {};
|
|
3330
|
+
intel.data.patterns[`edit:${ext}`] = intel.data.patterns[`edit:${ext}`] || {};
|
|
3331
|
+
});
|
|
3332
|
+
} catch (e) { /* continue without git */ }
|
|
3333
|
+
}
|
|
3334
|
+
|
|
3335
|
+
// Analyze patterns to determine relevant agents
|
|
3336
|
+
const patterns = intel.data.patterns || {};
|
|
3337
|
+
const detectedLangs = new Set();
|
|
3338
|
+
const detectedFrameworks = new Set();
|
|
3339
|
+
|
|
3340
|
+
Object.keys(patterns).forEach(state => {
|
|
3341
|
+
if (state.includes('.rs')) detectedLangs.add('rust');
|
|
3342
|
+
if (state.includes('.ts') || state.includes('.js')) detectedLangs.add('typescript');
|
|
3343
|
+
if (state.includes('.tsx') || state.includes('.jsx')) detectedFrameworks.add('react');
|
|
3344
|
+
if (state.includes('.py')) detectedLangs.add('python');
|
|
3345
|
+
if (state.includes('.go')) detectedLangs.add('go');
|
|
3346
|
+
if (state.includes('.vue')) detectedFrameworks.add('vue');
|
|
3347
|
+
if (state.includes('.sql')) detectedFrameworks.add('database');
|
|
3348
|
+
});
|
|
3349
|
+
|
|
3350
|
+
// Detect project type from files
|
|
3351
|
+
const projectTypes = detectProjectType();
|
|
3352
|
+
|
|
3353
|
+
console.log(chalk.blue(` Detected languages: ${[...detectedLangs].join(', ') || 'generic'}`));
|
|
3354
|
+
console.log(chalk.blue(` Detected frameworks: ${[...detectedFrameworks].join(', ') || 'none'}`));
|
|
3355
|
+
console.log(chalk.blue(` Focus mode: ${opts.focus}\n`));
|
|
3356
|
+
|
|
3357
|
+
// Focus configurations
|
|
3358
|
+
const focusConfigs = {
|
|
3359
|
+
quality: {
|
|
3360
|
+
description: 'Emphasizes code quality, best practices, and maintainability',
|
|
3361
|
+
priorities: ['code-review', 'refactoring', 'documentation', 'testing'],
|
|
3362
|
+
temperature: 0.3
|
|
3363
|
+
},
|
|
3364
|
+
speed: {
|
|
3365
|
+
description: 'Optimized for rapid development and iteration',
|
|
3366
|
+
priorities: ['implementation', 'prototyping', 'quick-fixes'],
|
|
3367
|
+
temperature: 0.7
|
|
3368
|
+
},
|
|
3369
|
+
security: {
|
|
3370
|
+
description: 'Security-first development with vulnerability awareness',
|
|
3371
|
+
priorities: ['security-audit', 'input-validation', 'authentication', 'encryption'],
|
|
3372
|
+
temperature: 0.2
|
|
3373
|
+
},
|
|
3374
|
+
testing: {
|
|
3375
|
+
description: 'Test-driven development with comprehensive coverage',
|
|
3376
|
+
priorities: ['unit-tests', 'integration-tests', 'e2e-tests', 'mocking'],
|
|
3377
|
+
temperature: 0.4
|
|
3378
|
+
},
|
|
3379
|
+
fullstack: {
|
|
3380
|
+
description: 'Balanced full-stack development capabilities',
|
|
3381
|
+
priorities: ['frontend', 'backend', 'database', 'api-design'],
|
|
3382
|
+
temperature: 0.5
|
|
3383
|
+
}
|
|
3384
|
+
};
|
|
3385
|
+
|
|
3386
|
+
const focus = focusConfigs[opts.focus] || focusConfigs.quality;
|
|
3387
|
+
|
|
3388
|
+
// Agent templates based on detected stack
|
|
3389
|
+
const agents = [];
|
|
3390
|
+
|
|
3391
|
+
// Core agents based on detected languages
|
|
3392
|
+
if (detectedLangs.has('rust')) {
|
|
3393
|
+
agents.push({
|
|
3394
|
+
name: 'rust-specialist',
|
|
3395
|
+
type: 'rust-developer',
|
|
3396
|
+
description: 'Rust development specialist for this codebase',
|
|
3397
|
+
capabilities: ['cargo', 'unsafe-rust', 'async-rust', 'wasm', 'error-handling'],
|
|
3398
|
+
focus: focus.priorities,
|
|
3399
|
+
systemPrompt: opts.includePrompts ? `You are a Rust specialist for this project.
|
|
3400
|
+
Focus on: memory safety, zero-cost abstractions, idiomatic Rust patterns.
|
|
3401
|
+
Use cargo conventions, prefer Result over panic, leverage the type system.
|
|
3402
|
+
${focus.description}` : null
|
|
3403
|
+
});
|
|
3404
|
+
}
|
|
3405
|
+
|
|
3406
|
+
if (detectedLangs.has('typescript')) {
|
|
3407
|
+
agents.push({
|
|
3408
|
+
name: 'typescript-specialist',
|
|
3409
|
+
type: 'typescript-developer',
|
|
3410
|
+
description: 'TypeScript development specialist',
|
|
3411
|
+
capabilities: ['types', 'generics', 'decorators', 'async-await', 'modules'],
|
|
3412
|
+
focus: focus.priorities,
|
|
3413
|
+
systemPrompt: opts.includePrompts ? `You are a TypeScript specialist for this project.
|
|
3414
|
+
Focus on: strict typing, type inference, generic patterns, module organization.
|
|
3415
|
+
Prefer type safety over any, use discriminated unions, leverage utility types.
|
|
3416
|
+
${focus.description}` : null
|
|
3417
|
+
});
|
|
3418
|
+
}
|
|
3419
|
+
|
|
3420
|
+
if (detectedLangs.has('python')) {
|
|
3421
|
+
agents.push({
|
|
3422
|
+
name: 'python-specialist',
|
|
3423
|
+
type: 'python-developer',
|
|
3424
|
+
description: 'Python development specialist',
|
|
3425
|
+
capabilities: ['typing', 'async', 'testing', 'packaging', 'data-science'],
|
|
3426
|
+
focus: focus.priorities,
|
|
3427
|
+
systemPrompt: opts.includePrompts ? `You are a Python specialist for this project.
|
|
3428
|
+
Focus on: type hints, PEP standards, pythonic idioms, virtual environments.
|
|
3429
|
+
Use dataclasses, prefer pathlib, leverage context managers.
|
|
3430
|
+
${focus.description}` : null
|
|
3431
|
+
});
|
|
3432
|
+
}
|
|
3433
|
+
|
|
3434
|
+
if (detectedLangs.has('go')) {
|
|
3435
|
+
agents.push({
|
|
3436
|
+
name: 'go-specialist',
|
|
3437
|
+
type: 'go-developer',
|
|
3438
|
+
description: 'Go development specialist',
|
|
3439
|
+
capabilities: ['goroutines', 'channels', 'interfaces', 'testing', 'modules'],
|
|
3440
|
+
focus: focus.priorities,
|
|
3441
|
+
systemPrompt: opts.includePrompts ? `You are a Go specialist for this project.
|
|
3442
|
+
Focus on: simplicity, explicit error handling, goroutines, interface composition.
|
|
3443
|
+
Follow Go conventions, use go fmt, prefer composition over inheritance.
|
|
3444
|
+
${focus.description}` : null
|
|
3445
|
+
});
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3448
|
+
// Framework-specific agents
|
|
3449
|
+
if (detectedFrameworks.has('react')) {
|
|
3450
|
+
agents.push({
|
|
3451
|
+
name: 'react-specialist',
|
|
3452
|
+
type: 'react-developer',
|
|
3453
|
+
description: 'React/Next.js development specialist',
|
|
3454
|
+
capabilities: ['hooks', 'state-management', 'components', 'ssr', 'testing'],
|
|
3455
|
+
focus: focus.priorities,
|
|
3456
|
+
systemPrompt: opts.includePrompts ? `You are a React specialist for this project.
|
|
3457
|
+
Focus on: functional components, hooks, state management, performance optimization.
|
|
3458
|
+
Prefer composition, use memo wisely, follow React best practices.
|
|
3459
|
+
${focus.description}` : null
|
|
3460
|
+
});
|
|
3461
|
+
}
|
|
3462
|
+
|
|
3463
|
+
if (detectedFrameworks.has('database')) {
|
|
3464
|
+
agents.push({
|
|
3465
|
+
name: 'database-specialist',
|
|
3466
|
+
type: 'database-specialist',
|
|
3467
|
+
description: 'Database design and optimization specialist',
|
|
3468
|
+
capabilities: ['schema-design', 'queries', 'indexing', 'migrations', 'orm'],
|
|
3469
|
+
focus: focus.priorities,
|
|
3470
|
+
systemPrompt: opts.includePrompts ? `You are a database specialist for this project.
|
|
3471
|
+
Focus on: normalized schemas, efficient queries, proper indexing, data integrity.
|
|
3472
|
+
Consider performance implications, use transactions appropriately.
|
|
3473
|
+
${focus.description}` : null
|
|
3474
|
+
});
|
|
3475
|
+
}
|
|
3476
|
+
|
|
3477
|
+
// Focus-specific agents
|
|
3478
|
+
if (opts.focus === 'testing' || opts.focus === 'quality') {
|
|
3479
|
+
agents.push({
|
|
3480
|
+
name: 'test-architect',
|
|
3481
|
+
type: 'test-engineer',
|
|
3482
|
+
description: 'Testing and quality assurance specialist',
|
|
3483
|
+
capabilities: ['unit-tests', 'integration-tests', 'mocking', 'coverage', 'tdd'],
|
|
3484
|
+
focus: ['testing', 'quality', 'reliability'],
|
|
3485
|
+
systemPrompt: opts.includePrompts ? `You are a testing specialist for this project.
|
|
3486
|
+
Focus on: comprehensive test coverage, meaningful assertions, test isolation.
|
|
3487
|
+
Write tests first when possible, mock external dependencies, aim for >80% coverage.
|
|
3488
|
+
${focus.description}` : null
|
|
3489
|
+
});
|
|
3490
|
+
}
|
|
3491
|
+
|
|
3492
|
+
if (opts.focus === 'security') {
|
|
3493
|
+
agents.push({
|
|
3494
|
+
name: 'security-auditor',
|
|
3495
|
+
type: 'security-specialist',
|
|
3496
|
+
description: 'Security audit and hardening specialist',
|
|
3497
|
+
capabilities: ['vulnerability-scan', 'auth', 'encryption', 'input-validation', 'owasp'],
|
|
3498
|
+
focus: ['security', 'compliance', 'hardening'],
|
|
3499
|
+
systemPrompt: opts.includePrompts ? `You are a security specialist for this project.
|
|
3500
|
+
Focus on: OWASP top 10, input validation, authentication, authorization, encryption.
|
|
3501
|
+
Never trust user input, use parameterized queries, implement defense in depth.
|
|
3502
|
+
${focus.description}` : null
|
|
3503
|
+
});
|
|
3504
|
+
}
|
|
3505
|
+
|
|
3506
|
+
// Add coordinator agent
|
|
3507
|
+
agents.push({
|
|
3508
|
+
name: 'project-coordinator',
|
|
3509
|
+
type: 'coordinator',
|
|
3510
|
+
description: 'Coordinates multi-agent workflows for this project',
|
|
3511
|
+
capabilities: ['task-decomposition', 'agent-routing', 'context-management'],
|
|
3512
|
+
focus: focus.priorities,
|
|
3513
|
+
routes: agents.filter(a => a.name !== 'project-coordinator').map(a => ({
|
|
3514
|
+
pattern: a.capabilities[0],
|
|
3515
|
+
agent: a.name
|
|
3516
|
+
}))
|
|
3517
|
+
});
|
|
3518
|
+
|
|
3519
|
+
// Create output directory
|
|
3520
|
+
if (!fs.existsSync(outputDir)) {
|
|
3521
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
3522
|
+
}
|
|
3523
|
+
|
|
3524
|
+
// Generate agent files
|
|
3525
|
+
agents.forEach(agent => {
|
|
3526
|
+
let content;
|
|
3527
|
+
const filename = `${agent.name}.${opts.format}`;
|
|
3528
|
+
const filepath = path.join(outputDir, filename);
|
|
3529
|
+
|
|
3530
|
+
if (opts.format === 'yaml') {
|
|
3531
|
+
const yaml = [
|
|
3532
|
+
`# Auto-generated by RuVector Agent Builder`,
|
|
3533
|
+
`# Focus: ${opts.focus}`,
|
|
3534
|
+
`# Generated: ${new Date().toISOString()}`,
|
|
3535
|
+
``,
|
|
3536
|
+
`name: ${agent.name}`,
|
|
3537
|
+
`type: ${agent.type}`,
|
|
3538
|
+
`description: ${agent.description}`,
|
|
3539
|
+
``,
|
|
3540
|
+
`capabilities:`,
|
|
3541
|
+
...agent.capabilities.map(c => ` - ${c}`),
|
|
3542
|
+
``,
|
|
3543
|
+
`focus:`,
|
|
3544
|
+
...agent.focus.map(f => ` - ${f}`),
|
|
3545
|
+
];
|
|
3546
|
+
if (agent.systemPrompt) {
|
|
3547
|
+
yaml.push(``, `system_prompt: |`);
|
|
3548
|
+
agent.systemPrompt.split('\n').forEach(line => yaml.push(` ${line}`));
|
|
3549
|
+
}
|
|
3550
|
+
if (agent.routes) {
|
|
3551
|
+
yaml.push(``, `routes:`);
|
|
3552
|
+
agent.routes.forEach(r => yaml.push(` - pattern: "${r.pattern}"`, ` agent: ${r.agent}`));
|
|
3553
|
+
}
|
|
3554
|
+
content = yaml.join('\n');
|
|
3555
|
+
} else if (opts.format === 'json') {
|
|
3556
|
+
content = JSON.stringify(agent, null, 2);
|
|
3557
|
+
} else {
|
|
3558
|
+
// Markdown format
|
|
3559
|
+
content = [
|
|
3560
|
+
`# ${agent.name}`,
|
|
3561
|
+
``,
|
|
3562
|
+
`**Type:** ${agent.type}`,
|
|
3563
|
+
`**Description:** ${agent.description}`,
|
|
3564
|
+
``,
|
|
3565
|
+
`## Capabilities`,
|
|
3566
|
+
...agent.capabilities.map(c => `- ${c}`),
|
|
3567
|
+
``,
|
|
3568
|
+
`## Focus Areas`,
|
|
3569
|
+
...agent.focus.map(f => `- ${f}`),
|
|
3570
|
+
].join('\n');
|
|
3571
|
+
if (agent.systemPrompt) {
|
|
3572
|
+
content += `\n\n## System Prompt\n\n\`\`\`\n${agent.systemPrompt}\n\`\`\``;
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3575
|
+
|
|
3576
|
+
fs.writeFileSync(filepath, content);
|
|
3577
|
+
console.log(chalk.green(` ā Created ${filename}`));
|
|
3578
|
+
});
|
|
3579
|
+
|
|
3580
|
+
// Create index file
|
|
3581
|
+
const indexContent = opts.format === 'yaml'
|
|
3582
|
+
? `# RuVector Agent Configuration\n# Focus: ${opts.focus}\n\nagents:\n${agents.map(a => ` - ${a.name}`).join('\n')}`
|
|
3583
|
+
: JSON.stringify({ focus: opts.focus, agents: agents.map(a => a.name) }, null, 2);
|
|
3584
|
+
|
|
3585
|
+
fs.writeFileSync(path.join(outputDir, `index.${opts.format === 'md' ? 'json' : opts.format}`), indexContent);
|
|
3586
|
+
|
|
3587
|
+
// Update settings to reference agents
|
|
3588
|
+
const settingsPath = path.join(process.cwd(), '.claude', 'settings.json');
|
|
3589
|
+
if (fs.existsSync(settingsPath)) {
|
|
3590
|
+
try {
|
|
3591
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
3592
|
+
settings.agentConfig = {
|
|
3593
|
+
directory: opts.output,
|
|
3594
|
+
focus: opts.focus,
|
|
3595
|
+
agents: agents.map(a => a.name),
|
|
3596
|
+
generated: new Date().toISOString()
|
|
3597
|
+
};
|
|
3598
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
3599
|
+
console.log(chalk.blue('\n ā Updated .claude/settings.json with agent config'));
|
|
3600
|
+
} catch (e) { /* ignore settings errors */ }
|
|
3601
|
+
}
|
|
3602
|
+
|
|
3603
|
+
console.log(chalk.bold.green(`\nā
Generated ${agents.length} optimized agents in ${opts.output}/\n`));
|
|
3604
|
+
console.log(chalk.cyan('Agents created:'));
|
|
3605
|
+
agents.forEach(a => {
|
|
3606
|
+
console.log(` š¤ ${chalk.bold(a.name)}: ${a.description}`);
|
|
3607
|
+
});
|
|
3608
|
+
console.log(chalk.dim(`\nFocus mode "${opts.focus}": ${focus.description}`));
|
|
3609
|
+
});
|
|
3610
|
+
|
|
3277
3611
|
program.parse();
|