@theihtisham/agent-shadow-brain 1.2.0 → 3.0.0
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 +837 -73
- package/dist/adapters/aider.d.ts +11 -0
- package/dist/adapters/aider.d.ts.map +1 -0
- package/dist/adapters/aider.js +149 -0
- package/dist/adapters/aider.js.map +1 -0
- package/dist/adapters/index.d.ts +3 -1
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +5 -3
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/roo-code.d.ts +14 -0
- package/dist/adapters/roo-code.d.ts.map +1 -0
- package/dist/adapters/roo-code.js +186 -0
- package/dist/adapters/roo-code.js.map +1 -0
- package/dist/brain/accessibility-checker.d.ts +10 -0
- package/dist/brain/accessibility-checker.d.ts.map +1 -0
- package/dist/brain/accessibility-checker.js +379 -0
- package/dist/brain/accessibility-checker.js.map +1 -0
- package/dist/brain/adr-engine.d.ts +58 -0
- package/dist/brain/adr-engine.d.ts.map +1 -0
- package/dist/brain/adr-engine.js +400 -0
- package/dist/brain/adr-engine.js.map +1 -0
- package/dist/brain/api-contract-analyzer.d.ts +19 -0
- package/dist/brain/api-contract-analyzer.d.ts.map +1 -0
- package/dist/brain/api-contract-analyzer.js +251 -0
- package/dist/brain/api-contract-analyzer.js.map +1 -0
- package/dist/brain/ast-analyzer.d.ts +23 -0
- package/dist/brain/ast-analyzer.d.ts.map +1 -0
- package/dist/brain/ast-analyzer.js +462 -0
- package/dist/brain/ast-analyzer.js.map +1 -0
- package/dist/brain/code-age-analyzer.d.ts +11 -0
- package/dist/brain/code-age-analyzer.d.ts.map +1 -0
- package/dist/brain/code-age-analyzer.js +152 -0
- package/dist/brain/code-age-analyzer.js.map +1 -0
- package/dist/brain/code-similarity.d.ts +43 -0
- package/dist/brain/code-similarity.d.ts.map +1 -0
- package/dist/brain/code-similarity.js +227 -0
- package/dist/brain/code-similarity.js.map +1 -0
- package/dist/brain/config-drift-detector.d.ts +13 -0
- package/dist/brain/config-drift-detector.d.ts.map +1 -0
- package/dist/brain/config-drift-detector.js +198 -0
- package/dist/brain/config-drift-detector.js.map +1 -0
- package/dist/brain/context-completion.d.ts +39 -0
- package/dist/brain/context-completion.d.ts.map +1 -0
- package/dist/brain/context-completion.js +851 -0
- package/dist/brain/context-completion.js.map +1 -0
- package/dist/brain/dead-code-eliminator.d.ts +16 -0
- package/dist/brain/dead-code-eliminator.d.ts.map +1 -0
- package/dist/brain/dead-code-eliminator.js +359 -0
- package/dist/brain/dead-code-eliminator.js.map +1 -0
- package/dist/brain/dependency-graph.d.ts +35 -0
- package/dist/brain/dependency-graph.d.ts.map +1 -0
- package/dist/brain/dependency-graph.js +310 -0
- package/dist/brain/dependency-graph.js.map +1 -0
- package/dist/brain/env-analyzer.d.ts +13 -0
- package/dist/brain/env-analyzer.d.ts.map +1 -0
- package/dist/brain/env-analyzer.js +277 -0
- package/dist/brain/env-analyzer.js.map +1 -0
- package/dist/brain/i18n-detector.d.ts +12 -0
- package/dist/brain/i18n-detector.d.ts.map +1 -0
- package/dist/brain/i18n-detector.js +242 -0
- package/dist/brain/i18n-detector.js.map +1 -0
- package/dist/brain/learning-engine.d.ts +54 -0
- package/dist/brain/learning-engine.d.ts.map +1 -0
- package/dist/brain/learning-engine.js +855 -0
- package/dist/brain/learning-engine.js.map +1 -0
- package/dist/brain/license-compliance.d.ts +13 -0
- package/dist/brain/license-compliance.d.ts.map +1 -0
- package/dist/brain/license-compliance.js +213 -0
- package/dist/brain/license-compliance.js.map +1 -0
- package/dist/brain/llm-client.d.ts.map +1 -1
- package/dist/brain/llm-client.js +3 -0
- package/dist/brain/llm-client.js.map +1 -1
- package/dist/brain/mcp-server.d.ts +30 -0
- package/dist/brain/mcp-server.d.ts.map +1 -0
- package/dist/brain/mcp-server.js +408 -0
- package/dist/brain/mcp-server.js.map +1 -0
- package/dist/brain/multi-project.d.ts +13 -0
- package/dist/brain/multi-project.d.ts.map +1 -0
- package/dist/brain/multi-project.js +163 -0
- package/dist/brain/multi-project.js.map +1 -0
- package/dist/brain/mutation-advisor.d.ts +11 -0
- package/dist/brain/mutation-advisor.d.ts.map +1 -0
- package/dist/brain/mutation-advisor.js +154 -0
- package/dist/brain/mutation-advisor.js.map +1 -0
- package/dist/brain/neural-mesh.d.ts +69 -0
- package/dist/brain/neural-mesh.d.ts.map +1 -0
- package/dist/brain/neural-mesh.js +677 -0
- package/dist/brain/neural-mesh.js.map +1 -0
- package/dist/brain/orchestrator.d.ts +159 -2
- package/dist/brain/orchestrator.d.ts.map +1 -1
- package/dist/brain/orchestrator.js +478 -0
- package/dist/brain/orchestrator.js.map +1 -1
- package/dist/brain/perf-profiler.d.ts +14 -0
- package/dist/brain/perf-profiler.d.ts.map +1 -0
- package/dist/brain/perf-profiler.js +289 -0
- package/dist/brain/perf-profiler.js.map +1 -0
- package/dist/brain/semantic-analyzer.d.ts +46 -0
- package/dist/brain/semantic-analyzer.d.ts.map +1 -0
- package/dist/brain/semantic-analyzer.js +496 -0
- package/dist/brain/semantic-analyzer.js.map +1 -0
- package/dist/brain/team-mode.d.ts +27 -0
- package/dist/brain/team-mode.d.ts.map +1 -0
- package/dist/brain/team-mode.js +262 -0
- package/dist/brain/team-mode.js.map +1 -0
- package/dist/brain/type-safety.d.ts +13 -0
- package/dist/brain/type-safety.d.ts.map +1 -0
- package/dist/brain/type-safety.js +217 -0
- package/dist/brain/type-safety.js.map +1 -0
- package/dist/cli.js +998 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +379 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// src/cli.ts — CLI entry point for Shadow Brain
|
|
2
|
+
// src/cli.ts — CLI entry point for Shadow Brain v3.0.0
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import Conf from 'conf';
|
|
@@ -7,7 +7,7 @@ import * as fs from 'fs';
|
|
|
7
7
|
import * as path from 'path';
|
|
8
8
|
import { Orchestrator } from './brain/orchestrator.js';
|
|
9
9
|
import { detectRunningAgents, createAdapter } from './adapters/index.js';
|
|
10
|
-
const VERSION = '
|
|
10
|
+
const VERSION = '3.0.0';
|
|
11
11
|
const config = new Conf({
|
|
12
12
|
projectName: 'shadow-brain',
|
|
13
13
|
defaults: {
|
|
@@ -882,11 +882,982 @@ const notifyCmd = new Command('notify')
|
|
|
882
882
|
process.exit(1);
|
|
883
883
|
}
|
|
884
884
|
});
|
|
885
|
+
// ─── MCP (Start MCP Server) ──────────────────────────────────────────────────
|
|
886
|
+
const mcpCmd = new Command('mcp')
|
|
887
|
+
.description('Start Shadow Brain as an MCP (Model Context Protocol) server')
|
|
888
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
889
|
+
.option('--port <port>', 'MCP server port', '7342')
|
|
890
|
+
.option('--host <host>', 'MCP server host', 'localhost')
|
|
891
|
+
.option('-p, --provider <provider>', 'LLM provider')
|
|
892
|
+
.option('-k, --api-key <key>', 'API key')
|
|
893
|
+
.action(async (projectDir, opts) => {
|
|
894
|
+
const brainConfig = mergeConfig({ ...opts, projectDir, watchMode: false });
|
|
895
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
896
|
+
try {
|
|
897
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN v${VERSION} — MCP Server\n`));
|
|
898
|
+
console.log(chalk.dim(' Starting MCP server...'));
|
|
899
|
+
await orchestrator.startMCPServer({ port: parseInt(opts.port || '7342'), host: opts.host || 'localhost' });
|
|
900
|
+
console.log(chalk.green(` ✓ MCP server running at http://${opts.host || 'localhost'}:${opts.port || '7342'}/mcp`));
|
|
901
|
+
console.log(chalk.dim(' Endpoints:'));
|
|
902
|
+
console.log(chalk.dim(' POST /mcp — JSON-RPC 2.0 requests'));
|
|
903
|
+
console.log(chalk.dim(' GET /sse — Server-Sent Events stream'));
|
|
904
|
+
console.log(chalk.dim('\n Press Ctrl+C to stop\n'));
|
|
905
|
+
process.on('SIGINT', async () => {
|
|
906
|
+
await orchestrator.stopMCPServer();
|
|
907
|
+
process.exit(0);
|
|
908
|
+
});
|
|
909
|
+
// Keep alive
|
|
910
|
+
await new Promise(() => { });
|
|
911
|
+
}
|
|
912
|
+
catch (err) {
|
|
913
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
914
|
+
process.exit(1);
|
|
915
|
+
}
|
|
916
|
+
});
|
|
917
|
+
// ─── TEAM (Team Mode) ────────────────────────────────────────────────────────
|
|
918
|
+
const teamCmd = new Command('team')
|
|
919
|
+
.description('Manage team mode — share insights and patterns across team')
|
|
920
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
921
|
+
.option('--share <message>', 'Share an insight with the team')
|
|
922
|
+
.option('--list', 'List team insights')
|
|
923
|
+
.option('--stats', 'Show team statistics')
|
|
924
|
+
.option('--user <name>', 'Your team username')
|
|
925
|
+
.option('--json', 'Output as JSON')
|
|
926
|
+
.action(async (projectDir, opts) => {
|
|
927
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
928
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
929
|
+
orchestrator.enableTeamMode(opts.user || process.env.USER || 'anonymous');
|
|
930
|
+
try {
|
|
931
|
+
if (opts.share) {
|
|
932
|
+
const insight = {
|
|
933
|
+
type: 'context', priority: 'medium',
|
|
934
|
+
title: opts.share.slice(0, 100), content: opts.share,
|
|
935
|
+
files: [], timestamp: new Date(),
|
|
936
|
+
};
|
|
937
|
+
const result = await orchestrator.shareTeamInsight(insight);
|
|
938
|
+
console.log(chalk.green(` ✓ Insight shared with team (ID: ${result?.id || 'unknown'})`));
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
if (opts.stats) {
|
|
942
|
+
const stats = await orchestrator.getTeamStats();
|
|
943
|
+
if (!stats) {
|
|
944
|
+
console.log(chalk.dim(' No team data available.'));
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
if (opts.json) {
|
|
948
|
+
console.log(JSON.stringify(stats, null, 2));
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
console.log(chalk.magenta.bold('\n SHADOW BRAIN Team Stats\n'));
|
|
952
|
+
console.log(chalk.dim(` Members: `) + chalk.cyan(String(stats.members)));
|
|
953
|
+
console.log(chalk.dim(` Total Insights: `) + chalk.cyan(String(stats.totalInsights)));
|
|
954
|
+
console.log(chalk.dim(` Total Patterns: `) + chalk.cyan(String(stats.totalPatterns)));
|
|
955
|
+
console.log();
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
// Default: list insights
|
|
959
|
+
const insights = await orchestrator.getTeamInsights(20);
|
|
960
|
+
if (insights.length === 0) {
|
|
961
|
+
console.log(chalk.dim(' No team insights yet. Use --share to add one.'));
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
if (opts.json) {
|
|
965
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Team Insights (${insights.length})\n`));
|
|
969
|
+
for (const ti of insights) {
|
|
970
|
+
const color = ti.insight.priority === 'critical' ? 'red' : ti.insight.priority === 'high' ? 'yellow' : 'blue';
|
|
971
|
+
console.log(chalk ` {${color}.bold [${ti.insight.priority}]} ${ti.insight.title}`);
|
|
972
|
+
console.log(chalk.dim(` Shared by: ${ti.sharedBy} | Upvotes: ${ti.upvotes}`));
|
|
973
|
+
console.log();
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
catch (err) {
|
|
977
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
978
|
+
process.exit(1);
|
|
979
|
+
}
|
|
980
|
+
});
|
|
981
|
+
// ─── PROJECTS (Multi-Project Manager) ─────────────────────────────────────────
|
|
982
|
+
const projectsCmd = new Command('projects')
|
|
983
|
+
.description('Manage multiple projects with Shadow Brain')
|
|
984
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
985
|
+
.option('--add <dir>', 'Register a project directory')
|
|
986
|
+
.option('--remove <dir>', 'Unregister a project directory')
|
|
987
|
+
.option('--scan <parent-dir>', 'Scan directory for git repositories')
|
|
988
|
+
.option('--health', 'Show aggregated health across all projects')
|
|
989
|
+
.option('--list', 'List all registered projects')
|
|
990
|
+
.option('--json', 'Output as JSON')
|
|
991
|
+
.action(async (projectDir, opts) => {
|
|
992
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
993
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
994
|
+
const mgr = orchestrator.getMultiProjectManager();
|
|
995
|
+
try {
|
|
996
|
+
if (opts.add) {
|
|
997
|
+
const info = await mgr.addProject(path.resolve(opts.add));
|
|
998
|
+
console.log(chalk.green(` ✓ Project registered: ${info.name} (${info.dir})`));
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
if (opts.remove) {
|
|
1002
|
+
await mgr.removeProject(path.resolve(opts.remove));
|
|
1003
|
+
console.log(chalk.green(` ✓ Project removed: ${opts.remove}`));
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
if (opts.scan) {
|
|
1007
|
+
console.log(chalk.cyan(` Scanning ${opts.scan} for git repositories...`));
|
|
1008
|
+
const repos = await mgr.scanDirectory(path.resolve(opts.scan));
|
|
1009
|
+
if (repos.length === 0) {
|
|
1010
|
+
console.log(chalk.dim(' No git repositories found.'));
|
|
1011
|
+
}
|
|
1012
|
+
else {
|
|
1013
|
+
console.log(chalk.green(` Found ${repos.length} project(s):`));
|
|
1014
|
+
for (const r of repos) {
|
|
1015
|
+
console.log(chalk.dim(` • ${r}`));
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
if (opts.health) {
|
|
1021
|
+
const health = await mgr.getAggregatedHealth();
|
|
1022
|
+
if (opts.json) {
|
|
1023
|
+
console.log(JSON.stringify(health, null, 2));
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
console.log(chalk.magenta.bold('\n SHADOW BRAIN Aggregated Health\n'));
|
|
1027
|
+
console.log(chalk.dim(` Projects: `) + chalk.cyan(String(health.projects)));
|
|
1028
|
+
console.log(chalk.dim(` Average Health: `) + chalk.cyan(`${health.averageHealth}/100`));
|
|
1029
|
+
console.log(chalk.dim(` Best Project: `) + chalk.green(health.bestProject));
|
|
1030
|
+
console.log(chalk.dim(` Worst Project: `) + chalk.yellow(health.worstProject));
|
|
1031
|
+
console.log(chalk.dim(` Critical Issues:`) + chalk.red(String(health.criticalIssues)));
|
|
1032
|
+
console.log();
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
// Default: list projects
|
|
1036
|
+
const projects = await mgr.listProjects();
|
|
1037
|
+
if (projects.length === 0) {
|
|
1038
|
+
console.log(chalk.dim(' No projects registered. Use --add or --scan to register projects.'));
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
if (opts.json) {
|
|
1042
|
+
console.log(JSON.stringify(projects, null, 2));
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Registered Projects (${projects.length})\n`));
|
|
1046
|
+
for (const p of projects) {
|
|
1047
|
+
const statusColor = p.status === 'running' ? 'green' : p.status === 'error' ? 'red' : 'yellow';
|
|
1048
|
+
const health = p.lastHealth !== null ? `${p.lastHealth}/100` : 'N/A';
|
|
1049
|
+
console.log(` ${chalk[statusColor]('●')} ${chalk.bold(p.name)} ${chalk.dim(`(${p.dir})`)}`);
|
|
1050
|
+
console.log(chalk.dim(` Status: ${p.status} | Health: ${health} | Insights: ${p.insightCount}`));
|
|
1051
|
+
}
|
|
1052
|
+
console.log();
|
|
1053
|
+
}
|
|
1054
|
+
catch (err) {
|
|
1055
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1056
|
+
process.exit(1);
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
// ─── SEMANTIC (Semantic Analysis) ─────────────────────────────────────────────
|
|
1060
|
+
const semanticCmd = new Command('semantic')
|
|
1061
|
+
.description('Run semantic code analysis — symbols, unused exports, dead code')
|
|
1062
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1063
|
+
.option('--json', 'Output as JSON')
|
|
1064
|
+
.action(async (projectDir, opts) => {
|
|
1065
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1066
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1067
|
+
try {
|
|
1068
|
+
console.log(chalk.cyan(' Running semantic analysis...'));
|
|
1069
|
+
const { symbols, unusedExports, deadCode } = await orchestrator.getSemanticInsights();
|
|
1070
|
+
const totalSymbols = Array.from(symbols.values()).reduce((sum, s) => sum + s.length, 0);
|
|
1071
|
+
if (opts.json) {
|
|
1072
|
+
const serializable = {
|
|
1073
|
+
totalSymbols,
|
|
1074
|
+
filesAnalyzed: symbols.size,
|
|
1075
|
+
unusedExports: unusedExports.map(s => ({ name: s.name, type: s.type, file: s.file, line: s.line })),
|
|
1076
|
+
deadCode: deadCode.map(s => ({ name: s.name, type: s.type, file: s.file, line: s.line })),
|
|
1077
|
+
};
|
|
1078
|
+
console.log(JSON.stringify(serializable, null, 2));
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Semantic Analysis\n`));
|
|
1082
|
+
console.log(chalk.dim(` Files analyzed: `) + chalk.cyan(String(symbols.size)));
|
|
1083
|
+
console.log(chalk.dim(` Total symbols: `) + chalk.cyan(String(totalSymbols)));
|
|
1084
|
+
console.log(chalk.dim(` Unused exports: `) + chalk.yellow(String(unusedExports.length)));
|
|
1085
|
+
console.log(chalk.dim(` Dead code: `) + chalk.red(String(deadCode.length)));
|
|
1086
|
+
if (unusedExports.length > 0) {
|
|
1087
|
+
console.log(chalk.yellow('\n Unused Exports:'));
|
|
1088
|
+
for (const s of unusedExports.slice(0, 20)) {
|
|
1089
|
+
console.log(chalk.dim(` • ${s.name} (${s.type}) — ${s.file}:${s.line}`));
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
if (deadCode.length > 0) {
|
|
1093
|
+
console.log(chalk.red('\n Dead Code:'));
|
|
1094
|
+
for (const s of deadCode.slice(0, 20)) {
|
|
1095
|
+
console.log(chalk.dim(` • ${s.name} (${s.type}) — ${s.file}:${s.line}`));
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
console.log();
|
|
1099
|
+
}
|
|
1100
|
+
catch (err) {
|
|
1101
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1102
|
+
process.exit(1);
|
|
1103
|
+
}
|
|
1104
|
+
});
|
|
1105
|
+
// ─── DEPS (Dependency Graph) ─────────────────────────────────────────────────
|
|
1106
|
+
const depsCmd = new Command('deps')
|
|
1107
|
+
.description('Analyze dependency graph — cycles, orphans, hubs')
|
|
1108
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1109
|
+
.option('--json', 'Output as JSON')
|
|
1110
|
+
.action(async (projectDir, opts) => {
|
|
1111
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1112
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1113
|
+
try {
|
|
1114
|
+
console.log(chalk.cyan(' Building dependency graph...'));
|
|
1115
|
+
const graph = await orchestrator.getDependencyGraph();
|
|
1116
|
+
const details = orchestrator.getDependencyDetails(graph);
|
|
1117
|
+
if (opts.json) {
|
|
1118
|
+
console.log(JSON.stringify({ ...graph, ...details }, null, 2));
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Dependency Graph\n`));
|
|
1122
|
+
console.log(chalk.dim(` Files (nodes): `) + chalk.cyan(String(graph.nodes.length)));
|
|
1123
|
+
console.log(chalk.dim(` Imports (edges):`) + chalk.cyan(String(graph.edges.length)));
|
|
1124
|
+
console.log(chalk.dim(` Orphans: `) + chalk.yellow(String(details.orphans.length)));
|
|
1125
|
+
console.log(chalk.dim(` Cycles: `) + chalk.red(String(details.cycles.length)));
|
|
1126
|
+
console.log(chalk.dim(` Hubs: `) + chalk.yellow(String(details.hubs.length)));
|
|
1127
|
+
if (details.cycles.length > 0) {
|
|
1128
|
+
console.log(chalk.red('\n Circular Dependencies:'));
|
|
1129
|
+
for (const cycle of details.cycles.slice(0, 10)) {
|
|
1130
|
+
console.log(chalk.red(` ↻ ${cycle.join(' → ')}`));
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
if (details.hubs.length > 0) {
|
|
1134
|
+
console.log(chalk.yellow('\n Dependency Hubs:'));
|
|
1135
|
+
for (const hub of details.hubs.slice(0, 10)) {
|
|
1136
|
+
console.log(chalk.dim(` • ${hub.file} — ${hub.dependents} dependents (${hub.risk} risk)`));
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
console.log();
|
|
1140
|
+
}
|
|
1141
|
+
catch (err) {
|
|
1142
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1143
|
+
process.exit(1);
|
|
1144
|
+
}
|
|
1145
|
+
});
|
|
1146
|
+
// ─── DUPES (Duplicate Detection) ─────────────────────────────────────────────
|
|
1147
|
+
const dupesCmd = new Command('dupes')
|
|
1148
|
+
.description('Detect duplicate and near-duplicate code blocks')
|
|
1149
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1150
|
+
.option('--threshold <n>', 'Minimum similarity (0-1)', '0.8')
|
|
1151
|
+
.option('--json', 'Output as JSON')
|
|
1152
|
+
.action(async (projectDir, opts) => {
|
|
1153
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1154
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1155
|
+
try {
|
|
1156
|
+
const threshold = parseFloat(opts.threshold || '0.8');
|
|
1157
|
+
console.log(chalk.cyan(` Detecting duplicate code (threshold: ${threshold})...`));
|
|
1158
|
+
const groups = await orchestrator.detectDuplicates(threshold);
|
|
1159
|
+
if (opts.json) {
|
|
1160
|
+
console.log(JSON.stringify(groups, null, 2));
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Duplicate Detection\n`));
|
|
1164
|
+
if (groups.length === 0) {
|
|
1165
|
+
console.log(chalk.green(' No significant duplicates found!'));
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
console.log(chalk.yellow(` Found ${groups.length} duplicate group(s):\n`));
|
|
1169
|
+
for (let i = 0; i < groups.length; i++) {
|
|
1170
|
+
const g = groups[i];
|
|
1171
|
+
console.log(chalk.bold(` Group ${i + 1} (${(g.similarity * 100).toFixed(0)}% similar):`));
|
|
1172
|
+
for (const block of g.blocks) {
|
|
1173
|
+
console.log(chalk.dim(` • ${block.file}:${block.startLine}-${block.endLine} (${block.type})`));
|
|
1174
|
+
}
|
|
1175
|
+
console.log(chalk.cyan(` Suggestion: ${g.suggestedRefactor}`));
|
|
1176
|
+
console.log();
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
catch (err) {
|
|
1180
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1181
|
+
process.exit(1);
|
|
1182
|
+
}
|
|
1183
|
+
});
|
|
1184
|
+
// ─── PERF (Performance Profiling) ────────────────────────────────────────────
|
|
1185
|
+
const perfCmd = new Command('perf')
|
|
1186
|
+
.description('Profile code for performance anti-patterns')
|
|
1187
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1188
|
+
.option('--json', 'Output as JSON')
|
|
1189
|
+
.action(async (projectDir, opts) => {
|
|
1190
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1191
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1192
|
+
try {
|
|
1193
|
+
console.log(chalk.cyan(' Profiling for performance issues...'));
|
|
1194
|
+
const insights = await orchestrator.profilePerformance();
|
|
1195
|
+
if (opts.json) {
|
|
1196
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1199
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Performance Profiler (${insights.length} findings)\n`));
|
|
1200
|
+
if (insights.length === 0) {
|
|
1201
|
+
console.log(chalk.green(' No performance issues detected!'));
|
|
1202
|
+
return;
|
|
1203
|
+
}
|
|
1204
|
+
for (const pi of insights) {
|
|
1205
|
+
const color = pi.severity === 'critical' ? 'red' : pi.severity === 'high' ? 'yellow' : 'blue';
|
|
1206
|
+
console.log(chalk ` {${color}.bold [${pi.severity.toUpperCase()}]} ${pi.description}`);
|
|
1207
|
+
console.log(chalk.dim(` Category: ${pi.category} | Impact: ${pi.estimatedImpact}`));
|
|
1208
|
+
console.log(chalk.cyan(` Fix: ${pi.suggestion}`));
|
|
1209
|
+
console.log();
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
catch (err) {
|
|
1213
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1214
|
+
process.exit(1);
|
|
1215
|
+
}
|
|
1216
|
+
});
|
|
1217
|
+
// ─── CONTEXT (Context Gaps) ──────────────────────────────────────────────────
|
|
1218
|
+
const contextCmd = new Command('context')
|
|
1219
|
+
.description('Analyze project context completeness and suggest improvements')
|
|
1220
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1221
|
+
.option('--json', 'Output as JSON')
|
|
1222
|
+
.action(async (projectDir, opts) => {
|
|
1223
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1224
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1225
|
+
try {
|
|
1226
|
+
console.log(chalk.cyan(' Analyzing project context...'));
|
|
1227
|
+
const [gaps, knowledge] = await Promise.all([
|
|
1228
|
+
orchestrator.getContextGaps(),
|
|
1229
|
+
orchestrator.buildKnowledge(),
|
|
1230
|
+
]);
|
|
1231
|
+
if (opts.json) {
|
|
1232
|
+
console.log(JSON.stringify({ knowledge, gaps }, null, 2));
|
|
1233
|
+
return;
|
|
1234
|
+
}
|
|
1235
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Context Analysis\n`));
|
|
1236
|
+
console.log(chalk.dim(' Project: ') + chalk.cyan(knowledge.name));
|
|
1237
|
+
console.log(chalk.dim(' Architecture: ') + chalk.cyan(knowledge.architecture || 'Not documented'));
|
|
1238
|
+
if (knowledge.conventions.length > 0) {
|
|
1239
|
+
console.log(chalk.dim(' Conventions: ') + chalk.cyan(knowledge.conventions.join(', ')));
|
|
1240
|
+
}
|
|
1241
|
+
if (gaps.length > 0) {
|
|
1242
|
+
console.log(chalk.yellow(`\n Context Gaps (${gaps.length}):`));
|
|
1243
|
+
for (const gap of gaps) {
|
|
1244
|
+
const color = gap.priority === 'critical' ? 'red' : gap.priority === 'high' ? 'yellow' : 'blue';
|
|
1245
|
+
console.log(chalk ` {${color}.bold [${gap.priority}]} ${gap.title}`);
|
|
1246
|
+
console.log(chalk.dim(` ${gap.content}`));
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
else {
|
|
1250
|
+
console.log(chalk.green('\n No context gaps found!'));
|
|
1251
|
+
}
|
|
1252
|
+
console.log();
|
|
1253
|
+
}
|
|
1254
|
+
catch (err) {
|
|
1255
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1256
|
+
process.exit(1);
|
|
1257
|
+
}
|
|
1258
|
+
});
|
|
1259
|
+
// ─── LEARN (Learning Engine) ─────────────────────────────────────────────────
|
|
1260
|
+
const learnCmd = new Command('learn')
|
|
1261
|
+
.description('Run the learning engine to extract patterns and lessons from the codebase')
|
|
1262
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1263
|
+
.option('--json', 'Output as JSON')
|
|
1264
|
+
.action(async (projectDir, opts) => {
|
|
1265
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1266
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1267
|
+
try {
|
|
1268
|
+
console.log(chalk.cyan(' Running learning engine...'));
|
|
1269
|
+
await orchestrator.runLearningCycle();
|
|
1270
|
+
const lessons = await orchestrator.getLearnedLessons();
|
|
1271
|
+
if (opts.json) {
|
|
1272
|
+
console.log(JSON.stringify(lessons, null, 2));
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Learning Engine (${lessons.length} lessons)\n`));
|
|
1276
|
+
if (lessons.length === 0) {
|
|
1277
|
+
console.log(chalk.dim(' No lessons learned yet. Run analysis first.'));
|
|
1278
|
+
return;
|
|
1279
|
+
}
|
|
1280
|
+
for (const lesson of lessons) {
|
|
1281
|
+
console.log(chalk.bold(` [${lesson.category}] ${lesson.pattern}`));
|
|
1282
|
+
console.log(chalk.dim(` Lesson: ${lesson.lesson}`));
|
|
1283
|
+
console.log(chalk.dim(` Confidence: ${(lesson.confidence * 100).toFixed(0)}%`));
|
|
1284
|
+
console.log();
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
catch (err) {
|
|
1288
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1289
|
+
process.exit(1);
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
// ─── MESH (v2.1.0 Quantum Neural Mesh) ──────────────────────────────────────
|
|
1293
|
+
const meshCmd = new Command('mesh')
|
|
1294
|
+
.description('Quantum Neural Mesh — cross-session shared intelligence');
|
|
1295
|
+
meshCmd.command('status')
|
|
1296
|
+
.description('Show mesh status and connected nodes')
|
|
1297
|
+
.action(async () => {
|
|
1298
|
+
try {
|
|
1299
|
+
const { NeuralMesh } = await import('./brain/neural-mesh.js');
|
|
1300
|
+
const mesh = new NeuralMesh(process.cwd());
|
|
1301
|
+
const state = mesh.getMeshState();
|
|
1302
|
+
console.log(chalk.magenta.bold('\n QUANTUM NEURAL MESH Status\n'));
|
|
1303
|
+
console.log(chalk.bold(' Quantum State:'), state.quantumState === 'coherent'
|
|
1304
|
+
? chalk.green(state.quantumState) : state.quantumState === 'decoherent'
|
|
1305
|
+
? chalk.yellow(state.quantumState) : chalk.red(state.quantumState));
|
|
1306
|
+
console.log(chalk.bold(' Active Nodes:'), state.nodes.filter(n => n.status === 'active').length);
|
|
1307
|
+
console.log(chalk.bold(' Total Nodes:'), state.nodes.length);
|
|
1308
|
+
console.log(chalk.bold(' Insights Exchanged:'), state.totalInsightsExchanged);
|
|
1309
|
+
console.log(chalk.bold(' Knowledge Entries:'), state.knowledge.length);
|
|
1310
|
+
console.log(chalk.bold(' Average Entropy:'), state.averageEntropy.toFixed(3));
|
|
1311
|
+
console.log(chalk.bold(' Mesh Uptime:'), Math.round(state.meshUptime / 1000) + 's');
|
|
1312
|
+
if (state.nodes.length > 0) {
|
|
1313
|
+
console.log(chalk.cyan('\n Connected Nodes:'));
|
|
1314
|
+
for (const node of state.nodes) {
|
|
1315
|
+
const statusIcon = node.status === 'active' ? chalk.green('●') : node.status === 'idle' ? chalk.yellow('◐') : chalk.red('○');
|
|
1316
|
+
console.log(` ${statusIcon} ${chalk.bold(node.projectName)} (${node.personality}) — PID ${node.pid}`);
|
|
1317
|
+
console.log(chalk.dim(` Health: ${node.healthScore ?? 'N/A'} | Insights: ${node.insightsGenerated} | Task: ${node.currentTask || 'idle'}`));
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
if (state.knowledge.length > 0) {
|
|
1321
|
+
console.log(chalk.cyan('\n Top Knowledge:'));
|
|
1322
|
+
for (const k of state.knowledge.slice(0, 10)) {
|
|
1323
|
+
const conf = (k.confidence * 100).toFixed(0);
|
|
1324
|
+
console.log(` ${chalk.bold(`[${k.category}]`)} ${k.content.slice(0, 80)}... (confidence: ${conf}%, freq: ${k.frequency})`);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
console.log();
|
|
1328
|
+
}
|
|
1329
|
+
catch (err) {
|
|
1330
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1331
|
+
process.exit(1);
|
|
1332
|
+
}
|
|
1333
|
+
});
|
|
1334
|
+
meshCmd.command('insights')
|
|
1335
|
+
.description('Get cross-session insights from other Shadow Brain instances')
|
|
1336
|
+
.option('-n, --limit <number>', 'Max insights to show', '20')
|
|
1337
|
+
.option('--json', 'Output as JSON')
|
|
1338
|
+
.action(async (opts) => {
|
|
1339
|
+
try {
|
|
1340
|
+
const { NeuralMesh } = await import('./brain/neural-mesh.js');
|
|
1341
|
+
const mesh = new NeuralMesh(process.cwd());
|
|
1342
|
+
const insights = mesh.getCrossSessionInsights(parseInt(opts.limit));
|
|
1343
|
+
if (opts.json) {
|
|
1344
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
console.log(chalk.magenta.bold(`\n Cross-Session Insights (${insights.length})\n`));
|
|
1348
|
+
if (insights.length === 0) {
|
|
1349
|
+
console.log(chalk.dim(' No cross-session insights found. Start multiple Shadow Brain instances to share knowledge.'));
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
for (const csi of insights) {
|
|
1353
|
+
const prioColor = csi.insight.priority === 'critical' ? 'red' : csi.insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1354
|
+
console.log(chalk ` {${prioColor}.bold [${csi.insight.priority}]} ${csi.insight.title}`);
|
|
1355
|
+
console.log(chalk.dim(` From: ${csi.sourceProject} | Relevance: ${(csi.relevanceScore * 100).toFixed(0)}%`));
|
|
1356
|
+
console.log(chalk.dim(` ${csi.insight.content.slice(0, 120)}`));
|
|
1357
|
+
console.log();
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
catch (err) {
|
|
1361
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1362
|
+
process.exit(1);
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1365
|
+
meshCmd.command('knowledge')
|
|
1366
|
+
.description('View shared knowledge base across all mesh nodes')
|
|
1367
|
+
.option('-n, --limit <number>', 'Max entries to show', '20')
|
|
1368
|
+
.option('--category <category>', 'Filter by category')
|
|
1369
|
+
.option('--json', 'Output as JSON')
|
|
1370
|
+
.action(async (opts) => {
|
|
1371
|
+
try {
|
|
1372
|
+
const { NeuralMesh } = await import('./brain/neural-mesh.js');
|
|
1373
|
+
const mesh = new NeuralMesh(process.cwd());
|
|
1374
|
+
let knowledge = mesh.getSharedKnowledge(parseInt(opts.limit));
|
|
1375
|
+
if (opts.category) {
|
|
1376
|
+
knowledge = knowledge.filter(k => k.category === opts.category);
|
|
1377
|
+
}
|
|
1378
|
+
if (opts.json) {
|
|
1379
|
+
console.log(JSON.stringify(knowledge, null, 2));
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
console.log(chalk.magenta.bold(`\n Shared Knowledge Base (${knowledge.length} entries)\n`));
|
|
1383
|
+
if (knowledge.length === 0) {
|
|
1384
|
+
console.log(chalk.dim(' No shared knowledge found yet.'));
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1387
|
+
for (const k of knowledge) {
|
|
1388
|
+
const conf = (k.confidence * 100).toFixed(0);
|
|
1389
|
+
console.log(chalk ` {bold [${k.category}]} ${k.content.slice(0, 100)}`);
|
|
1390
|
+
console.log(chalk.dim(` Confidence: ${conf}% | Frequency: ${k.frequency} | Source: ${k.sourceProject}`));
|
|
1391
|
+
console.log();
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
catch (err) {
|
|
1395
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1396
|
+
process.exit(1);
|
|
1397
|
+
}
|
|
1398
|
+
});
|
|
1399
|
+
meshCmd.command('nodes')
|
|
1400
|
+
.description('List all connected mesh nodes')
|
|
1401
|
+
.option('--json', 'Output as JSON')
|
|
1402
|
+
.action(async (opts) => {
|
|
1403
|
+
try {
|
|
1404
|
+
const { NeuralMesh } = await import('./brain/neural-mesh.js');
|
|
1405
|
+
const mesh = new NeuralMesh(process.cwd());
|
|
1406
|
+
const nodes = mesh.getConnectedNodes();
|
|
1407
|
+
if (opts.json) {
|
|
1408
|
+
console.log(JSON.stringify(nodes, null, 2));
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
console.log(chalk.magenta.bold(`\n Mesh Nodes (${nodes.length})\n`));
|
|
1412
|
+
if (nodes.length === 0) {
|
|
1413
|
+
console.log(chalk.dim(' No nodes connected.'));
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
for (const node of nodes) {
|
|
1417
|
+
const statusIcon = node.status === 'active' ? chalk.green('●') : node.status === 'idle' ? chalk.yellow('◐') : chalk.red('○');
|
|
1418
|
+
console.log(` ${statusIcon} ${chalk.bold(node.projectName)}`);
|
|
1419
|
+
console.log(chalk.dim(` Node: ${node.id.slice(0, 12)}... | PID: ${node.pid} | Personality: ${node.personality}`));
|
|
1420
|
+
console.log(chalk.dim(` Health: ${node.healthScore ?? 'N/A'} | Insights: ${node.insightsGenerated} | Task: ${node.currentTask || 'idle'}`));
|
|
1421
|
+
console.log(chalk.dim(` Started: ${new Date(node.startedAt).toLocaleString()} | Last HB: ${new Date(node.lastHeartbeat).toLocaleString()}`));
|
|
1422
|
+
console.log();
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
catch (err) {
|
|
1426
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1427
|
+
process.exit(1);
|
|
1428
|
+
}
|
|
1429
|
+
});
|
|
1430
|
+
meshCmd.command('aggregate')
|
|
1431
|
+
.description('Get aggregated insights across all mesh projects')
|
|
1432
|
+
.action(async () => {
|
|
1433
|
+
try {
|
|
1434
|
+
const { NeuralMesh } = await import('./brain/neural-mesh.js');
|
|
1435
|
+
const mesh = new NeuralMesh(process.cwd());
|
|
1436
|
+
const agg = mesh.getAggregatedInsights();
|
|
1437
|
+
if (!agg) {
|
|
1438
|
+
console.log(chalk.dim('\n No mesh data available.\n'));
|
|
1439
|
+
return;
|
|
1440
|
+
}
|
|
1441
|
+
console.log(chalk.magenta.bold('\n Aggregated Mesh Intelligence\n'));
|
|
1442
|
+
console.log(chalk.bold(' Total Projects:'), agg.totalProjects);
|
|
1443
|
+
console.log(chalk.bold(' Total Insights:'), agg.totalInsights);
|
|
1444
|
+
if (agg.topCategories.length > 0) {
|
|
1445
|
+
console.log(chalk.cyan('\n Top Categories:'));
|
|
1446
|
+
for (const cat of agg.topCategories.slice(0, 10)) {
|
|
1447
|
+
console.log(` ${chalk.bold(cat.category)}: ${cat.count}`);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
if (agg.crossProjectPatterns.length > 0) {
|
|
1451
|
+
console.log(chalk.cyan('\n Cross-Project Patterns:'));
|
|
1452
|
+
for (const p of agg.crossProjectPatterns.slice(0, 10)) {
|
|
1453
|
+
console.log(` ${chalk.bold(p.pattern)} — seen in ${p.projects} project(s)`);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
console.log();
|
|
1457
|
+
}
|
|
1458
|
+
catch (err) {
|
|
1459
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1460
|
+
process.exit(1);
|
|
1461
|
+
}
|
|
1462
|
+
});
|
|
1463
|
+
// ─── AST (Complexity Analysis) ────────────────────────────────────────────────
|
|
1464
|
+
const astCmd = new Command('ast')
|
|
1465
|
+
.description('Run AST-level complexity analysis — cyclomatic complexity, nesting, function size')
|
|
1466
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1467
|
+
.option('--json', 'Output as JSON')
|
|
1468
|
+
.option('--max-files <n>', 'Max files to analyze', '200')
|
|
1469
|
+
.action(async (projectDir, opts) => {
|
|
1470
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1471
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1472
|
+
try {
|
|
1473
|
+
console.log(chalk.cyan(' Running AST complexity analysis...'));
|
|
1474
|
+
const insights = await orchestrator.runASTAnalysis(parseInt(opts.maxFiles));
|
|
1475
|
+
if (opts.json) {
|
|
1476
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1477
|
+
return;
|
|
1478
|
+
}
|
|
1479
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN AST Analysis (${insights.length} findings)\n`));
|
|
1480
|
+
if (insights.length === 0) {
|
|
1481
|
+
console.log(chalk.green(' No complexity issues detected!'));
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1484
|
+
for (const insight of insights) {
|
|
1485
|
+
const color = insight.priority === 'critical' ? 'red' : insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1486
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1487
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1488
|
+
console.log(` ${insight.content.slice(0, 200)}${insight.content.length > 200 ? '...' : ''}`);
|
|
1489
|
+
console.log();
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
catch (err) {
|
|
1493
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1494
|
+
process.exit(1);
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1497
|
+
// ─── A11Y (Accessibility Audit) ──────────────────────────────────────────────
|
|
1498
|
+
const a11yCmd = new Command('a11y')
|
|
1499
|
+
.description('Run WCAG accessibility audit on frontend code')
|
|
1500
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1501
|
+
.option('--json', 'Output as JSON')
|
|
1502
|
+
.option('--max-files <n>', 'Max files to analyze', '200')
|
|
1503
|
+
.action(async (projectDir, opts) => {
|
|
1504
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1505
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1506
|
+
try {
|
|
1507
|
+
console.log(chalk.cyan(' Running accessibility audit...'));
|
|
1508
|
+
const insights = await orchestrator.runA11yCheck(parseInt(opts.maxFiles));
|
|
1509
|
+
if (opts.json) {
|
|
1510
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Accessibility Audit (${insights.length} issues)\n`));
|
|
1514
|
+
if (insights.length === 0) {
|
|
1515
|
+
console.log(chalk.green(' No accessibility issues found!'));
|
|
1516
|
+
return;
|
|
1517
|
+
}
|
|
1518
|
+
for (const insight of insights) {
|
|
1519
|
+
const color = insight.priority === 'critical' ? 'red' : insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1520
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1521
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1522
|
+
console.log(` ${insight.content.slice(0, 200)}${insight.content.length > 200 ? '...' : ''}`);
|
|
1523
|
+
console.log();
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
catch (err) {
|
|
1527
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1528
|
+
process.exit(1);
|
|
1529
|
+
}
|
|
1530
|
+
});
|
|
1531
|
+
// ─── I18N (Internationalization) ──────────────────────────────────────────────
|
|
1532
|
+
const i18nCmd = new Command('i18n')
|
|
1533
|
+
.description('Check internationalization readiness — hardcoded strings, locale support')
|
|
1534
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1535
|
+
.option('--json', 'Output as JSON')
|
|
1536
|
+
.option('--max-files <n>', 'Max files to analyze', '200')
|
|
1537
|
+
.action(async (projectDir, opts) => {
|
|
1538
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1539
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1540
|
+
try {
|
|
1541
|
+
console.log(chalk.cyan(' Running i18n readiness check...'));
|
|
1542
|
+
const insights = await orchestrator.runI18nAnalysis(parseInt(opts.maxFiles));
|
|
1543
|
+
if (opts.json) {
|
|
1544
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1547
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN i18n Analysis (${insights.length} findings)\n`));
|
|
1548
|
+
if (insights.length === 0) {
|
|
1549
|
+
console.log(chalk.green(' No i18n issues found!'));
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
for (const insight of insights) {
|
|
1553
|
+
const color = insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1554
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1555
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1556
|
+
console.log(` ${insight.content.slice(0, 200)}${insight.content.length > 200 ? '...' : ''}`);
|
|
1557
|
+
console.log();
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
catch (err) {
|
|
1561
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1562
|
+
process.exit(1);
|
|
1563
|
+
}
|
|
1564
|
+
});
|
|
1565
|
+
// ─── DEAD-CODE ────────────────────────────────────────────────────────────────
|
|
1566
|
+
const deadCodeCmd = new Command('dead-code')
|
|
1567
|
+
.description('Detect dead code — unreachable code, unused exports, unused variables')
|
|
1568
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1569
|
+
.option('--json', 'Output as JSON')
|
|
1570
|
+
.option('--max-files <n>', 'Max files to analyze', '200')
|
|
1571
|
+
.action(async (projectDir, opts) => {
|
|
1572
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1573
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1574
|
+
try {
|
|
1575
|
+
console.log(chalk.cyan(' Scanning for dead code...'));
|
|
1576
|
+
const insights = await orchestrator.runDeadCodeAnalysis(parseInt(opts.maxFiles));
|
|
1577
|
+
if (opts.json) {
|
|
1578
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1581
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Dead Code Detection (${insights.length} findings)\n`));
|
|
1582
|
+
if (insights.length === 0) {
|
|
1583
|
+
console.log(chalk.green(' No dead code detected!'));
|
|
1584
|
+
return;
|
|
1585
|
+
}
|
|
1586
|
+
for (const insight of insights) {
|
|
1587
|
+
const color = insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1588
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1589
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1590
|
+
console.log(` ${insight.content.slice(0, 200)}${insight.content.length > 200 ? '...' : ''}`);
|
|
1591
|
+
console.log();
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
catch (err) {
|
|
1595
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1596
|
+
process.exit(1);
|
|
1597
|
+
}
|
|
1598
|
+
});
|
|
1599
|
+
// ─── MUTATION (Mutation Testing Advisor) ──────────────────────────────────────
|
|
1600
|
+
const mutationCmd = new Command('mutation')
|
|
1601
|
+
.description('Suggest mutation testing cases — tests that would catch real bugs')
|
|
1602
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1603
|
+
.option('--json', 'Output as JSON')
|
|
1604
|
+
.option('--max-files <n>', 'Max files to analyze', '200')
|
|
1605
|
+
.action(async (projectDir, opts) => {
|
|
1606
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1607
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1608
|
+
try {
|
|
1609
|
+
console.log(chalk.cyan(' Running mutation testing advisor...'));
|
|
1610
|
+
const insights = await orchestrator.runMutationAnalysis(parseInt(opts.maxFiles));
|
|
1611
|
+
if (opts.json) {
|
|
1612
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Mutation Advisor (${insights.length} suggestions)\n`));
|
|
1616
|
+
if (insights.length === 0) {
|
|
1617
|
+
console.log(chalk.green(' No mutation suggestions — code looks well-tested or analysis found nothing!'));
|
|
1618
|
+
return;
|
|
1619
|
+
}
|
|
1620
|
+
for (const insight of insights) {
|
|
1621
|
+
const color = insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1622
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1623
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1624
|
+
console.log(` ${insight.content.slice(0, 200)}${insight.content.length > 200 ? '...' : ''}`);
|
|
1625
|
+
console.log();
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
catch (err) {
|
|
1629
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1630
|
+
process.exit(1);
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1633
|
+
// ─── CODE-AGE ─────────────────────────────────────────────────────────────────
|
|
1634
|
+
const codeAgeCmd = new Command('code-age')
|
|
1635
|
+
.description('Analyze code freshness — stale files, ownership, change frequency')
|
|
1636
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1637
|
+
.option('--json', 'Output as JSON')
|
|
1638
|
+
.action(async (projectDir, opts) => {
|
|
1639
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1640
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1641
|
+
try {
|
|
1642
|
+
console.log(chalk.cyan(' Analyzing code age and freshness...'));
|
|
1643
|
+
const insights = await orchestrator.runCodeAgeAnalysis();
|
|
1644
|
+
if (opts.json) {
|
|
1645
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1646
|
+
return;
|
|
1647
|
+
}
|
|
1648
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Code Age Analysis (${insights.length} findings)\n`));
|
|
1649
|
+
if (insights.length === 0) {
|
|
1650
|
+
console.log(chalk.green(' Code looks fresh and well-maintained!'));
|
|
1651
|
+
return;
|
|
1652
|
+
}
|
|
1653
|
+
for (const insight of insights) {
|
|
1654
|
+
const color = insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1655
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1656
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1657
|
+
console.log(` ${insight.content.slice(0, 200)}${insight.content.length > 200 ? '...' : ''}`);
|
|
1658
|
+
console.log();
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
catch (err) {
|
|
1662
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1663
|
+
process.exit(1);
|
|
1664
|
+
}
|
|
1665
|
+
});
|
|
1666
|
+
// ─── API (API Contract Analysis) ──────────────────────────────────────────────
|
|
1667
|
+
const apiCmd = new Command('api')
|
|
1668
|
+
.description('Analyze API contracts — endpoint discovery, security, consistency')
|
|
1669
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1670
|
+
.option('--json', 'Output as JSON')
|
|
1671
|
+
.option('--max-files <n>', 'Max files to analyze', '200')
|
|
1672
|
+
.action(async (projectDir, opts) => {
|
|
1673
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1674
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1675
|
+
try {
|
|
1676
|
+
console.log(chalk.cyan(' Running API contract analysis...'));
|
|
1677
|
+
const insights = await orchestrator.runAPIContractAnalysis(parseInt(opts.maxFiles));
|
|
1678
|
+
if (opts.json) {
|
|
1679
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1680
|
+
return;
|
|
1681
|
+
}
|
|
1682
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN API Contract Analysis (${insights.length} findings)\n`));
|
|
1683
|
+
if (insights.length === 0) {
|
|
1684
|
+
console.log(chalk.green(' No API contract issues detected!'));
|
|
1685
|
+
return;
|
|
1686
|
+
}
|
|
1687
|
+
for (const insight of insights) {
|
|
1688
|
+
const color = insight.priority === 'critical' ? 'red' : insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1689
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1690
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1691
|
+
console.log(` ${insight.content.slice(0, 200)}${insight.content.length > 200 ? '...' : ''}`);
|
|
1692
|
+
console.log();
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
catch (err) {
|
|
1696
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1697
|
+
process.exit(1);
|
|
1698
|
+
}
|
|
1699
|
+
});
|
|
1700
|
+
// ─── ENV (Environment Variable Analysis) ──────────────────────────────────────
|
|
1701
|
+
const envCmd = new Command('env')
|
|
1702
|
+
.description('Analyze environment variables — secrets, validation, naming conventions')
|
|
1703
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1704
|
+
.option('--json', 'Output as JSON')
|
|
1705
|
+
.option('--max-files <n>', 'Max files to analyze', '200')
|
|
1706
|
+
.action(async (projectDir, opts) => {
|
|
1707
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1708
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1709
|
+
try {
|
|
1710
|
+
console.log(chalk.cyan(' Analyzing environment variables...'));
|
|
1711
|
+
const insights = await orchestrator.runEnvAnalysis(parseInt(opts.maxFiles));
|
|
1712
|
+
if (opts.json) {
|
|
1713
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1714
|
+
return;
|
|
1715
|
+
}
|
|
1716
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Environment Analysis (${insights.length} findings)\n`));
|
|
1717
|
+
if (insights.length === 0) {
|
|
1718
|
+
console.log(chalk.green(' No environment variable issues detected!'));
|
|
1719
|
+
return;
|
|
1720
|
+
}
|
|
1721
|
+
for (const insight of insights) {
|
|
1722
|
+
const color = insight.priority === 'critical' ? 'red' : insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1723
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1724
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1725
|
+
console.log(` ${insight.content.slice(0, 200)}${insight.content.length > 200 ? '...' : ''}`);
|
|
1726
|
+
console.log();
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
catch (err) {
|
|
1730
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1731
|
+
process.exit(1);
|
|
1732
|
+
}
|
|
1733
|
+
});
|
|
1734
|
+
// ─── LICENSE (License Compliance) ─────────────────────────────────────────────
|
|
1735
|
+
const licenseCmd = new Command('license')
|
|
1736
|
+
.description('Audit dependency licenses — restricted, copyleft, unknown licenses')
|
|
1737
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1738
|
+
.option('--json', 'Output as JSON')
|
|
1739
|
+
.action(async (projectDir, opts) => {
|
|
1740
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1741
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1742
|
+
try {
|
|
1743
|
+
console.log(chalk.cyan(' Running license compliance audit...'));
|
|
1744
|
+
const insights = await orchestrator.runLicenseCompliance();
|
|
1745
|
+
if (opts.json) {
|
|
1746
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1747
|
+
return;
|
|
1748
|
+
}
|
|
1749
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN License Compliance (${insights.length} findings)\n`));
|
|
1750
|
+
if (insights.length === 0) {
|
|
1751
|
+
console.log(chalk.green(' All dependency licenses are compliant!'));
|
|
1752
|
+
return;
|
|
1753
|
+
}
|
|
1754
|
+
for (const insight of insights) {
|
|
1755
|
+
const color = insight.priority === 'critical' ? 'red' : insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1756
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1757
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1758
|
+
console.log(` ${insight.content.slice(0, 200)}${insight.content.length > 200 ? '...' : ''}`);
|
|
1759
|
+
console.log();
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
catch (err) {
|
|
1763
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1764
|
+
process.exit(1);
|
|
1765
|
+
}
|
|
1766
|
+
});
|
|
1767
|
+
// ─── CONFIG-DRIFT ─────────────────────────────────────────────────────────────
|
|
1768
|
+
const configDriftCmd = new Command('config-drift')
|
|
1769
|
+
.description('Detect configuration drift — missing configs, inconsistent settings')
|
|
1770
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1771
|
+
.option('--json', 'Output as JSON')
|
|
1772
|
+
.action(async (projectDir, opts) => {
|
|
1773
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1774
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1775
|
+
try {
|
|
1776
|
+
console.log(chalk.cyan(' Detecting configuration drift...'));
|
|
1777
|
+
const insights = await orchestrator.runConfigDriftDetection();
|
|
1778
|
+
if (opts.json) {
|
|
1779
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
1780
|
+
return;
|
|
1781
|
+
}
|
|
1782
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN Config Drift Detection (${insights.length} findings)\n`));
|
|
1783
|
+
if (insights.length === 0) {
|
|
1784
|
+
console.log(chalk.green(' No configuration drift detected!'));
|
|
1785
|
+
return;
|
|
1786
|
+
}
|
|
1787
|
+
for (const insight of insights) {
|
|
1788
|
+
const color = insight.priority === 'high' ? 'yellow' : 'blue';
|
|
1789
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1790
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1791
|
+
console.log(` ${insight.content.slice(0, 200)}${insight.content.length > 200 ? '...' : ''}`);
|
|
1792
|
+
console.log();
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
catch (err) {
|
|
1796
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1797
|
+
process.exit(1);
|
|
1798
|
+
}
|
|
1799
|
+
});
|
|
1800
|
+
// ─── HYPER (Full Hyper-Analysis) ──────────────────────────────────────────────
|
|
1801
|
+
const hyperCmd = new Command('hyper')
|
|
1802
|
+
.description('Run ALL v3.0.0 hyper-intelligence analyses at once')
|
|
1803
|
+
.argument('[project-dir]', 'Project directory', process.cwd())
|
|
1804
|
+
.option('--json', 'Output as JSON')
|
|
1805
|
+
.option('--max-files <n>', 'Max files per analysis', '200')
|
|
1806
|
+
.action(async (projectDir, opts) => {
|
|
1807
|
+
const brainConfig = mergeConfig({ projectDir, watchMode: false });
|
|
1808
|
+
const orchestrator = new Orchestrator(brainConfig);
|
|
1809
|
+
try {
|
|
1810
|
+
console.log(chalk.magenta.bold(`\n SHADOW BRAIN v${VERSION} — Hyper-Intelligence Full Scan\n`));
|
|
1811
|
+
console.log(chalk.cyan(' Running all 10 hyper-intelligence modules in parallel...'));
|
|
1812
|
+
console.log(chalk.dim(' This may take a moment for large projects.\n'));
|
|
1813
|
+
const results = await orchestrator.runFullHyperAnalysis({
|
|
1814
|
+
maxFiles: parseInt(opts.maxFiles),
|
|
1815
|
+
});
|
|
1816
|
+
if (opts.json) {
|
|
1817
|
+
console.log(JSON.stringify(results, null, 2));
|
|
1818
|
+
return;
|
|
1819
|
+
}
|
|
1820
|
+
const modules = [
|
|
1821
|
+
{ name: 'ast', label: 'AST Complexity', insights: results.ast },
|
|
1822
|
+
{ name: 'a11y', label: 'Accessibility (WCAG)', insights: results.a11y },
|
|
1823
|
+
{ name: 'i18n', label: 'Internationalization', insights: results.i18n },
|
|
1824
|
+
{ name: 'deadCode', label: 'Dead Code', insights: results.deadCode },
|
|
1825
|
+
{ name: 'mutation', label: 'Mutation Testing', insights: results.mutation },
|
|
1826
|
+
{ name: 'codeAge', label: 'Code Age', insights: results.codeAge },
|
|
1827
|
+
{ name: 'apiContract', label: 'API Contracts', insights: results.apiContract },
|
|
1828
|
+
{ name: 'env', label: 'Environment Variables', insights: results.env },
|
|
1829
|
+
{ name: 'license', label: 'License Compliance', insights: results.license },
|
|
1830
|
+
{ name: 'configDrift', label: 'Config Drift', insights: results.configDrift },
|
|
1831
|
+
];
|
|
1832
|
+
for (const mod of modules) {
|
|
1833
|
+
const count = mod.insights.length;
|
|
1834
|
+
const color = count === 0 ? 'green' : count < 5 ? 'yellow' : 'red';
|
|
1835
|
+
const icon = count === 0 ? '✓' : '⚠';
|
|
1836
|
+
console.log(chalk ` {${color}.bold ${icon}} ${chalk.bold(mod.label)}: ${count} finding(s)`);
|
|
1837
|
+
}
|
|
1838
|
+
console.log(chalk.bold(`\n Total findings: ${results.total}\n`));
|
|
1839
|
+
// Show critical/high priority details
|
|
1840
|
+
const allCritical = modules.flatMap(m => m.insights.filter(i => i.priority === 'critical' || i.priority === 'high'));
|
|
1841
|
+
if (allCritical.length > 0) {
|
|
1842
|
+
console.log(chalk.red.bold(` Critical/High Priority (${allCritical.length}):\n`));
|
|
1843
|
+
for (const insight of allCritical.slice(0, 20)) {
|
|
1844
|
+
const color = insight.priority === 'critical' ? 'red' : 'yellow';
|
|
1845
|
+
console.log(chalk ` {${color}.bold [${insight.priority.toUpperCase()}]} ${insight.title}`);
|
|
1846
|
+
console.log(chalk.dim(` Files: ${insight.files?.join(', ') || 'none'}`));
|
|
1847
|
+
console.log();
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
catch (err) {
|
|
1852
|
+
console.error(chalk.red(' Error:'), err.message);
|
|
1853
|
+
process.exit(1);
|
|
1854
|
+
}
|
|
1855
|
+
});
|
|
885
1856
|
// ─── MAIN ─────────────────────────────────────────────────────────────────────
|
|
886
1857
|
const program = new Command();
|
|
887
1858
|
program
|
|
888
1859
|
.name('shadow-brain')
|
|
889
|
-
.description('Shadow Brain — AI
|
|
1860
|
+
.description('Shadow Brain v3.0.0 — Hyper-Intelligence Layer for AI Coding Agents with Quantum Neural Mesh')
|
|
890
1861
|
.version(VERSION);
|
|
891
1862
|
program.addCommand(startCmd);
|
|
892
1863
|
program.addCommand(reviewCmd);
|
|
@@ -907,5 +1878,29 @@ program.addCommand(prCmd);
|
|
|
907
1878
|
program.addCommand(commitMsgCmd);
|
|
908
1879
|
program.addCommand(rulesCmd);
|
|
909
1880
|
program.addCommand(notifyCmd);
|
|
1881
|
+
// v2.0.0 commands
|
|
1882
|
+
program.addCommand(mcpCmd);
|
|
1883
|
+
program.addCommand(teamCmd);
|
|
1884
|
+
program.addCommand(projectsCmd);
|
|
1885
|
+
program.addCommand(semanticCmd);
|
|
1886
|
+
program.addCommand(depsCmd);
|
|
1887
|
+
program.addCommand(dupesCmd);
|
|
1888
|
+
program.addCommand(perfCmd);
|
|
1889
|
+
program.addCommand(contextCmd);
|
|
1890
|
+
program.addCommand(learnCmd);
|
|
1891
|
+
// v2.1.0 commands
|
|
1892
|
+
program.addCommand(meshCmd);
|
|
1893
|
+
// v3.0.0 hyper-intelligence commands
|
|
1894
|
+
program.addCommand(astCmd);
|
|
1895
|
+
program.addCommand(a11yCmd);
|
|
1896
|
+
program.addCommand(i18nCmd);
|
|
1897
|
+
program.addCommand(deadCodeCmd);
|
|
1898
|
+
program.addCommand(mutationCmd);
|
|
1899
|
+
program.addCommand(codeAgeCmd);
|
|
1900
|
+
program.addCommand(apiCmd);
|
|
1901
|
+
program.addCommand(envCmd);
|
|
1902
|
+
program.addCommand(licenseCmd);
|
|
1903
|
+
program.addCommand(configDriftCmd);
|
|
1904
|
+
program.addCommand(hyperCmd);
|
|
910
1905
|
program.parse();
|
|
911
1906
|
//# sourceMappingURL=cli.js.map
|