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 CHANGED
@@ -1,10 +1,16 @@
1
- Updated: 2026-01-02 11:15:00 EST | Version 6.3.0
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-KB-First Application Builder v6.3.0
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
  [![npm version](https://img.shields.io/npm/v/ruvnet-kb-first.svg)](https://www.npmjs.com/package/ruvnet-kb-first)
9
15
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
@@ -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: 62117666416c8c6e
8
- * Generated: 2026-01-02T18:51:15.858Z
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, pathToFileURL } from 'url';
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
- // Get the wasm file path
26
- const rvlitePath = path.dirname(fileURLToPath(import.meta.resolve('@ruvector/edge-full/rvlite')));
27
- const wasmPath = path.join(rvlitePath, 'rvlite_bg.wasm');
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: '62117666416c8c6e',
48
- exportedAt: '2026-01-02T18:51:15.858Z',
62
+ hash: '004c720e1d38de27',
63
+ exportedAt: '2026-01-02T18:55:18.300Z',
49
64
  totalEntries: 17524,
50
65
  embeddingDim: 384,
51
66
  quantization: 'binary',
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "1.0.0",
3
3
  "schema": "ask_ruvnet",
4
- "exportedAt": "2026-01-02T18:51:15.858Z",
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": "62117666416c8c6e"
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.1",
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 --experimental-vm-modules node_modules/jest/bin/jest.js",
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.43",
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.82"
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
- metadata.contentHash = crypto.createHash('sha256').update(hashInput).digest('hex').substring(0, 16);
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