feat(hooks): add build-agents command and integrate pretrain/agents into init

New command:
- hooks build-agents: Generate optimized agent configs based on repo analysis
  - Focus modes: quality, speed, security, testing, fullstack
  - Detects languages (Rust, TypeScript, Python, Go) and frameworks (React, Vue)
  - Generates YAML/JSON/MD agent definitions with system prompts
  - Creates coordinator agent with routing rules
  - Outputs to .claude/agents/

Init enhancements:
- --pretrain: Bootstrap intelligence after init
- --build-agents [focus]: Generate agents after init

Example: npx ruvector hooks init --pretrain --build-agents security
This commit is contained in:
rUv 2025-12-30 21:28:15 +00:00
parent 0a175e3040
commit 247aeb4fa3
2 changed files with 337 additions and 3 deletions

View file

@ -2311,7 +2311,9 @@ hooksCmd.command('init')
.option('--no-gitignore', 'Skip .gitignore update')
.option('--no-mcp', 'Skip MCP server configuration')
.option('--no-statusline', 'Skip statusLine configuration')
.action((opts) => {
.option('--pretrain', 'Run pretrain after init to bootstrap intelligence')
.option('--build-agents [focus]', 'Generate optimized agents (quality|speed|security|testing|fullstack)')
.action(async (opts) => {
const settingsPath = path.join(process.cwd(), '.claude', 'settings.json');
const settingsDir = path.dirname(settingsPath);
if (!fs.existsSync(settingsDir)) fs.mkdirSync(settingsDir, { recursive: true });
@ -2573,7 +2575,35 @@ npx ruvector hooks init --force # Overwrite existing
}
console.log(chalk.green('\n✅ RuVector hooks initialization complete!'));
console.log(chalk.dim(' Run `npx ruvector hooks verify` to test the setup'));
// Run pretrain if requested
if (opts.pretrain) {
console.log(chalk.yellow('\n📚 Running pretrain to bootstrap intelligence...\n'));
const { execSync } = require('child_process');
try {
execSync('npx ruvector hooks pretrain', { stdio: 'inherit' });
} catch (e) {
console.log(chalk.yellow('⚠️ Pretrain completed with warnings'));
}
}
// Build agents if requested
if (opts.buildAgents) {
const focus = typeof opts.buildAgents === 'string' ? opts.buildAgents : 'quality';
console.log(chalk.yellow(`\n🏗️ Building optimized agents (focus: ${focus})...\n`));
const { execSync } = require('child_process');
try {
execSync(`npx ruvector hooks build-agents --focus ${focus} --include-prompts`, { stdio: 'inherit' });
} catch (e) {
console.log(chalk.yellow('⚠️ Agent build completed with warnings'));
}
}
if (!opts.pretrain && !opts.buildAgents) {
console.log(chalk.dim(' Run `npx ruvector hooks verify` to test the setup'));
console.log(chalk.dim(' Run `npx ruvector hooks pretrain` to bootstrap intelligence'));
console.log(chalk.dim(' Run `npx ruvector hooks build-agents` to generate optimized agents'));
}
});
hooksCmd.command('stats').description('Show intelligence statistics').action(() => {
@ -3274,4 +3304,308 @@ hooksCmd.command('pretrain')
console.log(chalk.dim('\nThe intelligence layer will now provide better recommendations.'));
});
// Agent Builder - generate optimized agent configs based on pretrain
hooksCmd.command('build-agents')
.description('Generate optimized agent configurations based on repository analysis')
.option('--focus <type>', 'Focus type: quality, speed, security, testing, fullstack', 'quality')
.option('--output <dir>', 'Output directory', '.claude/agents')
.option('--format <fmt>', 'Format: yaml, json, md', 'yaml')
.option('--include-prompts', 'Include detailed system prompts')
.action((opts) => {
console.log(chalk.bold.cyan('\n🏗 RuVector Agent Builder\n'));
const intel = new Intelligence();
const outputDir = path.join(process.cwd(), opts.output);
// Check if pretrained
if (!intel.data.pretrained && Object.keys(intel.data.patterns || {}).length === 0) {
console.log(chalk.yellow('⚠️ No pretrain data found. Running quick analysis...\n'));
// Quick file analysis
try {
const { execSync } = require('child_process');
const files = execSync('git ls-files 2>/dev/null', { encoding: 'utf-8' }).trim().split('\n');
files.forEach(f => {
const ext = path.extname(f);
intel.data.patterns = intel.data.patterns || {};
intel.data.patterns[`edit:${ext}`] = intel.data.patterns[`edit:${ext}`] || {};
});
} catch (e) { /* continue without git */ }
}
// Analyze patterns to determine relevant agents
const patterns = intel.data.patterns || {};
const detectedLangs = new Set();
const detectedFrameworks = new Set();
Object.keys(patterns).forEach(state => {
if (state.includes('.rs')) detectedLangs.add('rust');
if (state.includes('.ts') || state.includes('.js')) detectedLangs.add('typescript');
if (state.includes('.tsx') || state.includes('.jsx')) detectedFrameworks.add('react');
if (state.includes('.py')) detectedLangs.add('python');
if (state.includes('.go')) detectedLangs.add('go');
if (state.includes('.vue')) detectedFrameworks.add('vue');
if (state.includes('.sql')) detectedFrameworks.add('database');
});
// Detect project type from files
const projectTypes = detectProjectType();
console.log(chalk.blue(` Detected languages: ${[...detectedLangs].join(', ') || 'generic'}`));
console.log(chalk.blue(` Detected frameworks: ${[...detectedFrameworks].join(', ') || 'none'}`));
console.log(chalk.blue(` Focus mode: ${opts.focus}\n`));
// Focus configurations
const focusConfigs = {
quality: {
description: 'Emphasizes code quality, best practices, and maintainability',
priorities: ['code-review', 'refactoring', 'documentation', 'testing'],
temperature: 0.3
},
speed: {
description: 'Optimized for rapid development and iteration',
priorities: ['implementation', 'prototyping', 'quick-fixes'],
temperature: 0.7
},
security: {
description: 'Security-first development with vulnerability awareness',
priorities: ['security-audit', 'input-validation', 'authentication', 'encryption'],
temperature: 0.2
},
testing: {
description: 'Test-driven development with comprehensive coverage',
priorities: ['unit-tests', 'integration-tests', 'e2e-tests', 'mocking'],
temperature: 0.4
},
fullstack: {
description: 'Balanced full-stack development capabilities',
priorities: ['frontend', 'backend', 'database', 'api-design'],
temperature: 0.5
}
};
const focus = focusConfigs[opts.focus] || focusConfigs.quality;
// Agent templates based on detected stack
const agents = [];
// Core agents based on detected languages
if (detectedLangs.has('rust')) {
agents.push({
name: 'rust-specialist',
type: 'rust-developer',
description: 'Rust development specialist for this codebase',
capabilities: ['cargo', 'unsafe-rust', 'async-rust', 'wasm', 'error-handling'],
focus: focus.priorities,
systemPrompt: opts.includePrompts ? `You are a Rust specialist for this project.
Focus on: memory safety, zero-cost abstractions, idiomatic Rust patterns.
Use cargo conventions, prefer Result over panic, leverage the type system.
${focus.description}` : null
});
}
if (detectedLangs.has('typescript')) {
agents.push({
name: 'typescript-specialist',
type: 'typescript-developer',
description: 'TypeScript development specialist',
capabilities: ['types', 'generics', 'decorators', 'async-await', 'modules'],
focus: focus.priorities,
systemPrompt: opts.includePrompts ? `You are a TypeScript specialist for this project.
Focus on: strict typing, type inference, generic patterns, module organization.
Prefer type safety over any, use discriminated unions, leverage utility types.
${focus.description}` : null
});
}
if (detectedLangs.has('python')) {
agents.push({
name: 'python-specialist',
type: 'python-developer',
description: 'Python development specialist',
capabilities: ['typing', 'async', 'testing', 'packaging', 'data-science'],
focus: focus.priorities,
systemPrompt: opts.includePrompts ? `You are a Python specialist for this project.
Focus on: type hints, PEP standards, pythonic idioms, virtual environments.
Use dataclasses, prefer pathlib, leverage context managers.
${focus.description}` : null
});
}
if (detectedLangs.has('go')) {
agents.push({
name: 'go-specialist',
type: 'go-developer',
description: 'Go development specialist',
capabilities: ['goroutines', 'channels', 'interfaces', 'testing', 'modules'],
focus: focus.priorities,
systemPrompt: opts.includePrompts ? `You are a Go specialist for this project.
Focus on: simplicity, explicit error handling, goroutines, interface composition.
Follow Go conventions, use go fmt, prefer composition over inheritance.
${focus.description}` : null
});
}
// Framework-specific agents
if (detectedFrameworks.has('react')) {
agents.push({
name: 'react-specialist',
type: 'react-developer',
description: 'React/Next.js development specialist',
capabilities: ['hooks', 'state-management', 'components', 'ssr', 'testing'],
focus: focus.priorities,
systemPrompt: opts.includePrompts ? `You are a React specialist for this project.
Focus on: functional components, hooks, state management, performance optimization.
Prefer composition, use memo wisely, follow React best practices.
${focus.description}` : null
});
}
if (detectedFrameworks.has('database')) {
agents.push({
name: 'database-specialist',
type: 'database-specialist',
description: 'Database design and optimization specialist',
capabilities: ['schema-design', 'queries', 'indexing', 'migrations', 'orm'],
focus: focus.priorities,
systemPrompt: opts.includePrompts ? `You are a database specialist for this project.
Focus on: normalized schemas, efficient queries, proper indexing, data integrity.
Consider performance implications, use transactions appropriately.
${focus.description}` : null
});
}
// Focus-specific agents
if (opts.focus === 'testing' || opts.focus === 'quality') {
agents.push({
name: 'test-architect',
type: 'test-engineer',
description: 'Testing and quality assurance specialist',
capabilities: ['unit-tests', 'integration-tests', 'mocking', 'coverage', 'tdd'],
focus: ['testing', 'quality', 'reliability'],
systemPrompt: opts.includePrompts ? `You are a testing specialist for this project.
Focus on: comprehensive test coverage, meaningful assertions, test isolation.
Write tests first when possible, mock external dependencies, aim for >80% coverage.
${focus.description}` : null
});
}
if (opts.focus === 'security') {
agents.push({
name: 'security-auditor',
type: 'security-specialist',
description: 'Security audit and hardening specialist',
capabilities: ['vulnerability-scan', 'auth', 'encryption', 'input-validation', 'owasp'],
focus: ['security', 'compliance', 'hardening'],
systemPrompt: opts.includePrompts ? `You are a security specialist for this project.
Focus on: OWASP top 10, input validation, authentication, authorization, encryption.
Never trust user input, use parameterized queries, implement defense in depth.
${focus.description}` : null
});
}
// Add coordinator agent
agents.push({
name: 'project-coordinator',
type: 'coordinator',
description: 'Coordinates multi-agent workflows for this project',
capabilities: ['task-decomposition', 'agent-routing', 'context-management'],
focus: focus.priorities,
routes: agents.filter(a => a.name !== 'project-coordinator').map(a => ({
pattern: a.capabilities[0],
agent: a.name
}))
});
// Create output directory
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// Generate agent files
agents.forEach(agent => {
let content;
const filename = `${agent.name}.${opts.format}`;
const filepath = path.join(outputDir, filename);
if (opts.format === 'yaml') {
const yaml = [
`# Auto-generated by RuVector Agent Builder`,
`# Focus: ${opts.focus}`,
`# Generated: ${new Date().toISOString()}`,
``,
`name: ${agent.name}`,
`type: ${agent.type}`,
`description: ${agent.description}`,
``,
`capabilities:`,
...agent.capabilities.map(c => ` - ${c}`),
``,
`focus:`,
...agent.focus.map(f => ` - ${f}`),
];
if (agent.systemPrompt) {
yaml.push(``, `system_prompt: |`);
agent.systemPrompt.split('\n').forEach(line => yaml.push(` ${line}`));
}
if (agent.routes) {
yaml.push(``, `routes:`);
agent.routes.forEach(r => yaml.push(` - pattern: "${r.pattern}"`, ` agent: ${r.agent}`));
}
content = yaml.join('\n');
} else if (opts.format === 'json') {
content = JSON.stringify(agent, null, 2);
} else {
// Markdown format
content = [
`# ${agent.name}`,
``,
`**Type:** ${agent.type}`,
`**Description:** ${agent.description}`,
``,
`## Capabilities`,
...agent.capabilities.map(c => `- ${c}`),
``,
`## Focus Areas`,
...agent.focus.map(f => `- ${f}`),
].join('\n');
if (agent.systemPrompt) {
content += `\n\n## System Prompt\n\n\`\`\`\n${agent.systemPrompt}\n\`\`\``;
}
}
fs.writeFileSync(filepath, content);
console.log(chalk.green(` ✓ Created ${filename}`));
});
// Create index file
const indexContent = opts.format === 'yaml'
? `# RuVector Agent Configuration\n# Focus: ${opts.focus}\n\nagents:\n${agents.map(a => ` - ${a.name}`).join('\n')}`
: JSON.stringify({ focus: opts.focus, agents: agents.map(a => a.name) }, null, 2);
fs.writeFileSync(path.join(outputDir, `index.${opts.format === 'md' ? 'json' : opts.format}`), indexContent);
// Update settings to reference agents
const settingsPath = path.join(process.cwd(), '.claude', 'settings.json');
if (fs.existsSync(settingsPath)) {
try {
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
settings.agentConfig = {
directory: opts.output,
focus: opts.focus,
agents: agents.map(a => a.name),
generated: new Date().toISOString()
};
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
console.log(chalk.blue('\n ✓ Updated .claude/settings.json with agent config'));
} catch (e) { /* ignore settings errors */ }
}
console.log(chalk.bold.green(`\n✅ Generated ${agents.length} optimized agents in ${opts.output}/\n`));
console.log(chalk.cyan('Agents created:'));
agents.forEach(a => {
console.log(` 🤖 ${chalk.bold(a.name)}: ${a.description}`);
});
console.log(chalk.dim(`\nFocus mode "${opts.focus}": ${focus.description}`));
});
program.parse();

View file

@ -1,6 +1,6 @@
{
"name": "ruvector",
"version": "0.1.47",
"version": "0.1.48",
"description": "High-performance vector database for Node.js with automatic native/WASM fallback",
"main": "dist/index.js",
"types": "dist/index.d.ts",