ruvector 0.1.49 → 0.1.51
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/HOOKS.md +221 -0
- package/README.md +20 -0
- package/bin/cli.js +55 -0
- package/bin/mcp-server.js +581 -0
- package/package.json +2 -1
package/HOOKS.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# RuVector Hooks for Claude Code
|
|
2
|
+
|
|
3
|
+
Self-learning intelligence hooks that enhance Claude Code with Q-learning, vector memory, and automatic agent routing.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Full setup: hooks + pretrain + optimized agents
|
|
9
|
+
npx ruvector hooks init --pretrain --build-agents quality
|
|
10
|
+
|
|
11
|
+
# Or step by step:
|
|
12
|
+
npx ruvector hooks init # Setup hooks
|
|
13
|
+
npx ruvector hooks pretrain # Analyze repository
|
|
14
|
+
npx ruvector hooks build-agents # Generate agent configs
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## What It Does
|
|
18
|
+
|
|
19
|
+
RuVector hooks integrate with Claude Code to provide:
|
|
20
|
+
|
|
21
|
+
| Feature | Description |
|
|
22
|
+
|---------|-------------|
|
|
23
|
+
| **Agent Routing** | Suggests the best agent for each file type based on learned patterns |
|
|
24
|
+
| **Co-edit Patterns** | Predicts "likely next files" from git history |
|
|
25
|
+
| **Vector Memory** | Semantic recall of project context |
|
|
26
|
+
| **Command Analysis** | Risk assessment for bash commands |
|
|
27
|
+
| **Self-Learning** | Q-learning improves suggestions over time |
|
|
28
|
+
|
|
29
|
+
## Commands
|
|
30
|
+
|
|
31
|
+
### Initialization
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Full configuration
|
|
35
|
+
npx ruvector hooks init
|
|
36
|
+
|
|
37
|
+
# With pretrain and agent building
|
|
38
|
+
npx ruvector hooks init --pretrain --build-agents security
|
|
39
|
+
|
|
40
|
+
# Minimal (basic hooks only)
|
|
41
|
+
npx ruvector hooks init --minimal
|
|
42
|
+
|
|
43
|
+
# Options
|
|
44
|
+
--force # Overwrite existing settings
|
|
45
|
+
--minimal # Basic hooks only
|
|
46
|
+
--pretrain # Run pretrain after init
|
|
47
|
+
--build-agents # Generate optimized agents (quality|speed|security|testing|fullstack)
|
|
48
|
+
--no-claude-md # Skip CLAUDE.md creation
|
|
49
|
+
--no-permissions # Skip permissions config
|
|
50
|
+
--no-env # Skip environment variables
|
|
51
|
+
--no-gitignore # Skip .gitignore update
|
|
52
|
+
--no-mcp # Skip MCP server config
|
|
53
|
+
--no-statusline # Skip status line config
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Pretrain
|
|
57
|
+
|
|
58
|
+
Analyze your repository to bootstrap intelligence:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx ruvector hooks pretrain
|
|
62
|
+
|
|
63
|
+
# Options
|
|
64
|
+
--depth <n> # Git history depth (default: 100)
|
|
65
|
+
--verbose # Show detailed progress
|
|
66
|
+
--skip-git # Skip git history analysis
|
|
67
|
+
--skip-files # Skip file structure analysis
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**What it learns:**
|
|
71
|
+
- File type → Agent mapping (`.rs` → rust-developer)
|
|
72
|
+
- Co-edit patterns from git history
|
|
73
|
+
- Directory → Agent mapping
|
|
74
|
+
- Project context memories
|
|
75
|
+
|
|
76
|
+
### Build Agents
|
|
77
|
+
|
|
78
|
+
Generate optimized `.claude/agents/` configurations:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npx ruvector hooks build-agents --focus quality
|
|
82
|
+
|
|
83
|
+
# Focus modes
|
|
84
|
+
--focus quality # Code quality, best practices (default)
|
|
85
|
+
--focus speed # Rapid development, prototyping
|
|
86
|
+
--focus security # OWASP, input validation, encryption
|
|
87
|
+
--focus testing # TDD, comprehensive coverage
|
|
88
|
+
--focus fullstack # Balanced frontend/backend/database
|
|
89
|
+
|
|
90
|
+
# Options
|
|
91
|
+
--output <dir> # Output directory (default: .claude/agents)
|
|
92
|
+
--format <fmt> # yaml, json, or md (default: yaml)
|
|
93
|
+
--include-prompts # Include system prompts in agent configs
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Verification & Diagnostics
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Check if hooks are working
|
|
100
|
+
npx ruvector hooks verify
|
|
101
|
+
|
|
102
|
+
# Diagnose and fix issues
|
|
103
|
+
npx ruvector hooks doctor
|
|
104
|
+
npx ruvector hooks doctor --fix
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Data Management
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# View statistics
|
|
111
|
+
npx ruvector hooks stats
|
|
112
|
+
|
|
113
|
+
# Export intelligence data
|
|
114
|
+
npx ruvector hooks export -o backup.json
|
|
115
|
+
npx ruvector hooks export --include-all
|
|
116
|
+
|
|
117
|
+
# Import intelligence data
|
|
118
|
+
npx ruvector hooks import backup.json
|
|
119
|
+
npx ruvector hooks import backup.json --merge
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Memory Operations
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Store context in vector memory
|
|
126
|
+
npx ruvector hooks remember "API uses JWT auth" -t project
|
|
127
|
+
|
|
128
|
+
# Semantic search memory
|
|
129
|
+
npx ruvector hooks recall "authentication"
|
|
130
|
+
|
|
131
|
+
# Route a task to best agent
|
|
132
|
+
npx ruvector hooks route "implement user login"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Hook Events
|
|
136
|
+
|
|
137
|
+
| Event | Trigger | RuVector Action |
|
|
138
|
+
|-------|---------|-----------------|
|
|
139
|
+
| **PreToolUse** | Before Edit/Write/Bash | Agent routing, file analysis, command risk |
|
|
140
|
+
| **PostToolUse** | After Edit/Write/Bash | Q-learning update, pattern recording |
|
|
141
|
+
| **SessionStart** | Conversation begins | Load intelligence, display stats |
|
|
142
|
+
| **Stop** | Conversation ends | Save learning data |
|
|
143
|
+
| **UserPromptSubmit** | User sends message | Context suggestions |
|
|
144
|
+
| **PreCompact** | Before context compaction | Preserve important context |
|
|
145
|
+
| **Notification** | Any notification | Track events for learning |
|
|
146
|
+
|
|
147
|
+
## Generated Files
|
|
148
|
+
|
|
149
|
+
After running `hooks init`:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
your-project/
|
|
153
|
+
├── .claude/
|
|
154
|
+
│ ├── settings.json # Hooks configuration
|
|
155
|
+
│ ├── statusline.sh # Status bar script
|
|
156
|
+
│ └── agents/ # Generated agents (with --build-agents)
|
|
157
|
+
│ ├── rust-specialist.yaml
|
|
158
|
+
│ ├── typescript-specialist.yaml
|
|
159
|
+
│ ├── test-architect.yaml
|
|
160
|
+
│ └── project-coordinator.yaml
|
|
161
|
+
├── .ruvector/
|
|
162
|
+
│ └── intelligence.json # Learning data
|
|
163
|
+
├── CLAUDE.md # Project documentation
|
|
164
|
+
└── .gitignore # Updated with .ruvector/
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Environment Variables
|
|
168
|
+
|
|
169
|
+
| Variable | Default | Description |
|
|
170
|
+
|----------|---------|-------------|
|
|
171
|
+
| `RUVECTOR_INTELLIGENCE_ENABLED` | `true` | Enable/disable intelligence |
|
|
172
|
+
| `RUVECTOR_LEARNING_RATE` | `0.1` | Q-learning rate (0.0-1.0) |
|
|
173
|
+
| `RUVECTOR_MEMORY_BACKEND` | `rvlite` | Memory storage backend |
|
|
174
|
+
| `INTELLIGENCE_MODE` | `treatment` | A/B testing mode |
|
|
175
|
+
|
|
176
|
+
## Example Output
|
|
177
|
+
|
|
178
|
+
### Agent Routing
|
|
179
|
+
```
|
|
180
|
+
🧠 Intelligence Analysis:
|
|
181
|
+
📁 src/api/routes.ts
|
|
182
|
+
🤖 Recommended: typescript-developer (85% confidence)
|
|
183
|
+
→ learned from 127 .ts files in repo
|
|
184
|
+
📎 Likely next files:
|
|
185
|
+
- src/api/handlers.ts (12 co-edits)
|
|
186
|
+
- src/types/api.ts (8 co-edits)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Command Analysis
|
|
190
|
+
```
|
|
191
|
+
🧠 Command Analysis:
|
|
192
|
+
📦 Category: rust
|
|
193
|
+
🏷️ Type: test
|
|
194
|
+
✅ Risk: LOW
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Best Practices
|
|
198
|
+
|
|
199
|
+
1. **Run pretrain on existing repos** — Bootstrap intelligence before starting work
|
|
200
|
+
2. **Use focus modes** — Match agent generation to your current task
|
|
201
|
+
3. **Export before major changes** — Backup learning data
|
|
202
|
+
4. **Let it learn** — Intelligence improves with each edit
|
|
203
|
+
|
|
204
|
+
## Troubleshooting
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# Check setup
|
|
208
|
+
npx ruvector hooks verify
|
|
209
|
+
|
|
210
|
+
# Fix common issues
|
|
211
|
+
npx ruvector hooks doctor --fix
|
|
212
|
+
|
|
213
|
+
# Reset and reinitialize
|
|
214
|
+
npx ruvector hooks init --force --pretrain
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Links
|
|
218
|
+
|
|
219
|
+
- [RuVector GitHub](https://github.com/ruvnet/ruvector)
|
|
220
|
+
- [npm Package](https://www.npmjs.com/package/ruvector)
|
|
221
|
+
- [Claude Code Documentation](https://docs.anthropic.com/claude-code)
|
package/README.md
CHANGED
|
@@ -20,6 +20,26 @@ Built by [rUv](https://ruv.io) with production-grade Rust performance and intell
|
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
+
## 🧠 Claude Code Hooks (NEW)
|
|
24
|
+
|
|
25
|
+
**Self-learning intelligence for Claude Code** — RuVector provides optimized hooks that learn from your development patterns.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# One-command setup with pretrain and agent generation
|
|
29
|
+
npx ruvector hooks init --pretrain --build-agents quality
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Features:**
|
|
33
|
+
- 🎯 **Smart Agent Routing** — Automatically suggests the best agent for each file type
|
|
34
|
+
- 📚 **Repository Pretrain** — Analyzes your codebase to bootstrap intelligence
|
|
35
|
+
- 🤖 **Agent Builder** — Generates optimized `.claude/agents/` configs for your stack
|
|
36
|
+
- 🔗 **Co-edit Patterns** — Learns which files are edited together from git history
|
|
37
|
+
- 💾 **Vector Memory** — Semantic recall of project context
|
|
38
|
+
|
|
39
|
+
📖 **[Full Hooks Documentation →](https://github.com/ruvnet/ruvector/blob/main/npm/packages/ruvector/HOOKS.md)**
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
23
43
|
## 🌟 Why Ruvector?
|
|
24
44
|
|
|
25
45
|
### The Problem with Existing Vector Databases
|
package/bin/cli.js
CHANGED
|
@@ -3628,4 +3628,59 @@ ${focus.description}` : null
|
|
|
3628
3628
|
console.log(chalk.dim(`\nFocus mode "${opts.focus}": ${focus.description}`));
|
|
3629
3629
|
});
|
|
3630
3630
|
|
|
3631
|
+
// MCP Server command
|
|
3632
|
+
const mcpCmd = program.command('mcp').description('MCP (Model Context Protocol) server for Claude Code integration');
|
|
3633
|
+
|
|
3634
|
+
mcpCmd.command('start')
|
|
3635
|
+
.description('Start the RuVector MCP server')
|
|
3636
|
+
.action(() => {
|
|
3637
|
+
// Execute the mcp-server.js directly
|
|
3638
|
+
const mcpServerPath = path.join(__dirname, 'mcp-server.js');
|
|
3639
|
+
if (!fs.existsSync(mcpServerPath)) {
|
|
3640
|
+
console.error(chalk.red('Error: MCP server not found at'), mcpServerPath);
|
|
3641
|
+
process.exit(1);
|
|
3642
|
+
}
|
|
3643
|
+
require(mcpServerPath);
|
|
3644
|
+
});
|
|
3645
|
+
|
|
3646
|
+
mcpCmd.command('info')
|
|
3647
|
+
.description('Show MCP server information and setup instructions')
|
|
3648
|
+
.action(() => {
|
|
3649
|
+
console.log(chalk.bold.cyan('\n🔌 RuVector MCP Server\n'));
|
|
3650
|
+
console.log(chalk.white('The RuVector MCP server provides self-learning intelligence'));
|
|
3651
|
+
console.log(chalk.white('tools to Claude Code via the Model Context Protocol.\n'));
|
|
3652
|
+
|
|
3653
|
+
console.log(chalk.bold('Available Tools:'));
|
|
3654
|
+
console.log(chalk.dim(' hooks_stats - Get intelligence statistics'));
|
|
3655
|
+
console.log(chalk.dim(' hooks_route - Route task to best agent'));
|
|
3656
|
+
console.log(chalk.dim(' hooks_remember - Store context in vector memory'));
|
|
3657
|
+
console.log(chalk.dim(' hooks_recall - Search vector memory'));
|
|
3658
|
+
console.log(chalk.dim(' hooks_init - Initialize hooks in project'));
|
|
3659
|
+
console.log(chalk.dim(' hooks_pretrain - Pretrain from repository'));
|
|
3660
|
+
console.log(chalk.dim(' hooks_build_agents - Generate agent configs'));
|
|
3661
|
+
console.log(chalk.dim(' hooks_verify - Verify hooks configuration'));
|
|
3662
|
+
console.log(chalk.dim(' hooks_doctor - Diagnose setup issues'));
|
|
3663
|
+
console.log(chalk.dim(' hooks_export - Export intelligence data'));
|
|
3664
|
+
|
|
3665
|
+
console.log(chalk.bold('\n📦 Resources:'));
|
|
3666
|
+
console.log(chalk.dim(' ruvector://intelligence/stats - Current statistics'));
|
|
3667
|
+
console.log(chalk.dim(' ruvector://intelligence/patterns - Learned patterns'));
|
|
3668
|
+
console.log(chalk.dim(' ruvector://intelligence/memories - Vector memories'));
|
|
3669
|
+
|
|
3670
|
+
console.log(chalk.bold.yellow('\n⚙️ Setup Instructions:\n'));
|
|
3671
|
+
console.log(chalk.white('Add to Claude Code:'));
|
|
3672
|
+
console.log(chalk.cyan(' claude mcp add ruvector npx ruvector mcp start\n'));
|
|
3673
|
+
|
|
3674
|
+
console.log(chalk.white('Or add to .claude/settings.json:'));
|
|
3675
|
+
console.log(chalk.dim(` {
|
|
3676
|
+
"mcpServers": {
|
|
3677
|
+
"ruvector": {
|
|
3678
|
+
"command": "npx",
|
|
3679
|
+
"args": ["ruvector", "mcp", "start"]
|
|
3680
|
+
}
|
|
3681
|
+
}
|
|
3682
|
+
}`));
|
|
3683
|
+
console.log();
|
|
3684
|
+
});
|
|
3685
|
+
|
|
3631
3686
|
program.parse();
|
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* RuVector MCP Server
|
|
5
|
+
*
|
|
6
|
+
* Model Context Protocol server for RuVector hooks
|
|
7
|
+
* Provides self-learning intelligence tools for Claude Code
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* npx ruvector mcp start
|
|
11
|
+
* claude mcp add ruvector npx ruvector mcp start
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
|
|
15
|
+
const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
16
|
+
const {
|
|
17
|
+
CallToolRequestSchema,
|
|
18
|
+
ListToolsRequestSchema,
|
|
19
|
+
ListResourcesRequestSchema,
|
|
20
|
+
ReadResourceRequestSchema,
|
|
21
|
+
} = require('@modelcontextprotocol/sdk/types.js');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const fs = require('fs');
|
|
24
|
+
const { execSync } = require('child_process');
|
|
25
|
+
|
|
26
|
+
// Intelligence class (simplified from cli.js)
|
|
27
|
+
class Intelligence {
|
|
28
|
+
constructor() {
|
|
29
|
+
this.intelPath = this.getIntelPath();
|
|
30
|
+
this.data = this.load();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
getIntelPath() {
|
|
34
|
+
const projectPath = path.join(process.cwd(), '.ruvector', 'intelligence.json');
|
|
35
|
+
const homePath = path.join(require('os').homedir(), '.ruvector', 'intelligence.json');
|
|
36
|
+
if (fs.existsSync(path.dirname(projectPath))) return projectPath;
|
|
37
|
+
if (fs.existsSync(path.join(process.cwd(), '.claude'))) return projectPath;
|
|
38
|
+
if (fs.existsSync(homePath)) return homePath;
|
|
39
|
+
return projectPath;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
load() {
|
|
43
|
+
try {
|
|
44
|
+
if (fs.existsSync(this.intelPath)) {
|
|
45
|
+
return JSON.parse(fs.readFileSync(this.intelPath, 'utf-8'));
|
|
46
|
+
}
|
|
47
|
+
} catch {}
|
|
48
|
+
return { patterns: {}, memories: [], trajectories: [], errors: {}, agents: {}, edges: [] };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
save() {
|
|
52
|
+
const dir = path.dirname(this.intelPath);
|
|
53
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
54
|
+
fs.writeFileSync(this.intelPath, JSON.stringify(this.data, null, 2));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
stats() {
|
|
58
|
+
return {
|
|
59
|
+
total_patterns: Object.keys(this.data.patterns || {}).length,
|
|
60
|
+
total_memories: (this.data.memories || []).length,
|
|
61
|
+
total_trajectories: (this.data.trajectories || []).length,
|
|
62
|
+
total_errors: Object.keys(this.data.errors || {}).length
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
embed(text) {
|
|
67
|
+
const embedding = new Array(64).fill(0);
|
|
68
|
+
for (let i = 0; i < text.length; i++) {
|
|
69
|
+
const idx = (text.charCodeAt(i) + i * 7) % 64;
|
|
70
|
+
embedding[idx] += 1.0;
|
|
71
|
+
}
|
|
72
|
+
const norm = Math.sqrt(embedding.reduce((a, b) => a + b * b, 0));
|
|
73
|
+
if (norm > 0) for (let i = 0; i < embedding.length; i++) embedding[i] /= norm;
|
|
74
|
+
return embedding;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
similarity(a, b) {
|
|
78
|
+
if (!a || !b || a.length !== b.length) return 0;
|
|
79
|
+
const dot = a.reduce((sum, v, i) => sum + v * b[i], 0);
|
|
80
|
+
const normA = Math.sqrt(a.reduce((sum, v) => sum + v * v, 0));
|
|
81
|
+
const normB = Math.sqrt(b.reduce((sum, v) => sum + v * v, 0));
|
|
82
|
+
return normA > 0 && normB > 0 ? dot / (normA * normB) : 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
remember(content, type = 'general') {
|
|
86
|
+
this.data.memories = this.data.memories || [];
|
|
87
|
+
this.data.memories.push({
|
|
88
|
+
content,
|
|
89
|
+
type,
|
|
90
|
+
created: new Date().toISOString(),
|
|
91
|
+
embedding: this.embed(content)
|
|
92
|
+
});
|
|
93
|
+
this.save();
|
|
94
|
+
return { stored: true, total: this.data.memories.length };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
recall(query, topK = 5) {
|
|
98
|
+
const queryEmbed = this.embed(query);
|
|
99
|
+
const scored = (this.data.memories || []).map((m, i) => ({
|
|
100
|
+
...m,
|
|
101
|
+
index: i,
|
|
102
|
+
score: this.similarity(queryEmbed, m.embedding)
|
|
103
|
+
}));
|
|
104
|
+
return scored.sort((a, b) => b.score - a.score).slice(0, topK);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
route(task, file = null) {
|
|
108
|
+
const ext = file ? path.extname(file) : '';
|
|
109
|
+
const state = `edit:${ext || 'unknown'}`;
|
|
110
|
+
const actions = this.data.patterns[state] || {};
|
|
111
|
+
|
|
112
|
+
// Default agent mapping
|
|
113
|
+
const defaults = {
|
|
114
|
+
'.rs': 'rust-developer',
|
|
115
|
+
'.ts': 'typescript-developer',
|
|
116
|
+
'.tsx': 'react-developer',
|
|
117
|
+
'.js': 'javascript-developer',
|
|
118
|
+
'.py': 'python-developer',
|
|
119
|
+
'.go': 'go-developer',
|
|
120
|
+
'.sql': 'database-specialist'
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
let bestAgent = defaults[ext] || 'coder';
|
|
124
|
+
let bestScore = 0.5;
|
|
125
|
+
|
|
126
|
+
for (const [agent, score] of Object.entries(actions)) {
|
|
127
|
+
if (score > bestScore) {
|
|
128
|
+
bestAgent = agent;
|
|
129
|
+
bestScore = score;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
agent: bestAgent,
|
|
135
|
+
confidence: Math.min(bestScore, 1.0),
|
|
136
|
+
reason: Object.keys(actions).length > 0 ? 'learned from patterns' : 'default mapping'
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Create MCP server
|
|
142
|
+
const server = new Server(
|
|
143
|
+
{
|
|
144
|
+
name: 'ruvector',
|
|
145
|
+
version: '0.1.51',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
capabilities: {
|
|
149
|
+
tools: {},
|
|
150
|
+
resources: {},
|
|
151
|
+
},
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
const intel = new Intelligence();
|
|
156
|
+
|
|
157
|
+
// Define tools
|
|
158
|
+
const TOOLS = [
|
|
159
|
+
{
|
|
160
|
+
name: 'hooks_stats',
|
|
161
|
+
description: 'Get RuVector intelligence statistics including learned patterns, memories, and trajectories',
|
|
162
|
+
inputSchema: {
|
|
163
|
+
type: 'object',
|
|
164
|
+
properties: {},
|
|
165
|
+
required: []
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: 'hooks_route',
|
|
170
|
+
description: 'Route a task to the best agent based on learned patterns',
|
|
171
|
+
inputSchema: {
|
|
172
|
+
type: 'object',
|
|
173
|
+
properties: {
|
|
174
|
+
task: { type: 'string', description: 'Task description' },
|
|
175
|
+
file: { type: 'string', description: 'File path (optional)' }
|
|
176
|
+
},
|
|
177
|
+
required: ['task']
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: 'hooks_remember',
|
|
182
|
+
description: 'Store context in vector memory for later recall',
|
|
183
|
+
inputSchema: {
|
|
184
|
+
type: 'object',
|
|
185
|
+
properties: {
|
|
186
|
+
content: { type: 'string', description: 'Content to remember' },
|
|
187
|
+
type: { type: 'string', description: 'Memory type (project, code, decision, context)', default: 'general' }
|
|
188
|
+
},
|
|
189
|
+
required: ['content']
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: 'hooks_recall',
|
|
194
|
+
description: 'Search vector memory for relevant context',
|
|
195
|
+
inputSchema: {
|
|
196
|
+
type: 'object',
|
|
197
|
+
properties: {
|
|
198
|
+
query: { type: 'string', description: 'Search query' },
|
|
199
|
+
top_k: { type: 'number', description: 'Number of results', default: 5 }
|
|
200
|
+
},
|
|
201
|
+
required: ['query']
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'hooks_init',
|
|
206
|
+
description: 'Initialize RuVector hooks in the current project',
|
|
207
|
+
inputSchema: {
|
|
208
|
+
type: 'object',
|
|
209
|
+
properties: {
|
|
210
|
+
pretrain: { type: 'boolean', description: 'Run pretrain after init', default: false },
|
|
211
|
+
build_agents: { type: 'string', description: 'Focus for agent generation (quality, speed, security, testing, fullstack)' },
|
|
212
|
+
force: { type: 'boolean', description: 'Force overwrite existing settings', default: false }
|
|
213
|
+
},
|
|
214
|
+
required: []
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: 'hooks_pretrain',
|
|
219
|
+
description: 'Pretrain intelligence by analyzing the repository structure and git history',
|
|
220
|
+
inputSchema: {
|
|
221
|
+
type: 'object',
|
|
222
|
+
properties: {
|
|
223
|
+
depth: { type: 'number', description: 'Git history depth to analyze', default: 100 },
|
|
224
|
+
skip_git: { type: 'boolean', description: 'Skip git history analysis', default: false },
|
|
225
|
+
verbose: { type: 'boolean', description: 'Show detailed progress', default: false }
|
|
226
|
+
},
|
|
227
|
+
required: []
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
name: 'hooks_build_agents',
|
|
232
|
+
description: 'Generate optimized agent configurations based on repository analysis',
|
|
233
|
+
inputSchema: {
|
|
234
|
+
type: 'object',
|
|
235
|
+
properties: {
|
|
236
|
+
focus: {
|
|
237
|
+
type: 'string',
|
|
238
|
+
description: 'Focus type for agent generation',
|
|
239
|
+
enum: ['quality', 'speed', 'security', 'testing', 'fullstack'],
|
|
240
|
+
default: 'quality'
|
|
241
|
+
},
|
|
242
|
+
include_prompts: { type: 'boolean', description: 'Include system prompts in agent configs', default: true }
|
|
243
|
+
},
|
|
244
|
+
required: []
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
name: 'hooks_verify',
|
|
249
|
+
description: 'Verify that hooks are configured correctly',
|
|
250
|
+
inputSchema: {
|
|
251
|
+
type: 'object',
|
|
252
|
+
properties: {},
|
|
253
|
+
required: []
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
name: 'hooks_doctor',
|
|
258
|
+
description: 'Diagnose and optionally fix setup issues',
|
|
259
|
+
inputSchema: {
|
|
260
|
+
type: 'object',
|
|
261
|
+
properties: {
|
|
262
|
+
fix: { type: 'boolean', description: 'Automatically fix issues', default: false }
|
|
263
|
+
},
|
|
264
|
+
required: []
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: 'hooks_export',
|
|
269
|
+
description: 'Export intelligence data for backup',
|
|
270
|
+
inputSchema: {
|
|
271
|
+
type: 'object',
|
|
272
|
+
properties: {
|
|
273
|
+
include_all: { type: 'boolean', description: 'Include all data (patterns, memories, trajectories)', default: false }
|
|
274
|
+
},
|
|
275
|
+
required: []
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
];
|
|
279
|
+
|
|
280
|
+
// List tools handler
|
|
281
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
282
|
+
return { tools: TOOLS };
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
// Call tool handler
|
|
286
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
287
|
+
const { name, arguments: args } = request.params;
|
|
288
|
+
|
|
289
|
+
try {
|
|
290
|
+
switch (name) {
|
|
291
|
+
case 'hooks_stats': {
|
|
292
|
+
const stats = intel.stats();
|
|
293
|
+
return {
|
|
294
|
+
content: [{
|
|
295
|
+
type: 'text',
|
|
296
|
+
text: JSON.stringify({
|
|
297
|
+
success: true,
|
|
298
|
+
stats,
|
|
299
|
+
intel_path: intel.intelPath
|
|
300
|
+
}, null, 2)
|
|
301
|
+
}]
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
case 'hooks_route': {
|
|
306
|
+
const result = intel.route(args.task, args.file);
|
|
307
|
+
return {
|
|
308
|
+
content: [{
|
|
309
|
+
type: 'text',
|
|
310
|
+
text: JSON.stringify({
|
|
311
|
+
success: true,
|
|
312
|
+
task: args.task,
|
|
313
|
+
file: args.file,
|
|
314
|
+
...result
|
|
315
|
+
}, null, 2)
|
|
316
|
+
}]
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
case 'hooks_remember': {
|
|
321
|
+
const result = intel.remember(args.content, args.type || 'general');
|
|
322
|
+
return {
|
|
323
|
+
content: [{
|
|
324
|
+
type: 'text',
|
|
325
|
+
text: JSON.stringify({
|
|
326
|
+
success: true,
|
|
327
|
+
...result
|
|
328
|
+
}, null, 2)
|
|
329
|
+
}]
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
case 'hooks_recall': {
|
|
334
|
+
const results = intel.recall(args.query, args.top_k || 5);
|
|
335
|
+
return {
|
|
336
|
+
content: [{
|
|
337
|
+
type: 'text',
|
|
338
|
+
text: JSON.stringify({
|
|
339
|
+
success: true,
|
|
340
|
+
query: args.query,
|
|
341
|
+
results: results.map(r => ({
|
|
342
|
+
content: r.content,
|
|
343
|
+
type: r.type,
|
|
344
|
+
score: r.score.toFixed(3),
|
|
345
|
+
created: r.created
|
|
346
|
+
}))
|
|
347
|
+
}, null, 2)
|
|
348
|
+
}]
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
case 'hooks_init': {
|
|
353
|
+
let cmd = 'npx ruvector hooks init';
|
|
354
|
+
if (args.force) cmd += ' --force';
|
|
355
|
+
if (args.pretrain) cmd += ' --pretrain';
|
|
356
|
+
if (args.build_agents) cmd += ` --build-agents ${args.build_agents}`;
|
|
357
|
+
|
|
358
|
+
try {
|
|
359
|
+
const output = execSync(cmd, { encoding: 'utf-8', timeout: 60000 });
|
|
360
|
+
return {
|
|
361
|
+
content: [{
|
|
362
|
+
type: 'text',
|
|
363
|
+
text: JSON.stringify({ success: true, output }, null, 2)
|
|
364
|
+
}]
|
|
365
|
+
};
|
|
366
|
+
} catch (e) {
|
|
367
|
+
return {
|
|
368
|
+
content: [{
|
|
369
|
+
type: 'text',
|
|
370
|
+
text: JSON.stringify({ success: false, error: e.message }, null, 2)
|
|
371
|
+
}]
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
case 'hooks_pretrain': {
|
|
377
|
+
let cmd = 'npx ruvector hooks pretrain';
|
|
378
|
+
if (args.depth) cmd += ` --depth ${args.depth}`;
|
|
379
|
+
if (args.skip_git) cmd += ' --skip-git';
|
|
380
|
+
if (args.verbose) cmd += ' --verbose';
|
|
381
|
+
|
|
382
|
+
try {
|
|
383
|
+
const output = execSync(cmd, { encoding: 'utf-8', timeout: 120000 });
|
|
384
|
+
// Reload intelligence after pretrain
|
|
385
|
+
intel.data = intel.load();
|
|
386
|
+
return {
|
|
387
|
+
content: [{
|
|
388
|
+
type: 'text',
|
|
389
|
+
text: JSON.stringify({
|
|
390
|
+
success: true,
|
|
391
|
+
output,
|
|
392
|
+
new_stats: intel.stats()
|
|
393
|
+
}, null, 2)
|
|
394
|
+
}]
|
|
395
|
+
};
|
|
396
|
+
} catch (e) {
|
|
397
|
+
return {
|
|
398
|
+
content: [{
|
|
399
|
+
type: 'text',
|
|
400
|
+
text: JSON.stringify({ success: false, error: e.message }, null, 2)
|
|
401
|
+
}]
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
case 'hooks_build_agents': {
|
|
407
|
+
let cmd = 'npx ruvector hooks build-agents';
|
|
408
|
+
if (args.focus) cmd += ` --focus ${args.focus}`;
|
|
409
|
+
if (args.include_prompts) cmd += ' --include-prompts';
|
|
410
|
+
|
|
411
|
+
try {
|
|
412
|
+
const output = execSync(cmd, { encoding: 'utf-8', timeout: 30000 });
|
|
413
|
+
return {
|
|
414
|
+
content: [{
|
|
415
|
+
type: 'text',
|
|
416
|
+
text: JSON.stringify({ success: true, output }, null, 2)
|
|
417
|
+
}]
|
|
418
|
+
};
|
|
419
|
+
} catch (e) {
|
|
420
|
+
return {
|
|
421
|
+
content: [{
|
|
422
|
+
type: 'text',
|
|
423
|
+
text: JSON.stringify({ success: false, error: e.message }, null, 2)
|
|
424
|
+
}]
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
case 'hooks_verify': {
|
|
430
|
+
try {
|
|
431
|
+
const output = execSync('npx ruvector hooks verify', { encoding: 'utf-8', timeout: 15000 });
|
|
432
|
+
return {
|
|
433
|
+
content: [{
|
|
434
|
+
type: 'text',
|
|
435
|
+
text: JSON.stringify({ success: true, output }, null, 2)
|
|
436
|
+
}]
|
|
437
|
+
};
|
|
438
|
+
} catch (e) {
|
|
439
|
+
return {
|
|
440
|
+
content: [{
|
|
441
|
+
type: 'text',
|
|
442
|
+
text: JSON.stringify({ success: false, error: e.message, output: e.stdout }, null, 2)
|
|
443
|
+
}]
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
case 'hooks_doctor': {
|
|
449
|
+
let cmd = 'npx ruvector hooks doctor';
|
|
450
|
+
if (args.fix) cmd += ' --fix';
|
|
451
|
+
|
|
452
|
+
try {
|
|
453
|
+
const output = execSync(cmd, { encoding: 'utf-8', timeout: 15000 });
|
|
454
|
+
return {
|
|
455
|
+
content: [{
|
|
456
|
+
type: 'text',
|
|
457
|
+
text: JSON.stringify({ success: true, output }, null, 2)
|
|
458
|
+
}]
|
|
459
|
+
};
|
|
460
|
+
} catch (e) {
|
|
461
|
+
return {
|
|
462
|
+
content: [{
|
|
463
|
+
type: 'text',
|
|
464
|
+
text: JSON.stringify({ success: false, error: e.message }, null, 2)
|
|
465
|
+
}]
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
case 'hooks_export': {
|
|
471
|
+
const exportData = {
|
|
472
|
+
version: '1.0',
|
|
473
|
+
exported_at: new Date().toISOString(),
|
|
474
|
+
patterns: intel.data.patterns || {},
|
|
475
|
+
memories: args.include_all ? (intel.data.memories || []) : [],
|
|
476
|
+
trajectories: args.include_all ? (intel.data.trajectories || []) : [],
|
|
477
|
+
errors: intel.data.errors || {},
|
|
478
|
+
stats: intel.stats()
|
|
479
|
+
};
|
|
480
|
+
return {
|
|
481
|
+
content: [{
|
|
482
|
+
type: 'text',
|
|
483
|
+
text: JSON.stringify({ success: true, data: exportData }, null, 2)
|
|
484
|
+
}]
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
default:
|
|
489
|
+
return {
|
|
490
|
+
content: [{
|
|
491
|
+
type: 'text',
|
|
492
|
+
text: JSON.stringify({ success: false, error: `Unknown tool: ${name}` }, null, 2)
|
|
493
|
+
}],
|
|
494
|
+
isError: true
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
} catch (error) {
|
|
498
|
+
return {
|
|
499
|
+
content: [{
|
|
500
|
+
type: 'text',
|
|
501
|
+
text: JSON.stringify({ success: false, error: error.message }, null, 2)
|
|
502
|
+
}],
|
|
503
|
+
isError: true
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
// Resources - expose intelligence data
|
|
509
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
510
|
+
return {
|
|
511
|
+
resources: [
|
|
512
|
+
{
|
|
513
|
+
uri: 'ruvector://intelligence/stats',
|
|
514
|
+
name: 'Intelligence Stats',
|
|
515
|
+
description: 'Current RuVector intelligence statistics',
|
|
516
|
+
mimeType: 'application/json'
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
uri: 'ruvector://intelligence/patterns',
|
|
520
|
+
name: 'Learned Patterns',
|
|
521
|
+
description: 'Q-learning patterns for agent routing',
|
|
522
|
+
mimeType: 'application/json'
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
uri: 'ruvector://intelligence/memories',
|
|
526
|
+
name: 'Vector Memories',
|
|
527
|
+
description: 'Stored context memories',
|
|
528
|
+
mimeType: 'application/json'
|
|
529
|
+
}
|
|
530
|
+
]
|
|
531
|
+
};
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
535
|
+
const { uri } = request.params;
|
|
536
|
+
|
|
537
|
+
switch (uri) {
|
|
538
|
+
case 'ruvector://intelligence/stats':
|
|
539
|
+
return {
|
|
540
|
+
contents: [{
|
|
541
|
+
uri,
|
|
542
|
+
mimeType: 'application/json',
|
|
543
|
+
text: JSON.stringify(intel.stats(), null, 2)
|
|
544
|
+
}]
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
case 'ruvector://intelligence/patterns':
|
|
548
|
+
return {
|
|
549
|
+
contents: [{
|
|
550
|
+
uri,
|
|
551
|
+
mimeType: 'application/json',
|
|
552
|
+
text: JSON.stringify(intel.data.patterns || {}, null, 2)
|
|
553
|
+
}]
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
case 'ruvector://intelligence/memories':
|
|
557
|
+
return {
|
|
558
|
+
contents: [{
|
|
559
|
+
uri,
|
|
560
|
+
mimeType: 'application/json',
|
|
561
|
+
text: JSON.stringify((intel.data.memories || []).map(m => ({
|
|
562
|
+
content: m.content,
|
|
563
|
+
type: m.type,
|
|
564
|
+
created: m.created
|
|
565
|
+
})), null, 2)
|
|
566
|
+
}]
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
default:
|
|
570
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
// Start server
|
|
575
|
+
async function main() {
|
|
576
|
+
const transport = new StdioServerTransport();
|
|
577
|
+
await server.connect(transport);
|
|
578
|
+
console.error('RuVector MCP server running on stdio');
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ruvector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.51",
|
|
4
4
|
"description": "High-performance vector database for Node.js with automatic native/WASM fallback",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"directory": "npm/packages/ruvector"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
55
56
|
"@ruvector/core": "^0.1.25",
|
|
56
57
|
"@ruvector/attention": "^0.1.3",
|
|
57
58
|
"@ruvector/gnn": "^0.1.22",
|