@syke1/mcp-server 1.6.0 → 1.7.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.
@@ -1 +1,326 @@
1
- 'use strict';const _0x272b69=_0x3b2f;(function(_0x33167a,_0x2ef849){const _0x47a745={_0x363b3d:0x9c,_0x345971:0xab,_0x324829:0xa8,_0x54972e:0xe6,_0x5407e7:0xd3},_0x5ebf64=_0x3b2f,_0x18d1bc=_0x33167a();while(!![]){try{const _0xad2bf0=-parseInt(_0x5ebf64(0xc6))/0x1*(-parseInt(_0x5ebf64(0x95))/0x2)+parseInt(_0x5ebf64(_0x47a745._0x363b3d))/0x3*(-parseInt(_0x5ebf64(0xc2))/0x4)+parseInt(_0x5ebf64(0xeb))/0x5+-parseInt(_0x5ebf64(_0x47a745._0x345971))/0x6*(-parseInt(_0x5ebf64(0xb1))/0x7)+parseInt(_0x5ebf64(_0x47a745._0x324829))/0x8+-parseInt(_0x5ebf64(0xbb))/0x9*(parseInt(_0x5ebf64(_0x47a745._0x54972e))/0xa)+parseInt(_0x5ebf64(0xd4))/0xb*(parseInt(_0x5ebf64(_0x47a745._0x5407e7))/0xc);if(_0xad2bf0===_0x2ef849)break;else _0x18d1bc['push'](_0x18d1bc['shift']());}catch(_0x512d04){_0x18d1bc['push'](_0x18d1bc['shift']());}}}(_0x53c8,0xc2f71));var __createBinding=this&&this['__createBinding']||(Object[_0x272b69(0x9b)]?function(_0x44c5c8,_0x1ea3cb,_0xa5cba6,_0xe9837f){const _0x4f8508={_0xd397d2:0xb2,_0x268202:0xb5,_0x4f13ee:0xce,_0x3bedc8:0xc5,_0x38e2e5:0xdc},_0x3183fb=_0x272b69,_0x56bdb0={};_0x56bdb0['uxrnA']=function(_0x18ee2a,_0x1fd33f){return _0x18ee2a in _0x1fd33f;},_0x56bdb0[_0x3183fb(_0x4f8508._0xd397d2)]='get';const _0x47bdb0=_0x56bdb0;if(_0xe9837f===undefined)_0xe9837f=_0xa5cba6;var _0x1ecb38=Object[_0x3183fb(_0x4f8508._0x268202)](_0x1ea3cb,_0xa5cba6);if(!_0x1ecb38||(_0x47bdb0[_0x3183fb(0xb0)](_0x47bdb0[_0x3183fb(0xb2)],_0x1ecb38)?!_0x1ea3cb[_0x3183fb(_0x4f8508._0x4f13ee)]:_0x1ecb38[_0x3183fb(_0x4f8508._0x3bedc8)]||_0x1ecb38[_0x3183fb(_0x4f8508._0x38e2e5)])){const _0xb46358={};_0xb46358['enumerable']=!![],_0xb46358[_0x3183fb(0xee)]=function(){return _0x1ea3cb[_0xa5cba6];},_0x1ecb38=_0xb46358;}Object['defineProperty'](_0x44c5c8,_0xe9837f,_0x1ecb38);}:function(_0x382578,_0x2c274e,_0x18edfe,_0x2fbdda){if(_0x2fbdda===undefined)_0x2fbdda=_0x18edfe;_0x382578[_0x2fbdda]=_0x2c274e[_0x18edfe];}),__setModuleDefault=this&&this[_0x272b69(0x99)]||(Object['create']?function(_0x17c29a,_0x106b7f){const _0x2ba2d5={_0x3b1dbf:0xdd,_0x5c4ae6:0xda},_0x36cba6=_0x272b69,_0x260452={};_0x260452['enumerable']=!![],_0x260452[_0x36cba6(_0x2ba2d5._0x3b1dbf)]=_0x106b7f,Object['defineProperty'](_0x17c29a,_0x36cba6(_0x2ba2d5._0x5c4ae6),_0x260452);}:function(_0xad2233,_0x24c1f6){const _0x228b5f=_0x272b69;_0xad2233[_0x228b5f(0xda)]=_0x24c1f6;}),__importStar=this&&this[_0x272b69(0xe2)]||(function(){const _0x5e102d={_0x542115:0xda,_0x413131:0xaa},_0x568e28={_0x18c953:0xa4},_0x535bce={_0x1c6f62:0xe4},_0x1600a6={'vmzXZ':function(_0x4b0035,_0x20f2f2){return _0x4b0035(_0x20f2f2);},'Nojje':function(_0x5a962b,_0x3f08b9){return _0x5a962b!=_0x3f08b9;},'onKgc':function(_0x440623,_0x273a1a){return _0x440623!==_0x273a1a;},'PDSIR':function(_0x19caeb,_0x4ae830,_0x55d4e1,_0x1cea00){return _0x19caeb(_0x4ae830,_0x55d4e1,_0x1cea00);},'QvNVH':function(_0xc8e315,_0x4e0ced,_0x39326a){return _0xc8e315(_0x4e0ced,_0x39326a);}};var _0x47ae2=function(_0x1e1ba9){const _0x19e49d=_0x3b2f;return _0x47ae2=Object['getOwnPropertyNames']||function(_0x1ffc82){const _0x3c0465=_0x3b2f;var _0x427cbc=[];for(var _0x55143b in _0x1ffc82)if(Object['prototype']['hasOwnProperty'][_0x3c0465(_0x535bce._0x1c6f62)](_0x1ffc82,_0x55143b))_0x427cbc[_0x427cbc[_0x3c0465(0xaf)]]=_0x55143b;return _0x427cbc;},_0x1600a6[_0x19e49d(_0x568e28._0x18c953)](_0x47ae2,_0x1e1ba9);};return function(_0x47e02a){const _0x151350=_0x3b2f;if(_0x47e02a&&_0x47e02a['__esModule'])return _0x47e02a;var _0xa3b2b8={};if(_0x1600a6[_0x151350(0xbd)](_0x47e02a,null)){for(var _0x34607e=_0x1600a6['vmzXZ'](_0x47ae2,_0x47e02a),_0x5cd02=0x0;_0x5cd02<_0x34607e['length'];_0x5cd02++)if(_0x1600a6['onKgc'](_0x34607e[_0x5cd02],_0x151350(_0x5e102d._0x542115)))_0x1600a6[_0x151350(0x94)](__createBinding,_0xa3b2b8,_0x47e02a,_0x34607e[_0x5cd02]);}return _0x1600a6[_0x151350(_0x5e102d._0x413131)](__setModuleDefault,_0xa3b2b8,_0x47e02a),_0xa3b2b8;};}());function _0x53c8(){const _0x4712d8=['zMLSzunVBNrLBNq','uertsvi','mJiZnJq3ne5rtwP2vG','CMvSyxrPDMu','C2HPzNq','y29TChv0zvbYB2PLy3rnzxrYAwnZ','x19ZzxrnB2r1BgvezwzHDwX0','zMLSDgvY','y3jLyxrL','m2HLEwjcBq','zMLSzxm','Bgv2zwW','Aw1Wywn0u2v0','Exfntei','qw5jCeK','zMLSzq','CMLZA0XLDMvS','DM16wfO','te9x','BM9Kzxm','AxndEwnSAwm','mJm2odi0ofznEgvAra','tLLuu3y','uxzovKG','nZa0ndyWquHpqKTS','ywrK','C2v0','Aw5ezxbLBMrLBMn5r3jHCgG','BgvUz3rO','DxHYBKe','mtrjwurPvuG','yuXNruO','v1HZwuy','zMLSzte','z2v0t3DUuhjVCgvYDhLezxnJCMLWDg9Y','CwTPAKm','zxjYB3i','ChjVAMvJDfjVB3q','C2nJ','C291CMnLrgLY','mZzTA3nLy3u','tK9orq','tM9QAMu','zM9YD2fYza','z2v0twvTB0nHy2HL','uuzuy2i','lI4Vz2L0l2nOyw5Nzs1JB3vWBgLUzW','ntGWmdyYnhnrthL5CW','vLzhrhy','seLhsa','D3jPDgfIBgu','mvHyqvnHuW','C2XPy2u','CMv2zxjZzq','y29dAgfUz2vdB3vUDa','BwfW','AgfZ','zMLSzti','ChvZAa','x19LC01VzhvSzq','tuvesvvn','zgLYzwn0q291BNq','CNLJAgG','w3n5A2u6C2nVCMLUz10GrMfPBgvKihrVignVBxb1DguGCMLZAYbZy29YzsbMB3iG','mte2mtm3nJH6t1DYt0y','mtf6vvv4A1u','zgLYzwn0rgvWzw5Kzw50CW','y2XHC3nPzNLsAxnR','BM9YBwfSAxPL','CMvWBgfJzq','z2v0uMLZA1nJB3jL','zgvMyxvSDa','y291CgXLzezPBgvZ','y29UzMLNDxjHyMXL','DMfSDwu','EwDjteK','y29UzMLKzw5Jzq','DhrhtMO','w3n5A2u6y291CgXPBMDDiezHAwXLzcb0BYbJB21WDxrLignOyw5NzsbJB3vWBgLUzYbMB3iG','x19PBxbVCNrtDgfY','C2nJswr4','y2fSBa','AM9PBG','mta1nJa3menJzvf2zW','y291BNq','C29YDa','C2L6zq','z2v0q291CgXLzezPBgvZ','mJCXmJK1swnAzgH3','lI4VC2nVCMLUzY9YAxnRlxnJB3jLCG','u0fgrq','z2v0','CMvSyxrPDMvqyxrO','y2fZy2fKzuXLDMvSCW','BM93'];_0x53c8=function(){return _0x4712d8;};return _0x53c8();}const _0xdd9ac0={};_0xdd9ac0['value']=!![],Object['defineProperty'](exports,_0x272b69(0xce),_0xdd9ac0),exports['analyzeImpact']=analyzeImpact,exports['getImpactMemoCache']=getImpactMemoCache,exports[_0x272b69(0xd6)]=classifyRisk,exports['getHubFiles']=getHubFiles;const path=__importStar(require('path')),risk_scorer_1=require(_0x272b69(0xec)),change_coupling_1=require(_0x272b69(0xc1)),memo_cache_1=require('../graph/memo-cache');async function analyzeImpact(_0x18d7d1,_0x3dbf0a,_0x468d21){const _0x5b7ea3={_0x4e3534:0xee,_0x452109:0xee,_0x351f2e:0x9f,_0x37ea57:0x91,_0x3ab7a5:0x98,_0x52cc78:0xa3,_0x3409e3:0xdb,_0x28776a:0xe1,_0x3c002f:0xd5,_0x568f5d:0xad,_0x33c478:0xaf,_0x43bede:0x92,_0x66a2db:0xd9,_0x22d808:0xa3},_0x3b22aa=_0x272b69,_0x50e338={'kydXK':function(_0x2ac152,_0x25d696,_0x189e21,_0x539c04){return _0x2ac152(_0x25d696,_0x189e21,_0x539c04);}},_0x5bd930=path[_0x3b22aa(0xd7)](_0x18d7d1),_0x285c3b=_0x7846fb=>path['relative'](_0x3dbf0a['sourceDir'],_0x7846fb)['replace'](/\\/g,'/'),_0x46f1ef=(0x0,memo_cache_1['getMemoCache'])(),_0x5d2b70=_0x46f1ef[_0x3b22aa(_0x5b7ea3._0x4e3534)](_0x5bd930);if(_0x5d2b70){const _0xca0d43=(_0x3dbf0a['reverse'][_0x3b22aa(_0x5b7ea3._0x452109)](_0x5bd930)||[])['map'](_0x285c3b),_0x2a26ed=new Set(_0xca0d43),_0x4cbf23=_0x5d2b70[_0x3b22aa(_0x5b7ea3._0x351f2e)]['map'](_0x615b8c=>_0x285c3b(_0x615b8c))[_0x3b22aa(0x9a)](_0x2dad17=>!_0x2a26ed['has'](_0x2dad17));let _0x6e522={'filePath':_0x5bd930,'relativePath':_0x285c3b(_0x5bd930),'riskLevel':_0x5d2b70['riskLevel'],'directDependents':_0xca0d43,'transitiveDependents':_0x4cbf23,'totalImpacted':_0x5d2b70[_0x3b22aa(0xd0)]+_0x5d2b70['transitiveCount'],'cascadeLevels':_0x5d2b70[_0x3b22aa(_0x5b7ea3._0x37ea57)],'fromCache':!![]};if(_0x468d21?.['includeRiskScore']&&_0x3dbf0a[_0x3b22aa(0x9d)]['has'](_0x5bd930))try{(0x0,risk_scorer_1[_0x3b22aa(_0x5b7ea3._0x3ab7a5)])(_0x3dbf0a);const _0x2ce322=(0x0,risk_scorer_1['getRiskScore'])(_0x5bd930,_0x3dbf0a,_0x468d21[_0x3b22aa(0x93)]??null);_0x6e522['riskScore']=_0x2ce322;const _0x362e02=_0x2ce322[_0x3b22aa(0xa3)];isHigherRisk(_0x362e02,_0x6e522[_0x3b22aa(_0x5b7ea3._0x52cc78)])&&(_0x6e522[_0x3b22aa(0xa3)]=mapCompositeToLegacy(_0x362e02));}catch(_0x5f2265){console['error']('[syke:scoring]\x20Failed\x20to\x20compute\x20risk\x20score\x20for\x20'+_0x18d7d1+':\x20'+_0x5f2265);}if(_0x468d21?.['includeCoupling'])try{const _0x3e3cb6=await computeCoupledFiles(_0x5bd930,_0x3dbf0a,_0x285c3b);_0x3e3cb6['length']>0x0&&(_0x6e522[_0x3b22aa(_0x5b7ea3._0x3409e3)]=_0x3e3cb6);}catch(_0x5c8e1a){console['error'](_0x3b22aa(_0x5b7ea3._0x28776a)+_0x18d7d1+':\x20'+_0x5c8e1a);}return _0x6e522;}let _0x5eb5c9;_0x3dbf0a['scc']?_0x5eb5c9=analyzeImpactWithSCC(_0x5bd930,_0x3dbf0a,_0x285c3b):_0x5eb5c9=analyzeImpactBFS(_0x5bd930,_0x3dbf0a,_0x285c3b);const _0xacbe04=[..._0x5eb5c9[_0x3b22aa(_0x5b7ea3._0x3c002f)],..._0x5eb5c9['transitiveDependents']][_0x3b22aa(0xca)](_0x1810fd=>path[_0x3b22aa(0xd7)](path[_0x3b22aa(0xe5)](_0x3dbf0a['sourceDir'],_0x1810fd)));_0x46f1ef[_0x3b22aa(_0x5b7ea3._0x568f5d)](_0x5bd930,{'impactSet':_0xacbe04,'directCount':_0x5eb5c9['directDependents']['length'],'transitiveCount':_0x5eb5c9['transitiveDependents'][_0x3b22aa(_0x5b7ea3._0x33c478)],'riskLevel':_0x5eb5c9[_0x3b22aa(_0x5b7ea3._0x52cc78)],'cascadeLevels':_0x5eb5c9['cascadeLevels'],'computedAt':Date[_0x3b22aa(_0x5b7ea3._0x43bede)]()});if(_0x468d21?.['includeRiskScore']&&_0x3dbf0a['files']['has'](_0x5bd930))try{(0x0,risk_scorer_1['computeProjectMetrics'])(_0x3dbf0a);const _0x15258d=(0x0,risk_scorer_1[_0x3b22aa(_0x5b7ea3._0x66a2db)])(_0x5bd930,_0x3dbf0a,_0x468d21['fileContent']??null);_0x5eb5c9['riskScore']=_0x15258d;const _0x52cd2b=_0x15258d['riskLevel'];isHigherRisk(_0x52cd2b,_0x5eb5c9[_0x3b22aa(_0x5b7ea3._0x22d808)])&&(_0x5eb5c9['riskLevel']=mapCompositeToLegacy(_0x52cd2b));}catch(_0x34d9d5){console[_0x3b22aa(0xb7)](_0x3b22aa(0xd2)+_0x18d7d1+':\x20'+_0x34d9d5);}if(_0x468d21?.['includeCoupling'])try{const _0x5aead8=await _0x50e338['kydXK'](computeCoupledFiles,_0x5bd930,_0x3dbf0a,_0x285c3b);_0x5aead8[_0x3b22aa(0xaf)]>0x0&&(_0x5eb5c9['coupledFiles']=_0x5aead8);}catch(_0x714a87){console['error']('[syke:coupling]\x20Failed\x20to\x20compute\x20change\x20coupling\x20for\x20'+_0x18d7d1+':\x20'+_0x714a87);}return _0x5eb5c9;}async function computeCoupledFiles(_0x241485,_0x2b4525,_0x5ca159){const _0x41ad80={_0x57704a:0xbe,_0xa66b97:0xac,_0x269177:0x96,_0x466903:0xb8,_0x4cf295:0xd8,_0x4029b8:0xc8,_0x4fd9c9:0xee,_0x364bcc:0xb4,_0x1ca11d:0xcb,_0x5c3e65:0xd7,_0x383a8a:0xe0,_0x155e72:0xdf,_0x23135d:0xc9,_0x1e2a06:0xcd},_0x5ebf39=_0x272b69,_0x3b8452={'UTdFq':function(_0x5b9a49,_0x280a47){return _0x5b9a49===_0x280a47;},'bYYQb':function(_0x49fe06,_0x58a759){return _0x49fe06===_0x58a759;},'ttGNj':function(_0x255eeb,_0x22e980){return _0x255eeb(_0x22e980);}},_0x36b25d=await(0x0,change_coupling_1['mineGitHistory'])(_0x2b4525['projectRoot']);if(_0x3b8452['UTdFq'](_0x36b25d['totalCommitsAnalyzed'],0x0))return[];const _0x657637=path['relative'](_0x2b4525['projectRoot'],_0x241485)[_0x5ebf39(0xd8)](/\\/g,'/'),_0x14a520=(0x0,change_coupling_1[_0x5ebf39(0xea)])(_0x657637,_0x36b25d);if(_0x14a520['length']===0x0)return[];const _0x567243=new Set(),_0x241dd4=_0x2b4525[_0x5ebf39(_0x41ad80._0x57704a)][_0x5ebf39(0xee)](_0x241485)||[];for(const _0x471d5d of _0x241dd4){_0x567243[_0x5ebf39(_0x41ad80._0xa66b97)](path[_0x5ebf39(_0x41ad80._0x269177)](_0x2b4525[_0x5ebf39(_0x41ad80._0x466903)],_0x471d5d)[_0x5ebf39(_0x41ad80._0x4cf295)](/\\/g,'/'));}const _0xb35b5a=_0x2b4525[_0x5ebf39(_0x41ad80._0x4029b8)][_0x5ebf39(_0x41ad80._0x4fd9c9)](_0x241485)||[];for(const _0x40fe29 of _0xb35b5a){_0x567243[_0x5ebf39(0xac)](path['relative'](_0x2b4525['projectRoot'],_0x40fe29)[_0x5ebf39(0xd8)](/\\/g,'/'));}const _0x49effb=[];for(const _0x4efe3d of _0x14a520){const _0x453f1d=_0x3b8452['bYYQb'](_0x4efe3d['file1'],_0x657637)?_0x4efe3d[_0x5ebf39(0xcc)]:_0x4efe3d[_0x5ebf39(_0x41ad80._0x364bcc)],_0x2437d7=_0x567243[_0x5ebf39(_0x41ad80._0x1ca11d)](_0x453f1d),_0x1f67e6=path[_0x5ebf39(_0x41ad80._0x5c3e65)](path[_0x5ebf39(0xe5)](_0x2b4525['projectRoot'],_0x453f1d)),_0x2c6e50=_0x3b8452[_0x5ebf39(_0x41ad80._0x383a8a)](_0x5ca159,_0x1f67e6),_0x3efcd6={};_0x3efcd6[_0x5ebf39(0x90)]=_0x2c6e50,_0x3efcd6[_0x5ebf39(_0x41ad80._0x155e72)]=_0x4efe3d[_0x5ebf39(0xdf)],_0x3efcd6['coChangeCount']=_0x4efe3d[_0x5ebf39(_0x41ad80._0x23135d)],_0x3efcd6['inDependencyGraph']=_0x2437d7,_0x49effb[_0x5ebf39(_0x41ad80._0x1e2a06)](_0x3efcd6);}const _0x111fdd=_0x49effb['filter'](_0x56771b=>!_0x56771b[_0x5ebf39(0xae)]);return _0x111fdd[_0x5ebf39(0xc7)](0x0,0x5);}function isHigherRisk(_0x5ad829,_0x405f00){const _0x4f6ef1={_0x1b950c:0xa5,_0xd722be:0xed,_0x534c0b:0xcf},_0x49f80e=_0x272b69,_0x54284c={};_0x54284c['ygILI']=function(_0xc75b4c,_0x280920){return _0xc75b4c>_0x280920;};const _0x190a3e=_0x54284c,_0x965bbe={};_0x965bbe['CRITICAL']=0x4,_0x965bbe[_0x49f80e(0xc4)]=0x3,_0x965bbe[_0x49f80e(0xcf)]=0x2,_0x965bbe[_0x49f80e(_0x4f6ef1._0x1b950c)]=0x1,_0x965bbe[_0x49f80e(_0x4f6ef1._0xd722be)]=0x0;const _0x43a6b0=_0x965bbe,_0x1cf4d8={};_0x1cf4d8[_0x49f80e(0xc4)]=0x3,_0x1cf4d8[_0x49f80e(_0x4f6ef1._0x534c0b)]=0x2,_0x1cf4d8['LOW']=0x1,_0x1cf4d8['NONE']=0x0;const _0x2e6287=_0x1cf4d8;return _0x190a3e[_0x49f80e(0xde)](_0x43a6b0[_0x5ad829]||0x0,_0x2e6287[_0x405f00]||0x0);}function mapCompositeToLegacy(_0x344895){const _0xb41601={_0xf2efc5:0xa0,_0x3097fc:0xbc},_0x55bd87=_0x272b69,_0x362ad3={};_0x362ad3[_0x55bd87(_0xb41601._0xf2efc5)]='CRITICAL',_0x362ad3[_0x55bd87(0xb6)]='HIGH',_0x362ad3[_0x55bd87(0xb3)]=_0x55bd87(0xcf);const _0xb145b7=_0x362ad3;switch(_0x344895){case _0xb145b7['yqMLB']:return'HIGH';case'HIGH':return _0xb145b7['qkijC'];case _0xb145b7['WXsYF']:return _0xb145b7['WXsYF'];case _0x55bd87(0xa5):return'LOW';case _0x55bd87(0xed):return _0x55bd87(_0xb41601._0x3097fc);}}function analyzeImpactBFS(_0x3db0bd,_0x4bdaa0,_0x3c15d1){const _0x4790e0={_0x33a480:0xee,_0x46e1bd:0xac,_0x6bde49:0xcd,_0x4a5ea5:0xca},_0x423642=_0x272b69,_0x3f3f8e=_0x4bdaa0['reverse'][_0x423642(0xee)](_0x3db0bd)||[],_0x251db4=new Set(),_0x550f19=[..._0x3f3f8e];for(const _0x877bd1 of _0x3f3f8e){_0x251db4[_0x423642(0xac)](_0x877bd1);}while(_0x550f19[_0x423642(0xaf)]>0x0){const _0x11a7db=_0x550f19[_0x423642(0x97)](),_0x2cf008=_0x4bdaa0['reverse'][_0x423642(_0x4790e0._0x33a480)](_0x11a7db)||[];for(const _0x32d0f5 of _0x2cf008){!_0x251db4[_0x423642(0xcb)](_0x32d0f5)&&_0x32d0f5!==_0x3db0bd&&(_0x251db4[_0x423642(_0x4790e0._0x46e1bd)](_0x32d0f5),_0x550f19[_0x423642(_0x4790e0._0x6bde49)](_0x32d0f5));}}const _0x2c1143=_0x251db4['size'],_0xabf9ca=new Set(_0x3f3f8e),_0x41ab0a=[..._0x251db4]['filter'](_0x60169c=>!_0xabf9ca['has'](_0x60169c)),_0x3140a6=classifyRisk(_0x2c1143);return{'filePath':_0x3db0bd,'relativePath':_0x3c15d1(_0x3db0bd),'riskLevel':_0x3140a6,'directDependents':_0x3f3f8e['map'](_0x3c15d1),'transitiveDependents':_0x41ab0a[_0x423642(_0x4790e0._0x4a5ea5)](_0x3c15d1),'totalImpacted':_0x2c1143};}function analyzeImpactWithSCC(_0x5c5079,_0x5bb250,_0x2251f3){const _0x4ec7ea={_0x194e3c:0xb9,_0x2824b8:0xa7,_0x1e2d53:0x9a,_0xdc27c1:0xe3,_0x478bea:0x9e,_0x23128d:0xc3,_0x1bfe30:0xad,_0x42298c:0xcd,_0x94abdb:0xac,_0x5c8f74:0xa7,_0x5c615e:0xca,_0xe2eafa:0x9a},_0x4a6ab7=_0x272b69,_0x2760cc={'jqgPk':function(_0x5579ac,_0x325b18){return _0x5579ac===_0x325b18;},'ZgSyU':function(_0x54148b,_0x42dced,_0x384df8,_0x44366f){return _0x54148b(_0x42dced,_0x384df8,_0x44366f);},'VVGDv':function(_0x2a31f6,_0x51432b){return _0x2a31f6>_0x51432b;},'vqjll':function(_0x12a082,_0x4c2f38){return _0x12a082!==_0x4c2f38;},'sasqM':function(_0x38fe5f,_0x5f4e8f){return _0x38fe5f(_0x5f4e8f);},'zCciv':function(_0x1d462e,_0x49d9b2){return _0x1d462e(_0x49d9b2);}},_0x12f51e=_0x5bb250[_0x4a6ab7(_0x4ec7ea._0x194e3c)],{nodeToComponent:_0x16a53c,condensed:_0x43d738}=_0x12f51e,_0x54a4e0=_0x16a53c['get'](_0x5c5079);if(_0x2760cc['jqgPk'](_0x54a4e0,undefined))return _0x2760cc['ZgSyU'](analyzeImpactBFS,_0x5c5079,_0x5bb250,_0x2251f3);const _0x10d940=_0x43d738['nodes'][_0x54a4e0],_0x2958ad=_0x10d940[_0x4a6ab7(_0x4ec7ea._0x2824b8)]?_0x10d940['files'][_0x4a6ab7(_0x4ec7ea._0x1e2d53)](_0x2dedd4=>_0x2dedd4!==_0x5c5079)[_0x4a6ab7(0xca)](_0x2251f3):undefined,_0x360a47=new Map();_0x360a47['set'](_0x54a4e0,0x0);const _0x4c2505={};_0x4c2505[_0x4a6ab7(_0x4ec7ea._0xdc27c1)]=_0x54a4e0,_0x4c2505[_0x4a6ab7(_0x4ec7ea._0x478bea)]=0x0;const _0x4255b0=[_0x4c2505];while(_0x2760cc[_0x4a6ab7(_0x4ec7ea._0x23128d)](_0x4255b0['length'],0x0)){const {sccIdx:_0x3ab84d,level:_0x322a89}=_0x4255b0[_0x4a6ab7(0x97)](),_0x4039e5=_0x43d738['reverse']['get'](_0x3ab84d)||[];for(const _0x3800fb of _0x4039e5){if(!_0x360a47['has'](_0x3800fb)){_0x360a47[_0x4a6ab7(_0x4ec7ea._0x1bfe30)](_0x3800fb,_0x322a89+0x1);const _0x52016b={};_0x52016b[_0x4a6ab7(_0x4ec7ea._0xdc27c1)]=_0x3800fb,_0x52016b[_0x4a6ab7(0x9e)]=_0x322a89+0x1,_0x4255b0[_0x4a6ab7(_0x4ec7ea._0x42298c)](_0x52016b);}}}const _0xf73318=new Map(),_0x14b772=new Set();for(const [_0x49db21,_0x3341a6]of _0x360a47){const _0x308514=_0x43d738[_0x4a6ab7(0xa6)][_0x49db21];for(const _0x28fef2 of _0x308514['files']){if(_0x28fef2===_0x5c5079)continue;_0x14b772[_0x4a6ab7(_0x4ec7ea._0x94abdb)](_0x28fef2),_0xf73318['set'](_0x28fef2,_0x3341a6);}}const _0x30d406=_0x5bb250[_0x4a6ab7(0xc8)]['get'](_0x5c5079)||[],_0x3ca08e=new Set(_0x30d406);if(_0x10d940[_0x4a6ab7(_0x4ec7ea._0x5c8f74)])for(const _0x3c69a0 of _0x10d940['files']){_0x2760cc['vqjll'](_0x3c69a0,_0x5c5079)&&_0x3ca08e['add'](_0x3c69a0);}const _0x507e7d=[..._0x14b772][_0x4a6ab7(0x9a)](_0xca5546=>_0x3ca08e['has'](_0xca5546)),_0x2c4e84=[..._0x14b772]['filter'](_0x3e1f67=>!_0x3ca08e[_0x4a6ab7(0xcb)](_0x3e1f67)),_0x37fea1=_0x14b772[_0x4a6ab7(0xe9)],_0x32e43b=_0x2760cc['sasqM'](classifyRisk,_0x37fea1),_0x5f02bc=new Map();for(const [_0x62ba02,_0x19a576]of _0xf73318){_0x5f02bc['set'](_0x2760cc['zCciv'](_0x2251f3,_0x62ba02),_0x19a576);}return{'filePath':_0x5c5079,'relativePath':_0x2251f3(_0x5c5079),'riskLevel':_0x32e43b,'directDependents':_0x507e7d['map'](_0x2251f3),'transitiveDependents':_0x2c4e84[_0x4a6ab7(_0x4ec7ea._0x5c615e)](_0x2251f3),'totalImpacted':_0x37fea1,'cascadeLevels':_0x5f02bc,'circularCluster':_0x2958ad,'sccCount':_0x43d738['nodes']['length'],'cyclicSCCs':_0x43d738['nodes'][_0x4a6ab7(_0x4ec7ea._0xe2eafa)](_0x2ba311=>_0x2ba311[_0x4a6ab7(0xa7)])['length']};}function getImpactMemoCache(){const _0x20b172=_0x272b69;return(0x0,memo_cache_1[_0x20b172(0xbf)])();}function _0x3b2f(_0x1fff12,_0x3238e0){_0x1fff12=_0x1fff12-0x90;const _0x53c8ea=_0x53c8();let _0x3b2fb1=_0x53c8ea[_0x1fff12];if(_0x3b2f['LcwOBn']===undefined){var _0x658aba=function(_0x184e1a){const _0x3e270b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x87858b='',_0x31a936='';for(let _0x1d7900=0x0,_0x5c92c9,_0x4b2264,_0x1fd92e=0x0;_0x4b2264=_0x184e1a['charAt'](_0x1fd92e++);~_0x4b2264&&(_0x5c92c9=_0x1d7900%0x4?_0x5c92c9*0x40+_0x4b2264:_0x4b2264,_0x1d7900++%0x4)?_0x87858b+=String['fromCharCode'](0xff&_0x5c92c9>>(-0x2*_0x1d7900&0x6)):0x0){_0x4b2264=_0x3e270b['indexOf'](_0x4b2264);}for(let _0x24168a=0x0,_0x373103=_0x87858b['length'];_0x24168a<_0x373103;_0x24168a++){_0x31a936+='%'+('00'+_0x87858b['charCodeAt'](_0x24168a)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x31a936);};_0x3b2f['KueHKI']=_0x658aba,_0x3b2f['pBwLZD']={},_0x3b2f['LcwOBn']=!![];}const _0x1b8548=_0x53c8ea[0x0],_0x1deb82=_0x1fff12+_0x1b8548,_0x18f128=_0x3b2f['pBwLZD'][_0x1deb82];return!_0x18f128?(_0x3b2fb1=_0x3b2f['KueHKI'](_0x3b2fb1),_0x3b2f['pBwLZD'][_0x1deb82]=_0x3b2fb1):_0x3b2fb1=_0x18f128,_0x3b2fb1;}function classifyRisk(_0x5d0cbc){const _0x264267={_0x364b05:0xa1,_0x3878a4:0xa5,_0x1ac0d8:0xc0,_0x20c4ee:0xa9},_0x137b5d=_0x272b69,_0x5c8aa3={};_0x5c8aa3[_0x137b5d(_0x264267._0x364b05)]=function(_0x3ac930,_0x2f2254){return _0x3ac930>=_0x2f2254;},_0x5c8aa3[_0x137b5d(0xc0)]='HIGH',_0x5c8aa3['KPgki']='MEDIUM',_0x5c8aa3['NYTSv']=_0x137b5d(_0x264267._0x3878a4),_0x5c8aa3['rychh']='NONE';const _0x946e5f=_0x5c8aa3;if(_0x946e5f[_0x137b5d(_0x264267._0x364b05)](_0x5d0cbc,0xa))return _0x946e5f[_0x137b5d(_0x264267._0x1ac0d8)];if(_0x5d0cbc>=0x5)return _0x946e5f['KPgki'];if(_0x5d0cbc>=0x1)return _0x946e5f[_0x137b5d(_0x264267._0x20c4ee)];return _0x946e5f[_0x137b5d(0xd1)];}function getHubFiles(_0x290027,_0x50189d=0xa){const _0x5681ac={_0x221127:0xee,_0x1e6a22:0xa2,_0x1d861d:0xaf,_0x38ff4e:0xcd,_0x149ca8:0xe8},_0x5df86b=_0x272b69,_0xcf40d3=[];for(const _0x53d918 of _0x290027['files']){const _0x2663fa=_0x290027[_0x5df86b(0xc8)][_0x5df86b(_0x5681ac._0x221127)](_0x53d918)||[],_0x476e1d={};_0x476e1d[_0x5df86b(_0x5681ac._0x1e6a22)]=_0x53d918,_0x476e1d[_0x5df86b(0xe7)]=_0x2663fa[_0x5df86b(_0x5681ac._0x1d861d)],_0xcf40d3[_0x5df86b(_0x5681ac._0x38ff4e)](_0x476e1d);}return _0xcf40d3[_0x5df86b(_0x5681ac._0x149ca8)]((_0xdaf8ad,_0x340e4b)=>_0x340e4b[_0x5df86b(0xe7)]-_0xdaf8ad[_0x5df86b(0xe7)]),_0xcf40d3['slice'](0x0,_0x50189d)['map'](_0x5c1f1c=>({'relativePath':path[_0x5df86b(0x96)](_0x290027[_0x5df86b(0xba)],_0x5c1f1c[_0x5df86b(0xa2)])['replace'](/\\/g,'/'),'dependentCount':_0x5c1f1c['count'],'riskLevel':classifyRisk(_0x5c1f1c[_0x5df86b(0xe7)])}));}
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.analyzeImpact = analyzeImpact;
37
+ exports.getImpactMemoCache = getImpactMemoCache;
38
+ exports.classifyRisk = classifyRisk;
39
+ exports.getHubFiles = getHubFiles;
40
+ const path = __importStar(require("path"));
41
+ const change_coupling_1 = require("../git/change-coupling");
42
+ const memo_cache_1 = require("../graph/memo-cache");
43
+ /**
44
+ * BFS reverse traversal to find all files impacted by modifying `filePath`.
45
+ * When SCC data is available, uses the condensed DAG for more accurate
46
+ * cascade-level analysis and circular dependency detection.
47
+ *
48
+ * Optionally computes a composite risk score when `includeRiskScore` is true.
49
+ * Optionally computes historical change coupling when `includeCoupling` is true.
50
+ */
51
+ /**
52
+ * Local BFS impact analysis — used by BYOK ai_analyze and web dashboard.
53
+ * Risk scoring is now server-side (Pro). This function provides basic
54
+ * BFS traversal and SCC-enhanced cascade analysis.
55
+ */
56
+ async function analyzeImpact(filePath, graph, options) {
57
+ const normalized = path.normalize(filePath);
58
+ const toRelative = (f) => path.relative(graph.sourceDir, f).replace(/\\/g, "/");
59
+ // Check memo cache for a cached BFS result (fast path)
60
+ const memoCache = (0, memo_cache_1.getMemoCache)();
61
+ const cached = memoCache.get(normalized);
62
+ if (cached) {
63
+ const directDependents = (graph.reverse.get(normalized) || []).map(toRelative);
64
+ const directSet = new Set(directDependents);
65
+ const transitiveDependents = cached.impactSet
66
+ .map(f => toRelative(f))
67
+ .filter(rel => !directSet.has(rel));
68
+ let result = {
69
+ filePath: normalized,
70
+ relativePath: toRelative(normalized),
71
+ riskLevel: cached.riskLevel,
72
+ directDependents,
73
+ transitiveDependents,
74
+ totalImpacted: cached.directCount + cached.transitiveCount,
75
+ cascadeLevels: cached.cascadeLevels,
76
+ fromCache: true,
77
+ };
78
+ if (options?.includeCoupling) {
79
+ try {
80
+ const coupledFiles = await computeCoupledFiles(normalized, graph, toRelative);
81
+ if (coupledFiles.length > 0) {
82
+ result.coupledFiles = coupledFiles;
83
+ }
84
+ }
85
+ catch (err) {
86
+ console.error(`[syke:coupling] Failed to compute change coupling for ${filePath}: ${err}`);
87
+ }
88
+ }
89
+ return result;
90
+ }
91
+ // Cache miss: run full BFS analysis
92
+ let result;
93
+ if (graph.scc) {
94
+ result = analyzeImpactWithSCC(normalized, graph, toRelative);
95
+ }
96
+ else {
97
+ result = analyzeImpactBFS(normalized, graph, toRelative);
98
+ }
99
+ // Store BFS result in memo cache
100
+ const allImpactedAbsPaths = [
101
+ ...result.directDependents,
102
+ ...result.transitiveDependents,
103
+ ].map(rel => path.normalize(path.join(graph.sourceDir, rel)));
104
+ memoCache.set(normalized, {
105
+ impactSet: allImpactedAbsPaths,
106
+ directCount: result.directDependents.length,
107
+ transitiveCount: result.transitiveDependents.length,
108
+ riskLevel: result.riskLevel,
109
+ cascadeLevels: result.cascadeLevels,
110
+ computedAt: Date.now(),
111
+ });
112
+ // Compute historical change coupling if requested
113
+ if (options?.includeCoupling) {
114
+ try {
115
+ const coupledFiles = await computeCoupledFiles(normalized, graph, toRelative);
116
+ if (coupledFiles.length > 0) {
117
+ result.coupledFiles = coupledFiles;
118
+ }
119
+ }
120
+ catch (err) {
121
+ console.error(`[syke:coupling] Failed to compute change coupling for ${filePath}: ${err}`);
122
+ }
123
+ }
124
+ return result;
125
+ }
126
+ /**
127
+ * Compute historical change coupling for a file, filtering to only show
128
+ * couplings that are NOT already in the dependency graph ("hidden" dependencies).
129
+ * Returns at most 5 coupled files, sorted by confidence.
130
+ */
131
+ async function computeCoupledFiles(normalizedPath, graph, toRelative) {
132
+ const couplingResult = await (0, change_coupling_1.mineGitHistory)(graph.projectRoot);
133
+ if (couplingResult.totalCommitsAnalyzed === 0) {
134
+ return [];
135
+ }
136
+ // Convert file path to git-relative format (forward slashes, relative to project root)
137
+ const gitRelPath = path.relative(graph.projectRoot, normalizedPath).replace(/\\/g, "/");
138
+ const couplings = (0, change_coupling_1.getCoupledFiles)(gitRelPath, couplingResult);
139
+ if (couplings.length === 0) {
140
+ return [];
141
+ }
142
+ // Build a set of all files in the dependency graph (both direct and transitive)
143
+ const graphDeps = new Set();
144
+ // Forward dependencies of this file
145
+ const forwardDeps = graph.forward.get(normalizedPath) || [];
146
+ for (const d of forwardDeps) {
147
+ graphDeps.add(path.relative(graph.projectRoot, d).replace(/\\/g, "/"));
148
+ }
149
+ // Reverse dependents of this file
150
+ const reverseDeps = graph.reverse.get(normalizedPath) || [];
151
+ for (const d of reverseDeps) {
152
+ graphDeps.add(path.relative(graph.projectRoot, d).replace(/\\/g, "/"));
153
+ }
154
+ const results = [];
155
+ for (const coupling of couplings) {
156
+ // Determine which file is the "other" file in the pair
157
+ const otherFile = coupling.file1 === gitRelPath ? coupling.file2 : coupling.file1;
158
+ const inGraph = graphDeps.has(otherFile);
159
+ // Convert to source-dir-relative path for display
160
+ const otherAbsolute = path.normalize(path.join(graph.projectRoot, otherFile));
161
+ const displayPath = toRelative(otherAbsolute);
162
+ results.push({
163
+ relativePath: displayPath,
164
+ confidence: coupling.confidence,
165
+ coChangeCount: coupling.coChangeCount,
166
+ inDependencyGraph: inGraph,
167
+ });
168
+ }
169
+ // Filter to only hidden dependencies (not in graph) and limit to top 5
170
+ const hidden = results.filter((r) => !r.inDependencyGraph);
171
+ return hidden.slice(0, 5);
172
+ }
173
+ /**
174
+ * Original BFS-based impact analysis (no SCC data).
175
+ */
176
+ function analyzeImpactBFS(normalized, graph, toRelative) {
177
+ // Direct dependents (depth 1)
178
+ const directDependents = graph.reverse.get(normalized) || [];
179
+ // BFS for transitive dependents (all depths)
180
+ const visited = new Set();
181
+ const queue = [...directDependents];
182
+ for (const d of directDependents) {
183
+ visited.add(d);
184
+ }
185
+ while (queue.length > 0) {
186
+ const current = queue.shift();
187
+ const dependents = graph.reverse.get(current) || [];
188
+ for (const dep of dependents) {
189
+ if (!visited.has(dep) && dep !== normalized) {
190
+ visited.add(dep);
191
+ queue.push(dep);
192
+ }
193
+ }
194
+ }
195
+ const totalImpacted = visited.size;
196
+ // Transitive-only = all visited minus direct
197
+ const directSet = new Set(directDependents);
198
+ const transitiveDependents = [...visited].filter((f) => !directSet.has(f));
199
+ const riskLevel = classifyRisk(totalImpacted);
200
+ return {
201
+ filePath: normalized,
202
+ relativePath: toRelative(normalized),
203
+ riskLevel,
204
+ directDependents: directDependents.map(toRelative),
205
+ transitiveDependents: transitiveDependents.map(toRelative),
206
+ totalImpacted,
207
+ };
208
+ }
209
+ /**
210
+ * SCC-enhanced impact analysis using the condensed DAG.
211
+ *
212
+ * 1. If the changed file is in a cyclic SCC (size > 1), ALL files in that SCC
213
+ * are immediately marked as affected at cascade level 0.
214
+ * 2. BFS on the condensed DAG (using reverse edges = dependents) to find
215
+ * all impacted SCCs with correct cascade levels.
216
+ * 3. Each file inherits the cascade level of its SCC.
217
+ */
218
+ function analyzeImpactWithSCC(normalized, graph, toRelative) {
219
+ const scc = graph.scc;
220
+ const { nodeToComponent, condensed } = scc;
221
+ const sccIndex = nodeToComponent.get(normalized);
222
+ // File not found in SCC mapping — fall back to BFS
223
+ if (sccIndex === undefined) {
224
+ return analyzeImpactBFS(normalized, graph, toRelative);
225
+ }
226
+ const startNode = condensed.nodes[sccIndex];
227
+ // Collect circular cluster info
228
+ const circularCluster = startNode.isCyclic
229
+ ? startNode.files.filter(f => f !== normalized).map(toRelative)
230
+ : undefined;
231
+ // BFS on condensed DAG reverse edges to find all impacted SCCs
232
+ // Level 0 = the SCC containing the changed file
233
+ // Level 1 = SCCs that directly depend on the changed SCC
234
+ // Level N = SCCs at distance N in the condensed DAG
235
+ const visitedSCCs = new Map(); // SCC index -> cascade level
236
+ visitedSCCs.set(sccIndex, 0);
237
+ const queue = [
238
+ { sccIdx: sccIndex, level: 0 },
239
+ ];
240
+ while (queue.length > 0) {
241
+ const { sccIdx, level } = queue.shift();
242
+ // Get SCCs that depend on this SCC (reverse edges in condensed DAG)
243
+ const dependentSCCs = condensed.reverse.get(sccIdx) || [];
244
+ for (const depSCC of dependentSCCs) {
245
+ if (!visitedSCCs.has(depSCC)) {
246
+ visitedSCCs.set(depSCC, level + 1);
247
+ queue.push({ sccIdx: depSCC, level: level + 1 });
248
+ }
249
+ }
250
+ }
251
+ // Expand SCC indices back to individual files
252
+ const cascadeLevels = new Map();
253
+ const allImpactedFiles = new Set();
254
+ for (const [sccIdx, level] of visitedSCCs) {
255
+ const node = condensed.nodes[sccIdx];
256
+ for (const file of node.files) {
257
+ if (file === normalized)
258
+ continue; // Exclude the changed file itself
259
+ allImpactedFiles.add(file);
260
+ cascadeLevels.set(file, level);
261
+ }
262
+ }
263
+ // Separate into direct (level 1 from raw graph) and transitive
264
+ const rawDirectDependents = graph.reverse.get(normalized) || [];
265
+ const directSet = new Set(rawDirectDependents);
266
+ // Files in the same cyclic SCC are also considered "direct" dependents
267
+ if (startNode.isCyclic) {
268
+ for (const f of startNode.files) {
269
+ if (f !== normalized) {
270
+ directSet.add(f);
271
+ }
272
+ }
273
+ }
274
+ const directDependents = [...allImpactedFiles].filter(f => directSet.has(f));
275
+ const transitiveDependents = [...allImpactedFiles].filter(f => !directSet.has(f));
276
+ const totalImpacted = allImpactedFiles.size;
277
+ const riskLevel = classifyRisk(totalImpacted);
278
+ // Convert cascade levels keys to relative paths
279
+ const relativeCascadeLevels = new Map();
280
+ for (const [file, level] of cascadeLevels) {
281
+ relativeCascadeLevels.set(toRelative(file), level);
282
+ }
283
+ return {
284
+ filePath: normalized,
285
+ relativePath: toRelative(normalized),
286
+ riskLevel,
287
+ directDependents: directDependents.map(toRelative),
288
+ transitiveDependents: transitiveDependents.map(toRelative),
289
+ totalImpacted,
290
+ cascadeLevels: relativeCascadeLevels,
291
+ circularCluster,
292
+ sccCount: condensed.nodes.length,
293
+ cyclicSCCs: condensed.nodes.filter(n => n.isCyclic).length,
294
+ };
295
+ }
296
+ /**
297
+ * Get the memo cache instance for diagnostics (cache stats, etc.).
298
+ */
299
+ function getImpactMemoCache() {
300
+ return (0, memo_cache_1.getMemoCache)();
301
+ }
302
+ function classifyRisk(count) {
303
+ if (count >= 10)
304
+ return "HIGH";
305
+ if (count >= 5)
306
+ return "MEDIUM";
307
+ if (count >= 1)
308
+ return "LOW";
309
+ return "NONE";
310
+ }
311
+ /**
312
+ * Rank files by number of reverse dependents (hub score).
313
+ */
314
+ function getHubFiles(graph, topN = 10) {
315
+ const entries = [];
316
+ for (const file of graph.files) {
317
+ const revDeps = graph.reverse.get(file) || [];
318
+ entries.push({ file, count: revDeps.length });
319
+ }
320
+ entries.sort((a, b) => b.count - a.count);
321
+ return entries.slice(0, topN).map((e) => ({
322
+ relativePath: path.relative(graph.sourceDir, e.file).replace(/\\/g, "/"),
323
+ dependentCount: e.count,
324
+ riskLevel: classifyRisk(e.count),
325
+ }));
326
+ }
@@ -1,5 +1,4 @@
1
1
  import { DependencyGraph } from "../graph";
2
- import { RiskScore } from "../scoring/risk-scorer";
3
2
  export type GateVerdict = "PASS" | "WARN" | "FAIL";
4
3
  export interface GateIssue {
5
4
  file: string;
@@ -18,8 +17,6 @@ export interface GateResult {
18
17
  cyclicSCCs?: number;
19
18
  };
20
19
  autoAcknowledged: number;
21
- /** Composite risk scores for specified files (when available) */
22
- riskScores?: Map<string, RiskScore>;
23
20
  }
24
21
  /**
25
22
  * Run the build gate check.