ruvnet-kb-first 6.5.1 → 6.5.3
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/README.md +54 -2
- package/kb-data/kb-loader.js +23 -8
- package/kb-data/kb-metadata.json +2 -2
- package/package.json +6 -4
- package/scripts/kb-export-wasm.js +7 -6
package/README.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
Updated: 2026-01-02
|
|
1
|
+
Updated: 2026-01-02 14:00:00 EST | Version 6.5.2
|
|
2
2
|
Created: 2026-01-01 15:28:53 EST
|
|
3
3
|
|
|
4
|
-
# RuvNet
|
|
4
|
+
# RuvNet KB-First Application Builder v6.5.2
|
|
5
5
|
|
|
6
6
|
## Build Intelligent Applications on Expert Knowledge
|
|
7
7
|
|
|
8
|
+
### NEW in v6.5: Embedded WASM Knowledge Base
|
|
9
|
+
- **17,524 entries** embedded directly in the npm package
|
|
10
|
+
- **Zero infrastructure** - works offline, no PostgreSQL required
|
|
11
|
+
- **15-30ms search latency** (1,340x faster than PostgreSQL)
|
|
12
|
+
- **Auto-update detection** - knows when KB needs refresh
|
|
13
|
+
|
|
8
14
|
[](https://www.npmjs.com/package/ruvnet-kb-first)
|
|
9
15
|
[](https://opensource.org/licenses/MIT)
|
|
10
16
|
|
|
@@ -71,6 +77,49 @@ npx ruvnet-kb-first init
|
|
|
71
77
|
|
|
72
78
|
---
|
|
73
79
|
|
|
80
|
+
## Embedded WASM Knowledge Base (NEW in v6.5)
|
|
81
|
+
|
|
82
|
+
The npm package now includes an **embedded WASM-based knowledge base** with 17,524 entries. This means you can use the KB without any infrastructure:
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
import { loadKB, search, checkForUpdates } from 'ruvnet-kb-first/kb-data/kb-loader.js';
|
|
86
|
+
|
|
87
|
+
// Load KB (once, ~400ms)
|
|
88
|
+
await loadKB();
|
|
89
|
+
|
|
90
|
+
// Search (15-30ms per query)
|
|
91
|
+
const results = await search('how to create agents', 5);
|
|
92
|
+
|
|
93
|
+
// Check if KB needs update
|
|
94
|
+
const status = await checkForUpdates();
|
|
95
|
+
if (status.needsUpdate) {
|
|
96
|
+
console.log('Run: npm update ruvnet-kb-first');
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### WASM KB vs PostgreSQL
|
|
101
|
+
|
|
102
|
+
| Feature | WASM KB | PostgreSQL KB |
|
|
103
|
+
|---------|---------|---------------|
|
|
104
|
+
| Entries | 17,524 | 230,000+ |
|
|
105
|
+
| Setup | None | Docker required |
|
|
106
|
+
| Search latency | 15-30ms | ~6,700ms |
|
|
107
|
+
| Works offline | ✓ | ✗ |
|
|
108
|
+
| Auto-updates | npm update | Docker pull |
|
|
109
|
+
|
|
110
|
+
### Update Workflow
|
|
111
|
+
|
|
112
|
+
When the PostgreSQL KB is updated:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npm run kb:export # Re-export WASM with new data
|
|
116
|
+
npm test # Verify 43 tests pass
|
|
117
|
+
npm version patch # Bump version
|
|
118
|
+
npm publish # Publish to npm
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
74
123
|
## Three-Tier Knowledge Base System
|
|
75
124
|
|
|
76
125
|
RuvNet-KB-First uses a tiered approach to ensure it works for everyone:
|
|
@@ -122,9 +171,12 @@ RuvNet-KB-First uses a tiered approach to ensure it works for everyone:
|
|
|
122
171
|
| Tier | Requirements | Entries | Features |
|
|
123
172
|
|------|--------------|---------|----------|
|
|
124
173
|
| **Full** | Docker + ruvector-postgres | 230K+ | All features: semantic search, citations, gap detection |
|
|
174
|
+
| **WASM** (NEW) | None (npm package) | 17,524 | Embedded KB, 15-30ms search, offline capable |
|
|
125
175
|
| **Starter** | None (bundled SQLite) | 500 | Core patterns, basic semantic search |
|
|
126
176
|
| **Structural** | None | 0 | Directory scoring, phase tracking, hooks only |
|
|
127
177
|
|
|
178
|
+
**v6.5 Default:** The WASM KB is now the automatic fallback when PostgreSQL is unavailable.
|
|
179
|
+
|
|
128
180
|
---
|
|
129
181
|
|
|
130
182
|
## What You See
|
package/kb-data/kb-loader.js
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
* Loads the embedded knowledge base into RvLite WASM.
|
|
5
5
|
* Provides semantic search with ~5ms latency.
|
|
6
6
|
*
|
|
7
|
-
* Content Hash:
|
|
8
|
-
* Generated: 2026-01-02T18:
|
|
7
|
+
* Content Hash: 004c720e1d38de27
|
|
8
|
+
* Generated: 2026-01-02T18:55:18.300Z
|
|
9
9
|
* Entries: 17,524
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import fs from 'fs';
|
|
13
13
|
import path from 'path';
|
|
14
|
-
import { fileURLToPath
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
15
15
|
|
|
16
16
|
// Initialize WASM on first import
|
|
17
17
|
let wasmInitialized = false;
|
|
@@ -22,9 +22,24 @@ async function ensureWasmInit() {
|
|
|
22
22
|
// Dynamic import to get the init function
|
|
23
23
|
const rvliteModule = await import('@ruvector/edge-full/rvlite');
|
|
24
24
|
|
|
25
|
-
//
|
|
26
|
-
const
|
|
27
|
-
|
|
25
|
+
// Find the WASM file by walking up from this file to find node_modules
|
|
26
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
27
|
+
let searchDir = __dirname;
|
|
28
|
+
let wasmPath = null;
|
|
29
|
+
|
|
30
|
+
// Search for node_modules in parent directories
|
|
31
|
+
while (searchDir !== path.dirname(searchDir)) {
|
|
32
|
+
const candidatePath = path.join(searchDir, 'node_modules', '@ruvector', 'edge-full', 'rvlite', 'rvlite_bg.wasm');
|
|
33
|
+
if (fs.existsSync(candidatePath)) {
|
|
34
|
+
wasmPath = candidatePath;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
searchDir = path.dirname(searchDir);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!wasmPath) {
|
|
41
|
+
throw new Error('Could not find rvlite_bg.wasm in node_modules');
|
|
42
|
+
}
|
|
28
43
|
|
|
29
44
|
// Read the wasm file and pass as buffer (Node.js compatible)
|
|
30
45
|
const wasmBuffer = fs.readFileSync(wasmPath);
|
|
@@ -44,8 +59,8 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
44
59
|
|
|
45
60
|
// KB Version Info
|
|
46
61
|
export const KB_VERSION = {
|
|
47
|
-
hash: '
|
|
48
|
-
exportedAt: '2026-01-02T18:
|
|
62
|
+
hash: '004c720e1d38de27',
|
|
63
|
+
exportedAt: '2026-01-02T18:55:18.300Z',
|
|
49
64
|
totalEntries: 17524,
|
|
50
65
|
embeddingDim: 384,
|
|
51
66
|
quantization: 'binary',
|
package/kb-data/kb-metadata.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.0.0",
|
|
3
3
|
"schema": "ask_ruvnet",
|
|
4
|
-
"exportedAt": "2026-01-02T18:
|
|
4
|
+
"exportedAt": "2026-01-02T18:55:18.300Z",
|
|
5
5
|
"totalEntries": 17524,
|
|
6
6
|
"embeddingDim": 384,
|
|
7
7
|
"quantization": "binary",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"count": 14
|
|
68
68
|
}
|
|
69
69
|
],
|
|
70
|
-
"contentHash": "
|
|
70
|
+
"contentHash": "004c720e1d38de27"
|
|
71
71
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ruvnet-kb-first",
|
|
3
|
-
"version": "6.5.
|
|
3
|
+
"version": "6.5.3",
|
|
4
4
|
"description": "RuvNet KB-First Application Builder - Build intelligent applications on expert knowledge",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -13,12 +13,14 @@
|
|
|
13
13
|
"dev": "tsc --watch",
|
|
14
14
|
"start": "node bin/kb-first.js",
|
|
15
15
|
"mcp": "node src/mcp-server.js",
|
|
16
|
-
"test": "node
|
|
16
|
+
"test": "node tests/run-wasm-tests.js",
|
|
17
|
+
"test:wasm": "node tests/run-wasm-tests.js",
|
|
17
18
|
"lint": "eslint src/ templates/",
|
|
18
19
|
"kb:init": "node bin/kb-first.js init",
|
|
19
20
|
"kb:score": "node bin/kb-first.js score",
|
|
20
21
|
"kb:verify": "node bin/kb-first.js verify",
|
|
21
22
|
"kb:status": "node bin/kb-first.js status",
|
|
23
|
+
"kb:export": "node scripts/kb-export-wasm.js --schema ask_ruvnet --output kb-data/",
|
|
22
24
|
"prepublishOnly": "echo 'Publishing ruvnet-kb-first...'"
|
|
23
25
|
},
|
|
24
26
|
"keywords": [
|
|
@@ -49,7 +51,7 @@
|
|
|
49
51
|
},
|
|
50
52
|
"dependencies": {
|
|
51
53
|
"@ruvector/edge-full": "^0.1.0",
|
|
52
|
-
"agentic-flow": "^2.0.1-alpha.
|
|
54
|
+
"agentic-flow": "^2.0.1-alpha.50",
|
|
53
55
|
"chalk": "^5.3.0",
|
|
54
56
|
"claude-flow": "^2.7.47",
|
|
55
57
|
"commander": "^12.0.0",
|
|
@@ -59,7 +61,7 @@
|
|
|
59
61
|
"ora": "^8.0.0",
|
|
60
62
|
"pg": "^8.16.3",
|
|
61
63
|
"ruv-swarm": "^1.0.20",
|
|
62
|
-
"ruvector": "^0.1.
|
|
64
|
+
"ruvector": "^0.1.94"
|
|
63
65
|
},
|
|
64
66
|
"devDependencies": {
|
|
65
67
|
"@types/jest": "^29.5.11",
|
|
@@ -122,7 +122,6 @@ async function exportKB(schema, outputDir) {
|
|
|
122
122
|
const entries = [];
|
|
123
123
|
const embeddings = [];
|
|
124
124
|
let offset = 0;
|
|
125
|
-
let hashInput = '';
|
|
126
125
|
|
|
127
126
|
console.log(`\n Exporting chunks...`);
|
|
128
127
|
|
|
@@ -155,9 +154,6 @@ async function exportKB(schema, outputDir) {
|
|
|
155
154
|
} else {
|
|
156
155
|
embeddings.push(new Float32Array(embeddingArray));
|
|
157
156
|
}
|
|
158
|
-
|
|
159
|
-
// Add to hash input
|
|
160
|
-
hashInput += `${row.id}:${row.title}:${row.category}|`;
|
|
161
157
|
}
|
|
162
158
|
|
|
163
159
|
offset += CONFIG.export.chunkSize;
|
|
@@ -167,8 +163,13 @@ async function exportKB(schema, outputDir) {
|
|
|
167
163
|
|
|
168
164
|
console.log('\n');
|
|
169
165
|
|
|
170
|
-
// Compute content hash
|
|
171
|
-
|
|
166
|
+
// Compute content hash using MD5 (matches PostgreSQL checkForUpdates query)
|
|
167
|
+
const hashResult = await client.query(`
|
|
168
|
+
SELECT MD5(STRING_AGG(id::text || ':' || title || ':' || category, '|' ORDER BY id))::text as hash
|
|
169
|
+
FROM ${schema}.architecture_docs
|
|
170
|
+
WHERE embedding IS NOT NULL AND is_duplicate = false
|
|
171
|
+
`);
|
|
172
|
+
metadata.contentHash = hashResult.rows[0]?.hash?.substring(0, 16) || 'unknown';
|
|
172
173
|
console.log(` Content Hash: ${metadata.contentHash}`);
|
|
173
174
|
|
|
174
175
|
// Write metadata
|