ruvector 0.2.19 → 0.2.20
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/bin/cli.js +139 -0
- package/bin/mcp-server.js +269 -0
- package/package.json +14 -6
- package/src/decompiler/index.js +407 -0
- package/src/decompiler/metrics.js +86 -0
- package/src/decompiler/module-splitter.js +498 -0
- package/src/decompiler/module-tree.js +142 -0
- package/src/decompiler/name-predictor.js +400 -0
- package/src/decompiler/npm-fetch.js +176 -0
- package/src/decompiler/reconstructor.js +499 -0
- package/src/decompiler/reference-tracker.js +285 -0
- package/src/decompiler/statement-parser.js +285 -0
- package/src/decompiler/style-improver.js +438 -0
- package/src/decompiler/subcategories.js +339 -0
- package/src/decompiler/validator.js +379 -0
- package/src/decompiler/witness.js +140 -0
package/bin/cli.js
CHANGED
|
@@ -8923,5 +8923,144 @@ routeCmd.command('info')
|
|
|
8923
8923
|
console.log('');
|
|
8924
8924
|
});
|
|
8925
8925
|
|
|
8926
|
+
// ── Decompile Command ──────────────────────────────────────────────────────
|
|
8927
|
+
const decompileCmd = program
|
|
8928
|
+
.command('decompile [target]')
|
|
8929
|
+
.description('Decompile npm packages, local JS files, or URLs into modules')
|
|
8930
|
+
.option('-o, --output <dir>', 'Output directory')
|
|
8931
|
+
.option('-f, --format <type>', 'Output format: modules, single, json', 'modules')
|
|
8932
|
+
.option('-c, --confidence <n>', 'Minimum confidence threshold (0-1)', '0.3')
|
|
8933
|
+
.option('--no-witness', 'Skip witness chain generation')
|
|
8934
|
+
.option('--json', 'JSON output to stdout (for piping)')
|
|
8935
|
+
.option('-q, --quiet', 'Suppress progress output')
|
|
8936
|
+
.option('--version-pkg <ver>', 'Package version (alternative to @version syntax)')
|
|
8937
|
+
.option('--diff <version>', 'Compare against another version')
|
|
8938
|
+
.action(async (target, opts) => {
|
|
8939
|
+
if (!target) {
|
|
8940
|
+
console.log(chalk.cyan('\nUsage:'));
|
|
8941
|
+
console.log(chalk.white(' ruvector decompile <package> Decompile npm package'));
|
|
8942
|
+
console.log(chalk.white(' ruvector decompile <pkg>@<ver> Specific version'));
|
|
8943
|
+
console.log(chalk.white(' ruvector decompile ./bundle.js Local file'));
|
|
8944
|
+
console.log(chalk.white(' ruvector decompile https://unpkg.com/x URL'));
|
|
8945
|
+
console.log(chalk.dim('\nOptions:'));
|
|
8946
|
+
console.log(chalk.dim(' -o, --output <dir> Output directory'));
|
|
8947
|
+
console.log(chalk.dim(' -f, --format <type> modules | single | json'));
|
|
8948
|
+
console.log(chalk.dim(' -c, --confidence <n> Min confidence (0-1, default: 0.3)'));
|
|
8949
|
+
console.log(chalk.dim(' --no-witness Skip witness chain'));
|
|
8950
|
+
console.log(chalk.dim(' --json JSON to stdout'));
|
|
8951
|
+
console.log(chalk.dim(' --diff <version> Diff against another version'));
|
|
8952
|
+
console.log('');
|
|
8953
|
+
return;
|
|
8954
|
+
}
|
|
8955
|
+
|
|
8956
|
+
const decompiler = require('../src/decompiler/index.js');
|
|
8957
|
+
const { parseTarget } = decompiler;
|
|
8958
|
+
const parsed = parseTarget(target);
|
|
8959
|
+
const minConfidence = parseFloat(opts.confidence);
|
|
8960
|
+
const decompileOpts = { minConfidence, witness: opts.witness !== false, useRust: true };
|
|
8961
|
+
const quiet = opts.quiet || opts.json;
|
|
8962
|
+
let spinner = null;
|
|
8963
|
+
|
|
8964
|
+
if (!quiet) {
|
|
8965
|
+
spinner = ora('Analyzing target...').start();
|
|
8966
|
+
}
|
|
8967
|
+
|
|
8968
|
+
try {
|
|
8969
|
+
let result;
|
|
8970
|
+
|
|
8971
|
+
if (parsed.type === 'npm') {
|
|
8972
|
+
const version = opts.versionPkg || parsed.version;
|
|
8973
|
+
if (!quiet) spinner.text = `Fetching ${parsed.name}${version ? '@' + version : ''}...`;
|
|
8974
|
+
result = await decompiler.decompilePackage(parsed.name, version, decompileOpts);
|
|
8975
|
+
if (!quiet) spinner.text = `Decompiled ${result.packageInfo.name}@${result.packageInfo.version}`;
|
|
8976
|
+
} else if (parsed.type === 'file') {
|
|
8977
|
+
if (!quiet) spinner.text = `Reading ${parsed.path}...`;
|
|
8978
|
+
result = decompiler.decompileFile(parsed.path, { ...decompileOpts, filePath: parsed.path });
|
|
8979
|
+
} else if (parsed.type === 'url') {
|
|
8980
|
+
if (!quiet) spinner.text = `Fetching ${parsed.url}...`;
|
|
8981
|
+
result = await decompiler.decompileUrl(parsed.url, decompileOpts);
|
|
8982
|
+
}
|
|
8983
|
+
|
|
8984
|
+
if (!quiet) spinner.succeed(chalk.green('Decompilation complete'));
|
|
8985
|
+
|
|
8986
|
+
// Handle --diff flag
|
|
8987
|
+
if (opts.diff && parsed.type === 'npm') {
|
|
8988
|
+
if (!quiet) {
|
|
8989
|
+
const diffSpinner = ora(`Fetching ${parsed.name}@${opts.diff} for diff...`).start();
|
|
8990
|
+
try {
|
|
8991
|
+
const other = await decompiler.decompilePackage(parsed.name, opts.diff, decompileOpts);
|
|
8992
|
+
diffSpinner.succeed('Diff complete');
|
|
8993
|
+
const resultNames = new Set(result.modules.map((m) => m.name));
|
|
8994
|
+
const otherNames = new Set(other.modules.map((m) => m.name));
|
|
8995
|
+
const added = [...resultNames].filter((n) => !otherNames.has(n));
|
|
8996
|
+
const removed = [...otherNames].filter((n) => !resultNames.has(n));
|
|
8997
|
+
const common = [...resultNames].filter((n) => otherNames.has(n));
|
|
8998
|
+
|
|
8999
|
+
console.log(chalk.bold.cyan('\n Version Diff'));
|
|
9000
|
+
console.log(chalk.white(` ${opts.diff} -> ${result.packageInfo.version}`));
|
|
9001
|
+
if (added.length) console.log(chalk.green(` Added: ${added.join(', ')}`));
|
|
9002
|
+
if (removed.length) console.log(chalk.red(` Removed: ${removed.join(', ')}`));
|
|
9003
|
+
console.log(chalk.dim(` Common: ${common.length} modules`));
|
|
9004
|
+
console.log('');
|
|
9005
|
+
} catch (err) {
|
|
9006
|
+
diffSpinner.fail(`Diff failed: ${err.message}`);
|
|
9007
|
+
}
|
|
9008
|
+
}
|
|
9009
|
+
}
|
|
9010
|
+
|
|
9011
|
+
// Output
|
|
9012
|
+
if (opts.json) {
|
|
9013
|
+
const jsonOut = {
|
|
9014
|
+
modules: result.modules.map((m) => ({
|
|
9015
|
+
name: m.name, fragments: m.fragments, confidence: m.confidence,
|
|
9016
|
+
contentLength: m.content.length,
|
|
9017
|
+
})),
|
|
9018
|
+
metrics: result.metrics,
|
|
9019
|
+
witness: result.witness ? { root: result.witness.root, chain_length: result.witness.chain.length } : null,
|
|
9020
|
+
packageInfo: result.packageInfo || null,
|
|
9021
|
+
};
|
|
9022
|
+
console.log(JSON.stringify(jsonOut, null, 2));
|
|
9023
|
+
return;
|
|
9024
|
+
}
|
|
9025
|
+
|
|
9026
|
+
// Determine output directory
|
|
9027
|
+
let outputDir = opts.output;
|
|
9028
|
+
if (!outputDir) {
|
|
9029
|
+
const baseName = result.packageInfo
|
|
9030
|
+
? `${result.packageInfo.name.replace('/', '-')}@${result.packageInfo.version}`
|
|
9031
|
+
: path.basename(target, '.js');
|
|
9032
|
+
outputDir = path.join(process.cwd(), 'decompiled', baseName);
|
|
9033
|
+
}
|
|
9034
|
+
|
|
9035
|
+
decompiler.writeOutput(result, outputDir, opts.format);
|
|
9036
|
+
|
|
9037
|
+
console.log(chalk.bold.cyan('\n Decompilation Summary'));
|
|
9038
|
+
console.log(chalk.white(` Modules: ${result.modules.length}`));
|
|
9039
|
+
console.log(chalk.white(` Source size: ${(result.metrics.source.sizeBytes / 1024).toFixed(1)} KB`));
|
|
9040
|
+
console.log(chalk.white(` Functions: ${result.metrics.source.functions}`));
|
|
9041
|
+
console.log(chalk.white(` Classes: ${result.metrics.source.classes}`));
|
|
9042
|
+
if (result.witness) {
|
|
9043
|
+
const wRoot = result.witness.root || result.witness.chain_root || '';
|
|
9044
|
+
console.log(chalk.white(` Witness root: ${wRoot.slice(0, 16)}...`));
|
|
9045
|
+
}
|
|
9046
|
+
console.log(chalk.green(` Output: ${outputDir}`));
|
|
9047
|
+
console.log('');
|
|
9048
|
+
|
|
9049
|
+
if (result.modules.length > 0) {
|
|
9050
|
+
console.log(chalk.dim(' Detected modules:'));
|
|
9051
|
+
for (const mod of result.modules) {
|
|
9052
|
+
const conf = (mod.confidence * 100).toFixed(0);
|
|
9053
|
+
console.log(chalk.dim(` ${mod.name} (${mod.fragments} fragments, ${conf}% confidence)`));
|
|
9054
|
+
}
|
|
9055
|
+
console.log('');
|
|
9056
|
+
}
|
|
9057
|
+
} catch (err) {
|
|
9058
|
+
if (spinner) spinner.fail(chalk.red('Decompilation failed'));
|
|
9059
|
+
console.error(chalk.red(` ${err.message}`));
|
|
9060
|
+
process.exit(1);
|
|
9061
|
+
}
|
|
9062
|
+
});
|
|
9063
|
+
|
|
8926
9064
|
program.parse();
|
|
8927
9065
|
|
|
9066
|
+
|
package/bin/mcp-server.js
CHANGED
|
@@ -1464,6 +1464,84 @@ const TOOLS = [
|
|
|
1464
1464
|
},
|
|
1465
1465
|
required: []
|
|
1466
1466
|
}
|
|
1467
|
+
},
|
|
1468
|
+
|
|
1469
|
+
// ── Decompiler Tools ───────────────────────────────────────────────────
|
|
1470
|
+
{
|
|
1471
|
+
name: 'decompile_package',
|
|
1472
|
+
description: 'Decompile an npm package. Fetches from registry, extracts bundle, splits into modules, computes metrics and witness chain.',
|
|
1473
|
+
inputSchema: {
|
|
1474
|
+
type: 'object',
|
|
1475
|
+
properties: {
|
|
1476
|
+
package: { type: 'string', description: 'npm package name (e.g. "express", "@anthropic-ai/claude-code")' },
|
|
1477
|
+
version: { type: 'string', description: 'Version (default: latest)' },
|
|
1478
|
+
min_confidence: { type: 'number', description: 'Minimum confidence threshold (0-1, default: 0.3)' }
|
|
1479
|
+
},
|
|
1480
|
+
required: ['package']
|
|
1481
|
+
}
|
|
1482
|
+
},
|
|
1483
|
+
{
|
|
1484
|
+
name: 'decompile_file',
|
|
1485
|
+
description: 'Decompile a local JavaScript file. Beautifies, splits into modules, computes metrics.',
|
|
1486
|
+
inputSchema: {
|
|
1487
|
+
type: 'object',
|
|
1488
|
+
properties: {
|
|
1489
|
+
path: { type: 'string', description: 'Path to .js file' },
|
|
1490
|
+
min_confidence: { type: 'number', description: 'Minimum confidence threshold (0-1, default: 0.3)' }
|
|
1491
|
+
},
|
|
1492
|
+
required: ['path']
|
|
1493
|
+
}
|
|
1494
|
+
},
|
|
1495
|
+
{
|
|
1496
|
+
name: 'decompile_url',
|
|
1497
|
+
description: 'Decompile JavaScript from a URL (unpkg, CDN, raw GitHub, etc).',
|
|
1498
|
+
inputSchema: {
|
|
1499
|
+
type: 'object',
|
|
1500
|
+
properties: {
|
|
1501
|
+
url: { type: 'string', description: 'URL to fetch JavaScript from' },
|
|
1502
|
+
min_confidence: { type: 'number', description: 'Minimum confidence threshold (0-1, default: 0.3)' }
|
|
1503
|
+
},
|
|
1504
|
+
required: ['url']
|
|
1505
|
+
}
|
|
1506
|
+
},
|
|
1507
|
+
{
|
|
1508
|
+
name: 'decompile_search',
|
|
1509
|
+
description: 'Search decompiled code for patterns, function names, or string literals.',
|
|
1510
|
+
inputSchema: {
|
|
1511
|
+
type: 'object',
|
|
1512
|
+
properties: {
|
|
1513
|
+
query: { type: 'string', description: 'Search query (regex supported)' },
|
|
1514
|
+
package: { type: 'string', description: 'npm package to decompile and search' },
|
|
1515
|
+
version: { type: 'string', description: 'Package version (default: latest)' },
|
|
1516
|
+
path: { type: 'string', description: 'Local file path to decompile and search (alternative to package)' }
|
|
1517
|
+
},
|
|
1518
|
+
required: ['query']
|
|
1519
|
+
}
|
|
1520
|
+
},
|
|
1521
|
+
{
|
|
1522
|
+
name: 'decompile_diff',
|
|
1523
|
+
description: 'Compare decompiled output between two versions of an npm package. Shows added/removed/changed modules.',
|
|
1524
|
+
inputSchema: {
|
|
1525
|
+
type: 'object',
|
|
1526
|
+
properties: {
|
|
1527
|
+
package: { type: 'string', description: 'npm package name' },
|
|
1528
|
+
version_a: { type: 'string', description: 'First version' },
|
|
1529
|
+
version_b: { type: 'string', description: 'Second version' }
|
|
1530
|
+
},
|
|
1531
|
+
required: ['package', 'version_a', 'version_b']
|
|
1532
|
+
}
|
|
1533
|
+
},
|
|
1534
|
+
{
|
|
1535
|
+
name: 'decompile_witness',
|
|
1536
|
+
description: 'Verify the cryptographic witness chain of a decompilation. Proves output derives faithfully from input.',
|
|
1537
|
+
inputSchema: {
|
|
1538
|
+
type: 'object',
|
|
1539
|
+
properties: {
|
|
1540
|
+
witness_path: { type: 'string', description: 'Path to witness.json file' },
|
|
1541
|
+
source_path: { type: 'string', description: 'Path to original bundle (optional, for source hash verification)' }
|
|
1542
|
+
},
|
|
1543
|
+
required: ['witness_path']
|
|
1544
|
+
}
|
|
1467
1545
|
}
|
|
1468
1546
|
];
|
|
1469
1547
|
|
|
@@ -3417,6 +3495,197 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3417
3495
|
return { content: [{ type: 'text', text: JSON.stringify({ success: true, pseudonym, mcp_token: mcpToken, key_prefix: key.slice(0, 8) + '...' }, null, 2) }] };
|
|
3418
3496
|
}
|
|
3419
3497
|
|
|
3498
|
+
// ── Decompiler Tool Handlers ─────────────────────────────────────────
|
|
3499
|
+
case 'decompile_package': {
|
|
3500
|
+
const decompiler = require('../src/decompiler/index.js');
|
|
3501
|
+
const result = await decompiler.decompilePackage(
|
|
3502
|
+
args.package,
|
|
3503
|
+
args.version || undefined,
|
|
3504
|
+
{ minConfidence: args.min_confidence || 0.3 }
|
|
3505
|
+
);
|
|
3506
|
+
return {
|
|
3507
|
+
content: [{
|
|
3508
|
+
type: 'text',
|
|
3509
|
+
text: JSON.stringify({
|
|
3510
|
+
success: true,
|
|
3511
|
+
packageInfo: result.packageInfo,
|
|
3512
|
+
modules: result.modules.map(m => ({
|
|
3513
|
+
name: m.name, fragments: m.fragments, confidence: m.confidence,
|
|
3514
|
+
contentPreview: m.content.slice(0, 500) + (m.content.length > 500 ? '...' : ''),
|
|
3515
|
+
})),
|
|
3516
|
+
metrics: result.metrics,
|
|
3517
|
+
witness_root: result.witness ? result.witness.root : null,
|
|
3518
|
+
}, null, 2)
|
|
3519
|
+
}]
|
|
3520
|
+
};
|
|
3521
|
+
}
|
|
3522
|
+
|
|
3523
|
+
case 'decompile_file': {
|
|
3524
|
+
const decompiler = require('../src/decompiler/index.js');
|
|
3525
|
+
const safePath = validateRvfPath(args.path);
|
|
3526
|
+
const result = decompiler.decompileFile(safePath, {
|
|
3527
|
+
minConfidence: args.min_confidence || 0.3
|
|
3528
|
+
});
|
|
3529
|
+
return {
|
|
3530
|
+
content: [{
|
|
3531
|
+
type: 'text',
|
|
3532
|
+
text: JSON.stringify({
|
|
3533
|
+
success: true,
|
|
3534
|
+
filePath: result.filePath,
|
|
3535
|
+
modules: result.modules.map(m => ({
|
|
3536
|
+
name: m.name, fragments: m.fragments, confidence: m.confidence,
|
|
3537
|
+
contentPreview: m.content.slice(0, 500) + (m.content.length > 500 ? '...' : ''),
|
|
3538
|
+
})),
|
|
3539
|
+
metrics: result.metrics,
|
|
3540
|
+
witness_root: result.witness ? result.witness.root : null,
|
|
3541
|
+
}, null, 2)
|
|
3542
|
+
}]
|
|
3543
|
+
};
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3546
|
+
case 'decompile_url': {
|
|
3547
|
+
const decompiler = require('../src/decompiler/index.js');
|
|
3548
|
+
const urlStr = args.url;
|
|
3549
|
+
// Basic URL validation
|
|
3550
|
+
if (!urlStr.startsWith('http://') && !urlStr.startsWith('https://')) {
|
|
3551
|
+
throw new Error('URL must start with http:// or https://');
|
|
3552
|
+
}
|
|
3553
|
+
const result = await decompiler.decompileUrl(urlStr, {
|
|
3554
|
+
minConfidence: args.min_confidence || 0.3
|
|
3555
|
+
});
|
|
3556
|
+
return {
|
|
3557
|
+
content: [{
|
|
3558
|
+
type: 'text',
|
|
3559
|
+
text: JSON.stringify({
|
|
3560
|
+
success: true,
|
|
3561
|
+
url: result.url,
|
|
3562
|
+
modules: result.modules.map(m => ({
|
|
3563
|
+
name: m.name, fragments: m.fragments, confidence: m.confidence,
|
|
3564
|
+
contentPreview: m.content.slice(0, 500) + (m.content.length > 500 ? '...' : ''),
|
|
3565
|
+
})),
|
|
3566
|
+
metrics: result.metrics,
|
|
3567
|
+
witness_root: result.witness ? result.witness.root : null,
|
|
3568
|
+
}, null, 2)
|
|
3569
|
+
}]
|
|
3570
|
+
};
|
|
3571
|
+
}
|
|
3572
|
+
|
|
3573
|
+
case 'decompile_search': {
|
|
3574
|
+
const decompiler = require('../src/decompiler/index.js');
|
|
3575
|
+
let result;
|
|
3576
|
+
if (args.path) {
|
|
3577
|
+
const safePath = validateRvfPath(args.path);
|
|
3578
|
+
result = decompiler.decompileFile(safePath);
|
|
3579
|
+
} else if (args.package) {
|
|
3580
|
+
result = await decompiler.decompilePackage(args.package, args.version || undefined);
|
|
3581
|
+
} else {
|
|
3582
|
+
throw new Error('Either "package" or "path" must be provided');
|
|
3583
|
+
}
|
|
3584
|
+
|
|
3585
|
+
const query = args.query;
|
|
3586
|
+
let regex;
|
|
3587
|
+
try { regex = new RegExp(query, 'gi'); } catch { regex = new RegExp(query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gi'); }
|
|
3588
|
+
|
|
3589
|
+
const matches = [];
|
|
3590
|
+
for (const mod of result.modules) {
|
|
3591
|
+
const lines = mod.content.split('\n');
|
|
3592
|
+
for (let i = 0; i < lines.length; i++) {
|
|
3593
|
+
if (regex.test(lines[i])) {
|
|
3594
|
+
matches.push({
|
|
3595
|
+
module: mod.name,
|
|
3596
|
+
line: i + 1,
|
|
3597
|
+
content: lines[i].trim().slice(0, 200),
|
|
3598
|
+
});
|
|
3599
|
+
regex.lastIndex = 0;
|
|
3600
|
+
}
|
|
3601
|
+
if (matches.length >= 50) break;
|
|
3602
|
+
}
|
|
3603
|
+
if (matches.length >= 50) break;
|
|
3604
|
+
}
|
|
3605
|
+
|
|
3606
|
+
return {
|
|
3607
|
+
content: [{
|
|
3608
|
+
type: 'text',
|
|
3609
|
+
text: JSON.stringify({
|
|
3610
|
+
success: true,
|
|
3611
|
+
query,
|
|
3612
|
+
total_matches: matches.length,
|
|
3613
|
+
matches,
|
|
3614
|
+
}, null, 2)
|
|
3615
|
+
}]
|
|
3616
|
+
};
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3619
|
+
case 'decompile_diff': {
|
|
3620
|
+
const decompiler = require('../src/decompiler/index.js');
|
|
3621
|
+
const [resultA, resultB] = await Promise.all([
|
|
3622
|
+
decompiler.decompilePackage(args.package, args.version_a),
|
|
3623
|
+
decompiler.decompilePackage(args.package, args.version_b),
|
|
3624
|
+
]);
|
|
3625
|
+
|
|
3626
|
+
const namesA = new Set(resultA.modules.map(m => m.name));
|
|
3627
|
+
const namesB = new Set(resultB.modules.map(m => m.name));
|
|
3628
|
+
const added = [...namesB].filter(n => !namesA.has(n));
|
|
3629
|
+
const removed = [...namesA].filter(n => !namesB.has(n));
|
|
3630
|
+
const common = [...namesA].filter(n => namesB.has(n));
|
|
3631
|
+
|
|
3632
|
+
// Compare declarations in common modules
|
|
3633
|
+
const changedDeclarations = [];
|
|
3634
|
+
for (const name of common) {
|
|
3635
|
+
const modA = resultA.modules.find(m => m.name === name);
|
|
3636
|
+
const modB = resultB.modules.find(m => m.name === name);
|
|
3637
|
+
if (modA && modB && modA.content !== modB.content) {
|
|
3638
|
+
changedDeclarations.push({
|
|
3639
|
+
module: name,
|
|
3640
|
+
sizeChange: modB.content.length - modA.content.length,
|
|
3641
|
+
fragmentsA: modA.fragments,
|
|
3642
|
+
fragmentsB: modB.fragments,
|
|
3643
|
+
});
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3647
|
+
return {
|
|
3648
|
+
content: [{
|
|
3649
|
+
type: 'text',
|
|
3650
|
+
text: JSON.stringify({
|
|
3651
|
+
success: true,
|
|
3652
|
+
package: args.package,
|
|
3653
|
+
version_a: args.version_a,
|
|
3654
|
+
version_b: args.version_b,
|
|
3655
|
+
added_modules: added,
|
|
3656
|
+
removed_modules: removed,
|
|
3657
|
+
common_modules: common.length,
|
|
3658
|
+
changed_declarations: changedDeclarations,
|
|
3659
|
+
metrics_a: resultA.metrics.source,
|
|
3660
|
+
metrics_b: resultB.metrics.source,
|
|
3661
|
+
}, null, 2)
|
|
3662
|
+
}]
|
|
3663
|
+
};
|
|
3664
|
+
}
|
|
3665
|
+
|
|
3666
|
+
case 'decompile_witness': {
|
|
3667
|
+
const decompiler = require('../src/decompiler/index.js');
|
|
3668
|
+
const witnessPath = validateRvfPath(args.witness_path);
|
|
3669
|
+
const witnessData = JSON.parse(fs.readFileSync(witnessPath, 'utf-8'));
|
|
3670
|
+
|
|
3671
|
+
let sourceContent = undefined;
|
|
3672
|
+
if (args.source_path) {
|
|
3673
|
+
const sourcePath = validateRvfPath(args.source_path);
|
|
3674
|
+
sourceContent = fs.readFileSync(sourcePath, 'utf-8');
|
|
3675
|
+
}
|
|
3676
|
+
|
|
3677
|
+
const verification = decompiler.verifyWitnessChain(witnessData, sourceContent);
|
|
3678
|
+
return {
|
|
3679
|
+
content: [{
|
|
3680
|
+
type: 'text',
|
|
3681
|
+
text: JSON.stringify({
|
|
3682
|
+
success: true,
|
|
3683
|
+
...verification,
|
|
3684
|
+
}, null, 2)
|
|
3685
|
+
}]
|
|
3686
|
+
};
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3420
3689
|
default:
|
|
3421
3690
|
return {
|
|
3422
3691
|
content: [{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ruvector",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.20",
|
|
4
4
|
"description": "Self-learning vector database for Node.js — hybrid search, Graph RAG, FlashAttention-3, DiskANN, 50+ attention mechanisms",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
"@ruvector/sona": "^0.1.4",
|
|
77
77
|
"chalk": "^4.1.2",
|
|
78
78
|
"commander": "^11.1.0",
|
|
79
|
+
"js-beautify": "^1.15.4",
|
|
79
80
|
"ora": "^5.4.1"
|
|
80
81
|
},
|
|
81
82
|
"optionalDependencies": {
|
|
@@ -88,18 +89,25 @@
|
|
|
88
89
|
"files": [
|
|
89
90
|
"bin/",
|
|
90
91
|
"dist/",
|
|
92
|
+
"src/decompiler/",
|
|
91
93
|
"README.md",
|
|
92
94
|
"LICENSE"
|
|
93
95
|
],
|
|
94
96
|
"peerDependencies": {
|
|
95
97
|
"@ruvector/pi-brain": ">=0.1.0",
|
|
96
|
-
"@ruvector/
|
|
97
|
-
"@ruvector/
|
|
98
|
+
"@ruvector/router": ">=0.1.0",
|
|
99
|
+
"@ruvector/ruvllm": ">=2.0.0"
|
|
98
100
|
},
|
|
99
101
|
"peerDependenciesMeta": {
|
|
100
|
-
"@ruvector/pi-brain": {
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
"@ruvector/pi-brain": {
|
|
103
|
+
"optional": true
|
|
104
|
+
},
|
|
105
|
+
"@ruvector/ruvllm": {
|
|
106
|
+
"optional": true
|
|
107
|
+
},
|
|
108
|
+
"@ruvector/router": {
|
|
109
|
+
"optional": true
|
|
110
|
+
}
|
|
103
111
|
},
|
|
104
112
|
"engines": {
|
|
105
113
|
"node": ">=18.0.0"
|