ruvector 0.2.27 → 0.2.29
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/LICENSE +21 -21
- package/README.md +2270 -2270
- package/bin/cli.js +9570 -9479
- package/bin/mcp-server.js +3854 -3854
- package/dist/core/intelligence-engine.d.ts +13 -0
- package/dist/core/intelligence-engine.d.ts.map +1 -1
- package/dist/core/intelligence-engine.js +38 -0
- package/dist/core/onnx/bundled-parallel.mjs +164 -164
- package/dist/core/onnx/embed-worker.mjs +67 -67
- package/dist/core/onnx/loader.js +434 -434
- package/dist/core/onnx/package.json +3 -3
- package/dist/core/onnx/pkg/LICENSE +21 -21
- package/dist/core/onnx/pkg/loader.js +348 -348
- package/dist/core/onnx/pkg/package.json +3 -3
- package/dist/core/onnx/pkg/ruvector_onnx_embeddings_wasm.d.ts +112 -112
- package/dist/core/onnx/pkg/ruvector_onnx_embeddings_wasm.js +5 -5
- package/dist/core/onnx/pkg/ruvector_onnx_embeddings_wasm_bg.js +638 -638
- package/dist/core/onnx/pkg/ruvector_onnx_embeddings_wasm_bg.wasm.d.ts +29 -29
- package/dist/core/onnx-embedder.d.ts.map +1 -1
- package/dist/core/onnx-embedder.js +24 -30
- package/dist/core/parallel-workers.js +439 -439
- package/dist/workers/benchmark.js +15 -15
- package/package.json +122 -122
- package/src/decompiler/api-prober.js +302 -302
- package/src/decompiler/index.js +463 -463
- package/src/decompiler/metrics.js +86 -86
- package/src/decompiler/model-decompiler.js +423 -423
- package/src/decompiler/module-splitter.js +498 -498
- package/src/decompiler/module-tree.js +142 -142
- package/src/decompiler/name-predictor.js +400 -400
- package/src/decompiler/npm-fetch.js +176 -176
- package/src/decompiler/reconstructor.js +499 -499
- package/src/decompiler/reference-tracker.js +285 -285
- package/src/decompiler/statement-parser.js +285 -285
- package/src/decompiler/style-improver.js +438 -438
- package/src/decompiler/subcategories.js +339 -339
- package/src/decompiler/validator.js +379 -379
- package/src/decompiler/witness.js +140 -140
- package/wasm/package.json +26 -26
- package/wasm/ruvector_decompiler_wasm.d.ts +27 -27
- package/wasm/ruvector_decompiler_wasm.js +220 -220
- package/wasm/ruvector_decompiler_wasm_bg.wasm.d.ts +16 -16
- package/dist/core/onnx/pkg/ruvector.db +0 -0
|
@@ -1,142 +1,142 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* module-tree.js - Hierarchical module tree builder.
|
|
3
|
-
*
|
|
4
|
-
* Builds a tree from co-reference density between modules using
|
|
5
|
-
* agglomerative clustering and discriminative token naming.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
'use strict';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Build a hierarchical module tree from co-reference density.
|
|
12
|
-
*
|
|
13
|
-
* 1. Build adjacency matrix from shared string references between modules.
|
|
14
|
-
* 2. Agglomerative clustering by edge density.
|
|
15
|
-
* 3. Name clusters from dominant discriminative strings.
|
|
16
|
-
*
|
|
17
|
-
* @param {Array<{name: string, content: string, fragments: number, confidence: number}>} modules
|
|
18
|
-
* @param {string} source
|
|
19
|
-
* @returns {{name: string, path: string, modules: Array, children: Array, depth: number}}
|
|
20
|
-
*/
|
|
21
|
-
function buildModuleTree(modules, source) {
|
|
22
|
-
if (modules.length <= 1) {
|
|
23
|
-
return {
|
|
24
|
-
name: 'src',
|
|
25
|
-
path: 'src',
|
|
26
|
-
modules,
|
|
27
|
-
children: [],
|
|
28
|
-
depth: 0,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Extract string tokens from each module's content.
|
|
33
|
-
const moduleTokens = modules.map((m) => {
|
|
34
|
-
const tokens = new Set();
|
|
35
|
-
const re = /["']([a-zA-Z_]\w{2,30})["']/g;
|
|
36
|
-
let match;
|
|
37
|
-
while ((match = re.exec(m.content)) !== null) {
|
|
38
|
-
tokens.add(match[1]);
|
|
39
|
-
}
|
|
40
|
-
return tokens;
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// Build adjacency: weight = number of shared tokens.
|
|
44
|
-
const weights = new Map();
|
|
45
|
-
for (let i = 0; i < modules.length; i++) {
|
|
46
|
-
for (let j = i + 1; j < modules.length; j++) {
|
|
47
|
-
let shared = 0;
|
|
48
|
-
for (const tok of moduleTokens[i]) {
|
|
49
|
-
if (moduleTokens[j].has(tok)) shared++;
|
|
50
|
-
}
|
|
51
|
-
if (shared > 0) {
|
|
52
|
-
weights.set(`${i}:${j}`, shared);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Agglomerative clustering.
|
|
58
|
-
let clusters = modules.map((_, i) => [i]);
|
|
59
|
-
|
|
60
|
-
while (clusters.length > 3) {
|
|
61
|
-
let bestI = 0, bestJ = 1, bestW = -1;
|
|
62
|
-
for (let i = 0; i < clusters.length; i++) {
|
|
63
|
-
for (let j = i + 1; j < clusters.length; j++) {
|
|
64
|
-
const w = clusterWeight(clusters[i], clusters[j], weights);
|
|
65
|
-
const norm = w / (clusters[i].length + clusters[j].length);
|
|
66
|
-
if (norm > bestW) {
|
|
67
|
-
bestW = norm;
|
|
68
|
-
bestI = i;
|
|
69
|
-
bestJ = j;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (bestW <= 0) break;
|
|
74
|
-
const merged = [...clusters[bestI], ...clusters[bestJ]];
|
|
75
|
-
clusters.splice(bestJ, 1);
|
|
76
|
-
clusters.splice(bestI, 1);
|
|
77
|
-
clusters.push(merged);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Name each cluster from discriminative tokens.
|
|
81
|
-
const children = clusters.map((group) => {
|
|
82
|
-
const groupModules = group.map((i) => modules[i]);
|
|
83
|
-
const name = inferGroupName(group, moduleTokens, modules);
|
|
84
|
-
return {
|
|
85
|
-
name,
|
|
86
|
-
path: `src/${name}`,
|
|
87
|
-
modules: groupModules,
|
|
88
|
-
children: [],
|
|
89
|
-
depth: 1,
|
|
90
|
-
};
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
return {
|
|
94
|
-
name: 'src',
|
|
95
|
-
path: 'src',
|
|
96
|
-
modules: [],
|
|
97
|
-
children,
|
|
98
|
-
depth: 0,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/** Compute total shared-token weight between two clusters. */
|
|
103
|
-
function clusterWeight(a, b, weights) {
|
|
104
|
-
let total = 0;
|
|
105
|
-
for (const ai of a) {
|
|
106
|
-
for (const bi of b) {
|
|
107
|
-
const key = ai < bi ? `${ai}:${bi}` : `${bi}:${ai}`;
|
|
108
|
-
total += weights.get(key) || 0;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return total;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/** Infer a group name from discriminative tokens. */
|
|
115
|
-
function inferGroupName(group, moduleTokens, modules) {
|
|
116
|
-
const freq = new Map();
|
|
117
|
-
for (const i of group) {
|
|
118
|
-
for (const tok of moduleTokens[i]) {
|
|
119
|
-
freq.set(tok, (freq.get(tok) || 0) + 1);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
const globalFreq = new Map();
|
|
123
|
-
for (const tokens of moduleTokens) {
|
|
124
|
-
for (const tok of tokens) {
|
|
125
|
-
globalFreq.set(tok, (globalFreq.get(tok) || 0) + 1);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
let best = null, bestScore = -1;
|
|
129
|
-
for (const [tok, count] of freq) {
|
|
130
|
-
const global = globalFreq.get(tok) || 0;
|
|
131
|
-
const score = (count / (global + 1)) * Math.log(count + 1);
|
|
132
|
-
if (score > bestScore && tok.length >= 3) {
|
|
133
|
-
bestScore = score;
|
|
134
|
-
best = tok;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
if (best) return best.toLowerCase().replace(/[^a-z0-9_-]/g, '_');
|
|
138
|
-
if (group.length > 0) return modules[group[0]].name;
|
|
139
|
-
return 'group';
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
module.exports = { buildModuleTree };
|
|
1
|
+
/**
|
|
2
|
+
* module-tree.js - Hierarchical module tree builder.
|
|
3
|
+
*
|
|
4
|
+
* Builds a tree from co-reference density between modules using
|
|
5
|
+
* agglomerative clustering and discriminative token naming.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Build a hierarchical module tree from co-reference density.
|
|
12
|
+
*
|
|
13
|
+
* 1. Build adjacency matrix from shared string references between modules.
|
|
14
|
+
* 2. Agglomerative clustering by edge density.
|
|
15
|
+
* 3. Name clusters from dominant discriminative strings.
|
|
16
|
+
*
|
|
17
|
+
* @param {Array<{name: string, content: string, fragments: number, confidence: number}>} modules
|
|
18
|
+
* @param {string} source
|
|
19
|
+
* @returns {{name: string, path: string, modules: Array, children: Array, depth: number}}
|
|
20
|
+
*/
|
|
21
|
+
function buildModuleTree(modules, source) {
|
|
22
|
+
if (modules.length <= 1) {
|
|
23
|
+
return {
|
|
24
|
+
name: 'src',
|
|
25
|
+
path: 'src',
|
|
26
|
+
modules,
|
|
27
|
+
children: [],
|
|
28
|
+
depth: 0,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Extract string tokens from each module's content.
|
|
33
|
+
const moduleTokens = modules.map((m) => {
|
|
34
|
+
const tokens = new Set();
|
|
35
|
+
const re = /["']([a-zA-Z_]\w{2,30})["']/g;
|
|
36
|
+
let match;
|
|
37
|
+
while ((match = re.exec(m.content)) !== null) {
|
|
38
|
+
tokens.add(match[1]);
|
|
39
|
+
}
|
|
40
|
+
return tokens;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Build adjacency: weight = number of shared tokens.
|
|
44
|
+
const weights = new Map();
|
|
45
|
+
for (let i = 0; i < modules.length; i++) {
|
|
46
|
+
for (let j = i + 1; j < modules.length; j++) {
|
|
47
|
+
let shared = 0;
|
|
48
|
+
for (const tok of moduleTokens[i]) {
|
|
49
|
+
if (moduleTokens[j].has(tok)) shared++;
|
|
50
|
+
}
|
|
51
|
+
if (shared > 0) {
|
|
52
|
+
weights.set(`${i}:${j}`, shared);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Agglomerative clustering.
|
|
58
|
+
let clusters = modules.map((_, i) => [i]);
|
|
59
|
+
|
|
60
|
+
while (clusters.length > 3) {
|
|
61
|
+
let bestI = 0, bestJ = 1, bestW = -1;
|
|
62
|
+
for (let i = 0; i < clusters.length; i++) {
|
|
63
|
+
for (let j = i + 1; j < clusters.length; j++) {
|
|
64
|
+
const w = clusterWeight(clusters[i], clusters[j], weights);
|
|
65
|
+
const norm = w / (clusters[i].length + clusters[j].length);
|
|
66
|
+
if (norm > bestW) {
|
|
67
|
+
bestW = norm;
|
|
68
|
+
bestI = i;
|
|
69
|
+
bestJ = j;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (bestW <= 0) break;
|
|
74
|
+
const merged = [...clusters[bestI], ...clusters[bestJ]];
|
|
75
|
+
clusters.splice(bestJ, 1);
|
|
76
|
+
clusters.splice(bestI, 1);
|
|
77
|
+
clusters.push(merged);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Name each cluster from discriminative tokens.
|
|
81
|
+
const children = clusters.map((group) => {
|
|
82
|
+
const groupModules = group.map((i) => modules[i]);
|
|
83
|
+
const name = inferGroupName(group, moduleTokens, modules);
|
|
84
|
+
return {
|
|
85
|
+
name,
|
|
86
|
+
path: `src/${name}`,
|
|
87
|
+
modules: groupModules,
|
|
88
|
+
children: [],
|
|
89
|
+
depth: 1,
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
name: 'src',
|
|
95
|
+
path: 'src',
|
|
96
|
+
modules: [],
|
|
97
|
+
children,
|
|
98
|
+
depth: 0,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Compute total shared-token weight between two clusters. */
|
|
103
|
+
function clusterWeight(a, b, weights) {
|
|
104
|
+
let total = 0;
|
|
105
|
+
for (const ai of a) {
|
|
106
|
+
for (const bi of b) {
|
|
107
|
+
const key = ai < bi ? `${ai}:${bi}` : `${bi}:${ai}`;
|
|
108
|
+
total += weights.get(key) || 0;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return total;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Infer a group name from discriminative tokens. */
|
|
115
|
+
function inferGroupName(group, moduleTokens, modules) {
|
|
116
|
+
const freq = new Map();
|
|
117
|
+
for (const i of group) {
|
|
118
|
+
for (const tok of moduleTokens[i]) {
|
|
119
|
+
freq.set(tok, (freq.get(tok) || 0) + 1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const globalFreq = new Map();
|
|
123
|
+
for (const tokens of moduleTokens) {
|
|
124
|
+
for (const tok of tokens) {
|
|
125
|
+
globalFreq.set(tok, (globalFreq.get(tok) || 0) + 1);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
let best = null, bestScore = -1;
|
|
129
|
+
for (const [tok, count] of freq) {
|
|
130
|
+
const global = globalFreq.get(tok) || 0;
|
|
131
|
+
const score = (count / (global + 1)) * Math.log(count + 1);
|
|
132
|
+
if (score > bestScore && tok.length >= 3) {
|
|
133
|
+
bestScore = score;
|
|
134
|
+
best = tok;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (best) return best.toLowerCase().replace(/[^a-z0-9_-]/g, '_');
|
|
138
|
+
if (group.length > 0) return modules[group[0]].name;
|
|
139
|
+
return 'group';
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
module.exports = { buildModuleTree };
|