@syke1/mcp-server 1.6.1 → 1.7.1
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/dist/ai/analyzer.js +112 -1
- package/dist/ai/context-extractor.js +224 -1
- package/dist/ai/provider.js +186 -1
- package/dist/ai/realtime-analyzer.js +253 -1
- package/dist/config.js +121 -1
- package/dist/git/change-coupling.js +250 -1
- package/dist/graph/incremental.js +313 -1
- package/dist/graph/memo-cache.js +176 -1
- package/dist/graph/scc.js +206 -1
- package/dist/graph.d.ts +0 -3
- package/dist/graph.js +130 -1
- package/dist/index.js +813 -1
- package/dist/license/validator.js +344 -1
- package/dist/remote/proxy.d.ts +30 -0
- package/dist/remote/proxy.js +192 -0
- package/dist/remote/types.d.ts +70 -0
- package/dist/remote/types.js +8 -0
- package/dist/tools/analyze-impact.d.ts +5 -5
- package/dist/tools/analyze-impact.js +326 -1
- package/dist/tools/gate-build.d.ts +0 -3
- package/dist/tools/gate-build.js +361 -1
- package/dist/watcher/file-cache.js +281 -1
- package/dist/web/server.js +925 -1
- package/package.json +2 -3
- package/dist/scoring/pagerank.d.ts +0 -67
- package/dist/scoring/pagerank.js +0 -1
- package/dist/scoring/risk-scorer.d.ts +0 -99
- package/dist/scoring/risk-scorer.js +0 -1
|
@@ -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.
|
package/dist/tools/gate-build.js
CHANGED
|
@@ -1 +1,361 @@
|
|
|
1
|
-
'use strict';const _0x312c3b=_0x471a;(function(_0x43585b,_0x3b0b91){const _0xadd48d={_0x25e98a:0x102,_0xfec5fe:0x170,_0x24ccee:0x177,_0x153d48:0x168,_0x51335d:0x175,_0xfec04:0x118},_0x5d4316=_0x471a,_0x103131=_0x43585b();while(!![]){try{const _0x3a49bf=parseInt(_0x5d4316(0x137))/0x1*(parseInt(_0x5d4316(_0xadd48d._0x25e98a))/0x2)+-parseInt(_0x5d4316(_0xadd48d._0xfec5fe))/0x3*(parseInt(_0x5d4316(_0xadd48d._0x24ccee))/0x4)+-parseInt(_0x5d4316(0x124))/0x5+-parseInt(_0x5d4316(_0xadd48d._0x153d48))/0x6+parseInt(_0x5d4316(_0xadd48d._0x51335d))/0x7+-parseInt(_0x5d4316(0x12f))/0x8*(-parseInt(_0x5d4316(_0xadd48d._0xfec04))/0x9)+parseInt(_0x5d4316(0x10b))/0xa;if(_0x3a49bf===_0x3b0b91)break;else _0x103131['push'](_0x103131['shift']());}catch(_0xa57f28){_0x103131['push'](_0x103131['shift']());}}}(_0x5046,0xe9c60));var __createBinding=this&&this[_0x312c3b(0x115)]||(Object[_0x312c3b(0x142)]?function(_0x400115,_0x5372d8,_0x2862b3,_0x373e63){const _0x3589c3={_0x4bf718:0x14a,_0xe2333b:0x138,_0x3b81db:0x129,_0xa631b0:0x14a,_0x22879b:0x13a},_0x4fa839=_0x312c3b,_0x43d609={};_0x43d609[_0x4fa839(0x14c)]=function(_0x45a7c8,_0xf07621){return _0x45a7c8===_0xf07621;},_0x43d609['oWeUz']=function(_0x1c2bac,_0x4c29f9){return _0x1c2bac in _0x4c29f9;},_0x43d609[_0x4fa839(_0x3589c3._0x4bf718)]=_0x4fa839(_0x3589c3._0xe2333b);const _0x1f969c=_0x43d609;if(_0x1f969c['suVWC'](_0x373e63,undefined))_0x373e63=_0x2862b3;var _0x5d6c01=Object[_0x4fa839(0x13d)](_0x5372d8,_0x2862b3);if(!_0x5d6c01||(_0x1f969c[_0x4fa839(_0x3589c3._0x3b81db)](_0x1f969c[_0x4fa839(_0x3589c3._0xa631b0)],_0x5d6c01)?!_0x5372d8['__esModule']:_0x5d6c01['writable']||_0x5d6c01['configurable'])){const _0x1904c0={};_0x1904c0[_0x4fa839(0x148)]=!![],_0x1904c0['get']=function(){return _0x5372d8[_0x2862b3];},_0x5d6c01=_0x1904c0;}Object[_0x4fa839(_0x3589c3._0x22879b)](_0x400115,_0x373e63,_0x5d6c01);}:function(_0x1ac497,_0xfdcbd5,_0x3848d4,_0x49151a){if(_0x49151a===undefined)_0x49151a=_0x3848d4;_0x1ac497[_0x49151a]=_0xfdcbd5[_0x3848d4];}),__setModuleDefault=this&&this['__setModuleDefault']||(Object[_0x312c3b(0x142)]?function(_0x136985,_0x25999d){const _0x18cddd={_0x2b2c65:0x133},_0x3ecb21=_0x312c3b,_0x5c5bde={};_0x5c5bde['enumerable']=!![],_0x5c5bde['value']=_0x25999d,Object['defineProperty'](_0x136985,_0x3ecb21(_0x18cddd._0x2b2c65),_0x5c5bde);}:function(_0x50bc2e,_0x4bfa81){_0x50bc2e['default']=_0x4bfa81;}),__importStar=this&&this[_0x312c3b(0x10e)]||(function(){const _0x170635={_0x1591de:0x17d,_0x244381:0x163},_0x3b5185={_0x726097:0x109},_0x203916={'xeYxW':function(_0x5791f6,_0x146c12){return _0x5791f6(_0x146c12);},'JoopM':function(_0x56715e,_0x5cfc88){return _0x56715e!=_0x5cfc88;},'EaEaT':function(_0x3c25fd,_0x282be3){return _0x3c25fd<_0x282be3;}};var _0x203b0e=function(_0x9bafc6){return _0x203b0e=Object['getOwnPropertyNames']||function(_0xff7668){const _0x55088c=_0x471a;var _0xb7f46a=[];for(var _0x259bed in _0xff7668)if(Object['prototype'][_0x55088c(0x13e)][_0x55088c(_0x3b5185._0x726097)](_0xff7668,_0x259bed))_0xb7f46a[_0xb7f46a['length']]=_0x259bed;return _0xb7f46a;},_0x203916['xeYxW'](_0x203b0e,_0x9bafc6);};return function(_0x84b1f3){const _0x42cd35=_0x471a;if(_0x84b1f3&&_0x84b1f3[_0x42cd35(_0x170635._0x1591de)])return _0x84b1f3;var _0x1ebaeb={};if(_0x203916[_0x42cd35(_0x170635._0x244381)](_0x84b1f3,null)){for(var _0xd0558f=_0x203b0e(_0x84b1f3),_0x12a73e=0x0;_0x203916['EaEaT'](_0x12a73e,_0xd0558f[_0x42cd35(0x161)]);_0x12a73e++)if(_0xd0558f[_0x12a73e]!==_0x42cd35(0x133))__createBinding(_0x1ebaeb,_0x84b1f3,_0xd0558f[_0x12a73e]);}return __setModuleDefault(_0x1ebaeb,_0x84b1f3),_0x1ebaeb;};}());function _0x471a(_0x2ee1f0,_0x3ae936){_0x2ee1f0=_0x2ee1f0-0x101;const _0x504640=_0x5046();let _0x471aa3=_0x504640[_0x2ee1f0];if(_0x471a['JxBkzH']===undefined){var _0x1424c8=function(_0x5d52ff){const _0x10dde2='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2c64a2='',_0x17e116='';for(let _0x154095=0x0,_0xf9af07,_0x5eb41c,_0x2bbc6a=0x0;_0x5eb41c=_0x5d52ff['charAt'](_0x2bbc6a++);~_0x5eb41c&&(_0xf9af07=_0x154095%0x4?_0xf9af07*0x40+_0x5eb41c:_0x5eb41c,_0x154095++%0x4)?_0x2c64a2+=String['fromCharCode'](0xff&_0xf9af07>>(-0x2*_0x154095&0x6)):0x0){_0x5eb41c=_0x10dde2['indexOf'](_0x5eb41c);}for(let _0x5a9d9a=0x0,_0x134c04=_0x2c64a2['length'];_0x5a9d9a<_0x134c04;_0x5a9d9a++){_0x17e116+='%'+('00'+_0x2c64a2['charCodeAt'](_0x5a9d9a)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x17e116);};_0x471a['KEOCyT']=_0x1424c8,_0x471a['GExXEP']={},_0x471a['JxBkzH']=!![];}const _0x4ea239=_0x504640[0x0],_0x161a63=_0x2ee1f0+_0x4ea239,_0x24c9ee=_0x471a['GExXEP'][_0x161a63];return!_0x24c9ee?(_0x471aa3=_0x471a['KEOCyT'](_0x471aa3),_0x471a['GExXEP'][_0x161a63]=_0x471aa3):_0x471aa3=_0x24c9ee,_0x471aa3;}const _0x5d62ee={};_0x5d62ee[_0x312c3b(0x178)]=!![],Object[_0x312c3b(0x13a)](exports,'__esModule',_0x5d62ee),exports[_0x312c3b(0x108)]=gateCheck,exports[_0x312c3b(0x16e)]=formatGateResult;const path=__importStar(require('path')),server_1=require(_0x312c3b(0x12c)),analyze_impact_1=require(_0x312c3b(0x12d)),risk_scorer_1=require(_0x312c3b(0x171)),change_coupling_1=require('../git/change-coupling');function _0x5046(){const _0x269656=['igrLCgvUzgvUDhmPlcbJB21WB3nPDguGC2nVCMu6ia','BwfW','lsbgAwXLCYbPBIbNCMfWAdOG','vxfdyxq','zMLSDgvY','Dg9gAxHLza','Aw5JBhvKzxm','AgfZ','yNfiv08','Aw5KzxHpzG','z2v0vw5Hy2TUB3DSzwrNzwrxyxjUAw5NCW','v0fstG','ihDHCM5PBMCOCYK','y29TChv0zvbYB2PLy3rnzxrYAwnZ','Cg9W','AwrQDfK','ywrK','AxndEwnSAwm','Dw5YzxnVBhzLzfDHCM5PBMDZ','BgvUz3rO','q1jjveLdquW','sM9VCe0','y29UzMLKzw5Jzq','icOQwW','CMLZA1nJB3jLCW','iYmGu1LlrsbcDwLSzcbhyxrLiokaLca','nJuYmtCWnMLHzMnVDq','iYmJifn0yxrZ','yxv0B0fJA25VD2XLzgDLza','CMvWBgfJzq','C2v2zxjPDhK','lsbdAxjJDwXHCIbKzxbLBMrLBMn5ignSDxn0zxjZoIa','zM9YBwf0r2f0zvjLC3vSDa','zw5KC1DPDgG','nte2rxDovvri','lI4VC2nVCMLUzY9YAxnRlxnJB3jLCG','D0zlCeq','z2v0q291CgXLzezPBgvZ','iYmJifjLy29TBwvUzgf0Aw9U','nda5nZi2oenSwvDKva','ignOyw5NzxmGD2L0Acb0AgLZigzPBguGAw4G','nJeYCLHyvhrS','DMfSDwu','D1vRsgm','oIOQ','ufjpq0vfrcbxsvriienbvvrjt04G4Ocuia','lsbtDhjVBMDSEsbdB25Uzwn0zwqGq29TCg9Uzw50CZOG','x19LC01VzhvSzq','C29Tzq','sgLNAcbYAxnRihnJB3jLia','y29TCgXLEgL0Eq','CMvSyxrPDMvqyxrO','zM5gs2G','ChjVAMvJDfjVB3q','CMv2zxjZzq','ihjPC2SP','C3rHDhm','mta2odiYsg5fzxzs','zMLSzxm','y3LJBgu','u0fgrq','BM9YBwfSAxPL','CNndyxC','z2f0zunOzwnR','y2fSBa','iYmJifn0yxr1CW','mZC3mJm3mgnTze5RDW','z25Prwy','zM9YBwf0uMLZA1nJB3jL','x19PBxbVCNrtDgfY','txHotLK','DuDJCu8','tuvesvvn','tg1OsfK','DhHVzfa','igzPBgvZktOG','x19JCMvHDgvcAw5KAw5N','shvIigzPBguGBw9KAwzPzwqGka','AM9PBG','mtqZmJe3C0nsy3Pp','iYmJieLZC3vLCW','lsbvBNjLC29SDMvKihDHCM5PBMDZoIa','sgLZDg9YAwnHBcbJB3vWBgLUzZOG','C3rHDhvZtgLUzq','q2LYy3vSyxiGzgvWzw5Kzw5JEsbKzxrLy3rLzcaO','icHMyw4TAw46ia','CMLZA0XLDMvS','zgvSzxrL','q1jjveLdquWGD2fYBMLUz3m','zMLSzxnjBKDYyxbO','seLhsa','odm5nZuWtevdCunw','zMLSzq','rML4ihrOzsbPC3n1zxmGywjVDMuGyMvMB3jLigj1AwXKAw5NlIbvC2uGygnOzwnRx3DHCM5PBMDZycbMB3iGzgv0ywLSCYWGDgHLBIbGyw5HBhL6zv9PBxbHy3rGig9UigfMzMvJDgvKigzPBgvZlG','rKfjta','C291CMnLrgLY','B1DLvxO','q3jPDgLJywWGCMLZAYbZy29Yzsa','C2nJq291BNq','lI4VD2vIl3nLCNzLCG','lI9HBMfSExPLlwLTCgfJDa','te9x','mJrqufbRELG','u1PZDhm','ugLUuem','C2nJ','zgvMyxvSDa','y29UzgvUC2vK','zgvZy3jPChrPB24','AuzSsui','mJn6s0nNEeu','z2v0','CMvSyxrPDMu','zgvMAw5LuhjVCgvYDhK','AxnZDwvZ','zMLUza','z2v0t3DUuhjVCgvYDhLezxnJCMLWDg9Y','AgfZt3DUuhjVCgvYDhK','EMP1r3C','DhjHBNnPDgL2zuzHBKLU','y29TCg9ZAxrL','y3jLyxrL','C2XPy2u','iYmJifjPC2SGu2nVCMvZ','z2v0uMLZA1nJB3jL','ChvZAa','igXLDMvSCYWGy29TCgXLEgL0EtOG','zw51BwvYywjSzq','BM9Kzxm','wgrTBem','q3Ltwwi','C3vwv0m','BM9KzvrVq29TCg9Uzw50'];_0x5046=function(){return _0x269656;};return _0x5046();}function detectCyclesWithSCC(_0x5d06a2,_0xf75d1f){const _0x32957b={_0x388bdd:0x155,_0x2b09d9:0x15e,_0x5aa6cf:0x103,_0x4994e7:0x146},_0x12a342=_0x312c3b,_0x3a633b={'QPese':function(_0x52a526,_0x2399e2,_0x3a64a5,_0x1fa62e){return _0x52a526(_0x2399e2,_0x3a64a5,_0x1fa62e);},'QfENi':function(_0x55442e,_0x17ae7f){return _0x55442e===_0x17ae7f;}},_0x5a7b55=_0xf75d1f['scc'];if(!_0x5a7b55)return _0x3a633b['QPese'](detectCyclesForFilesDFS,_0x5d06a2,_0xf75d1f,0xa);const _0x334d8a=[],_0x5c1e9a=new Set();for(const _0x2265cb of _0x5d06a2){if(!_0xf75d1f['files'][_0x12a342(_0x32957b._0x388bdd)](_0x2265cb))continue;const _0x767cea=_0x5a7b55[_0x12a342(0x14d)]['get'](_0x2265cb);if(_0x3a633b['QfENi'](_0x767cea,undefined))continue;const _0x38ce99=_0x5a7b55['condensed'][_0x12a342(0x149)][_0x767cea];if(!_0x38ce99[_0x12a342(0x15f)])continue;if(_0x5c1e9a['has'](_0x767cea))continue;_0x5c1e9a[_0x12a342(_0x32957b._0x2b09d9)](_0x767cea);const _0x31b294=[..._0x38ce99[_0x12a342(_0x32957b._0x5aa6cf)],_0x38ce99['files'][0x0]],_0x25e5ca={};_0x25e5ca['cycle']=_0x31b294,_0x25e5ca[_0x12a342(0x125)]=_0x2265cb,_0x334d8a[_0x12a342(_0x32957b._0x4994e7)](_0x25e5ca);}return _0x334d8a;}function detectAllCycles(_0x2419be){const _0x5e71f4={_0x21eeba:0x15f,_0x23616b:0x104},_0x1039c5=_0x312c3b,_0x1b108d=_0x2419be[_0x1039c5(0x132)];if(!_0x1b108d)return[];const _0x26c8f4=[];for(const _0x57b0c8 of _0x1b108d['condensed'][_0x1039c5(0x149)]){if(!_0x57b0c8[_0x1039c5(_0x5e71f4._0x21eeba)])continue;const _0x3ae55b=[..._0x57b0c8['files'],_0x57b0c8['files'][0x0]],_0x31cb3e={};_0x31cb3e[_0x1039c5(_0x5e71f4._0x23616b)]=_0x3ae55b,_0x31cb3e[_0x1039c5(0x125)]=_0x57b0c8['files'][0x0],_0x26c8f4['push'](_0x31cb3e);}return _0x26c8f4;}function detectCyclesForFilesDFS(_0x121d32,_0x14b61e,_0x17e4bb=0xa){const _0x4dc2cb={_0x36ad03:0x103,_0x287b66:0x155},_0x44bba0={_0x2106d5:0x138,_0x121bcc:0x182,_0x2f125c:0x155,_0x59ae20:0x143,_0x174cb9:0x151},_0x2ab3de=_0x312c3b,_0x1d2269={'fnFKh':function(_0x2a92dd,_0x3feef0){return _0x2a92dd>=_0x3feef0;},'UqCat':function(_0x44490d,_0x167d57){return _0x44490d(_0x167d57);},'CdXym':function(_0x53cb83,_0x8c9af6){return _0x53cb83(_0x8c9af6);}},_0x522a26=[],_0x6748ad=new Set();for(const _0x2580a1 of _0x121d32){if(!_0x14b61e[_0x2ab3de(_0x4dc2cb._0x36ad03)][_0x2ab3de(_0x4dc2cb._0x287b66)](_0x2580a1))continue;const _0x581e5a=new Set(),_0x10e3ff=[];function _0x456119(_0x446818){const _0xec53fd=_0x2ab3de;if(_0x522a26['length']>=_0x17e4bb)return;if(_0x6748ad['has'](_0x446818))return;_0x581e5a['add'](_0x446818),_0x10e3ff['push'](_0x446818);const _0x3bf810=_0x14b61e['forward'][_0xec53fd(_0x44bba0._0x2106d5)](_0x446818)||[];for(const _0x2cc437 of _0x3bf810){if(_0x1d2269[_0xec53fd(_0x44bba0._0x121bcc)](_0x522a26['length'],_0x17e4bb))break;if(_0x581e5a[_0xec53fd(_0x44bba0._0x2f125c)](_0x2cc437)){const _0x42fa53=_0x10e3ff[_0xec53fd(0x157)](_0x2cc437);_0x42fa53>=0x0&&_0x522a26['push']({'cycle':[..._0x10e3ff[_0xec53fd(_0x44bba0._0x59ae20)](_0x42fa53),_0x2cc437],'file':_0x2580a1});}else!_0x6748ad[_0xec53fd(_0x44bba0._0x2f125c)](_0x2cc437)&&_0x1d2269[_0xec53fd(_0x44bba0._0x174cb9)](_0x456119,_0x2cc437);}_0x581e5a[_0xec53fd(0x120)](_0x446818),_0x10e3ff[_0xec53fd(0x15c)]();}_0x1d2269['CdXym'](_0x456119,_0x2580a1);for(const _0x10c74c of _0x581e5a)_0x6748ad['add'](_0x10c74c);}return _0x522a26['slice'](0x0,_0x17e4bb);}async function gateCheck(_0x86ba1e,_0x31013a){const _0x5778fd={_0x54812e:0x127,_0x27c52c:0x126,_0x4a0461:0x134,_0x29145d:0x149,_0x108364:0x161,_0x473def:0x122,_0x9343c9:0x152,_0x15d9c4:0x16b,_0x5eec42:0x15b,_0x4de8bb:0x155,_0x1b9a5b:0x145,_0x8745fa:0x11e,_0x50fdf1:0x140,_0x5ee65d:0x147,_0x200862:0x146,_0x5ee04d:0x180,_0x8cb864:0x16c,_0x4fc5dd:0x135,_0x33c9ab:0x11f,_0x3eea3d:0x10c,_0x581c5c:0x13c,_0x4204ae:0x116,_0x5f3c29:0x14e,_0x207f75:0x103,_0x1d7282:0x106,_0x20b6e6:0x138,_0x14e657:0x154,_0x22292a:0x164,_0x5b5321:0x139,_0xbbaab5:0x125,_0x4253d8:0x11b,_0x4e7406:0x10f,_0x170915:0x110,_0x1585b4:0x146,_0x1d434e:0x121,_0x161cb5:0x156,_0x4bb4bb:0x13f,_0x19b1d4:0x161,_0x3aad8b:0x107,_0xb5111a:0x13b},_0xd02e53=_0x312c3b,_0x4049eb={'TzjtO':function(_0x4edfdd,_0x180cda){return _0x4edfdd(_0x180cda);},'UjPxV':function(_0x50eaa1,_0x360611){return _0x50eaa1+_0x360611;},'mCLCs':_0xd02e53(0x162),'nBTRM':function(_0x2247ef,_0x5962a3){return _0x2247ef-_0x5962a3;},'mErQW':_0xd02e53(0x12e),'gniEf':function(_0x13db22,_0x3cb107){return _0x13db22===_0x3cb107;},'mNywS':_0xd02e53(0x105),'WWSzo':'MEDIUM','bqHWO':function(_0x7b8df0,_0xc7855){return _0x7b8df0>_0xc7855;},'MxNNY':function(_0x3f7718,_0x27df01){return _0x3f7718||_0x27df01;},'uGcqO':_0xd02e53(_0x5778fd._0x54812e),'hzXGb':_0xd02e53(_0x5778fd._0x27c52c),'zjuGw':'WARN','rsCaw':'PASS','xyxXW':'All\x20clear\x20—\x20safe\x20to\x20build'},_0x4772ec=(0x0,server_1[_0xd02e53(0x158)])(),_0x26e9e7=_0x86ba1e['scc']?.[_0xd02e53(_0x5778fd._0x4a0461)][_0xd02e53(_0x5778fd._0x29145d)][_0xd02e53(_0x5778fd._0x108364)],_0xed94ec=_0x86ba1e['scc']?.['condensed']['nodes']['filter'](_0x6ab15c=>_0x6ab15c['isCyclic'])['length'],_0x2f15d7={};_0x2f15d7[_0xd02e53(_0x5778fd._0x473def)]=_0x86ba1e[_0xd02e53(0x103)]['size'],_0x2f15d7[_0xd02e53(0x160)]=_0x4772ec['length'],_0x2f15d7[_0xd02e53(0x12b)]=_0x26e9e7,_0x2f15d7['cyclicSCCs']=_0xed94ec;const _0x4ccae0=_0x2f15d7,_0x24deb1=_0x31013a?_0x4772ec[_0xd02e53(_0x5778fd._0x9343c9)](_0x5ad135=>_0x31013a[_0xd02e53(0x17e)](_0x3a3666=>_0x5ad135[_0xd02e53(0x125)]===_0x3a3666||_0x3a3666['endsWith'](_0x5ad135[_0xd02e53(0x125)])||_0x5ad135['file'][_0xd02e53(0x16f)](_0x3a3666['replace'](/\\/g,'/')))):_0x4772ec,_0x457f89=[];for(const _0x27a4c6 of _0x24deb1){const _0x4d445d=_0x4049eb['TzjtO'](mapRiskToSeverity,_0x27a4c6['riskLevel']);_0x4d445d&&_0x457f89['push']({'file':_0x27a4c6['file'],'severity':_0x4d445d,'description':_0x4049eb['UjPxV'](_0x27a4c6['summary'],_0x27a4c6['brokenImports']['length']>0x0?'\x20(broken\x20imports:\x20'+_0x27a4c6['brokenImports']['join'](',\x20')+')':'')});}const _0x8c781=_0x31013a||[],_0x5a3d74=detectCyclesWithSCC(_0x8c781,_0x86ba1e);for(const _0x300d8e of _0x5a3d74){const _0x92681c=_0x300d8e['cycle']['map'](_0x2aeccd=>path['relative'](_0x86ba1e[_0xd02e53(0x128)],_0x2aeccd)[_0xd02e53(0x16b)](/\\/g,'/'))['join']('\x20->\x20');_0x457f89['push']({'file':path['relative'](_0x86ba1e[_0xd02e53(0x128)],_0x300d8e[_0xd02e53(0x125)])[_0xd02e53(_0x5778fd._0x15d9c4)](/\\/g,'/'),'severity':_0x4049eb['mCLCs'],'description':_0xd02e53(0x11d)+_0x4049eb['nBTRM'](_0x300d8e['cycle']['length'],0x1)+_0xd02e53(0x114)+_0x92681c});}const _0x3e46b2=new Map();if(_0x31013a){try{(0x0,risk_scorer_1[_0xd02e53(_0x5778fd._0x5eec42)])(_0x86ba1e);}catch{}const _0x214838=(0x0,analyze_impact_1['getHubFiles'])(_0x86ba1e,0x5),_0x350727=new Set(_0x214838[_0xd02e53(0x14f)](_0x7bd156=>_0x7bd156['relativePath']));for(const _0x263418 of _0x31013a){if(!_0x86ba1e[_0xd02e53(0x103)][_0xd02e53(_0x5778fd._0x4de8bb)](_0x263418))continue;const _0x2e0ba7=path['relative'](_0x86ba1e['sourceDir'],_0x263418)['replace'](/\\/g,'/');try{const _0x6425a5=(0x0,risk_scorer_1[_0xd02e53(_0x5778fd._0x1b9a5b)])(_0x263418,_0x86ba1e);_0x3e46b2['set'](_0x2e0ba7,_0x6425a5);if(_0x6425a5['riskLevel']==='CRITICAL')_0x457f89['push']({'file':_0x2e0ba7,'severity':_0x4049eb['mCLCs'],'description':_0xd02e53(0x12a)+_0x6425a5['composite'][_0xd02e53(0x153)](0x2)+_0xd02e53(_0x5778fd._0x8745fa)+_0x6425a5[_0xd02e53(_0x5778fd._0x50fdf1)]+',\x20cascade:\x20'+_0x6425a5['cascadeDepth']+_0xd02e53(_0x5778fd._0x5ee65d)+_0x6425a5['complexity']+')'});else _0x6425a5['riskLevel']==='HIGH'&&_0x457f89[_0xd02e53(_0x5778fd._0x200862)]({'file':_0x2e0ba7,'severity':'HIGH','description':_0xd02e53(0x17f)+_0x6425a5[_0xd02e53(0x141)]['toFixed'](0x2)+'\x20(fan-in:\x20'+_0x6425a5['transitiveFanIn']+',\x20cascade:\x20'+_0x6425a5['cascadeDepth']+'\x20levels,\x20complexity:\x20'+_0x6425a5[_0xd02e53(_0x5778fd._0x5ee04d)]+')'});}catch{}if(_0x350727['has'](_0x2e0ba7)&&!_0x3e46b2[_0xd02e53(_0x5778fd._0x4de8bb)](_0x2e0ba7)){const _0xf2d6f2=_0x214838[_0xd02e53(0x13c)](_0x28a19e=>_0x28a19e[_0xd02e53(0x181)]===_0x2e0ba7),_0x22665a={};_0x22665a[_0xd02e53(0x125)]=_0x2e0ba7,_0x22665a[_0xd02e53(_0x5778fd._0x8cb864)]='MEDIUM',_0x22665a[_0xd02e53(_0x5778fd._0x4fc5dd)]='Hub\x20file\x20modified\x20('+_0xf2d6f2['dependentCount']+'\x20dependents,\x20'+_0xf2d6f2[_0xd02e53(_0x5778fd._0x33c9ab)]+_0xd02e53(0x185),_0x457f89[_0xd02e53(0x146)](_0x22665a);}else{if(_0x350727[_0xd02e53(_0x5778fd._0x4de8bb)](_0x2e0ba7)){const _0x74852c=_0x3e46b2[_0xd02e53(0x138)](_0x2e0ba7);if(_0x74852c&&(_0x74852c[_0xd02e53(_0x5778fd._0x33c9ab)]===_0x4049eb['mErQW']||_0x4049eb['gniEf'](_0x74852c[_0xd02e53(_0x5778fd._0x33c9ab)],_0xd02e53(0x111))||_0x4049eb[_0xd02e53(_0x5778fd._0x3eea3d)](_0x74852c['riskLevel'],_0x4049eb['mNywS']))){const _0x3a582f=_0x214838[_0xd02e53(_0x5778fd._0x581c5c)](_0x59beb7=>_0x59beb7['relativePath']===_0x2e0ba7);_0x457f89['push']({'file':_0x2e0ba7,'severity':'MEDIUM','description':_0xd02e53(_0x5778fd._0x4204ae)+_0x3a582f['dependentCount']+_0xd02e53(_0x5778fd._0x5f3c29)+_0x74852c['composite']['toFixed'](0x2)});}}}}try{const _0x5dfc26=await(0x0,change_coupling_1['mineGitHistory'])(_0x86ba1e['projectRoot']);if(_0x5dfc26['totalCommitsAnalyzed']>0x0){const _0x2792cd=new Set(_0x31013a['map'](_0x5a6cb8=>path['relative'](_0x86ba1e['projectRoot'],_0x5a6cb8)['replace'](/\\/g,'/')));for(const _0x2dde62 of _0x31013a){if(!_0x86ba1e[_0xd02e53(_0x5778fd._0x207f75)][_0xd02e53(_0x5778fd._0x4de8bb)](_0x2dde62))continue;const _0x4cca7d=path['relative'](_0x86ba1e[_0xd02e53(0x183)],_0x2dde62)['replace'](/\\/g,'/'),_0x1fc420=(0x0,change_coupling_1[_0xd02e53(0x173)])(_0x4cca7d,_0x5dfc26);for(const _0x1e6e28 of _0x1fc420){const _0x47da2e=_0x4049eb[_0xd02e53(0x10c)](_0x1e6e28['file1'],_0x4cca7d)?_0x1e6e28['file2']:_0x1e6e28['file1'];if(_0x2792cd['has'](_0x47da2e))continue;const _0x2fc71f=path[_0xd02e53(_0x5778fd._0x1d7282)](path['join'](_0x86ba1e['projectRoot'],_0x47da2e)),_0x5a1f33=_0x86ba1e['forward'][_0xd02e53(_0x5778fd._0x20b6e6)](_0x2dde62)||[],_0x198f80=_0x86ba1e[_0xd02e53(0x184)]['get'](_0x2dde62)||[],_0x46b95e=_0x5a1f33[_0xd02e53(_0x5778fd._0x14e657)](_0x2fc71f)||_0x198f80['includes'](_0x2fc71f);if(_0x46b95e)continue;if(_0x1e6e28['confidence']<0.3)continue;const _0x47116d=_0x1e6e28['confidence']>=0.5?_0x4049eb['WWSzo']:'LOW',_0x3f2782=Math['round'](_0x1e6e28[_0xd02e53(_0x5778fd._0x22292a)]*0x64),_0x40b35c=path[_0xd02e53(_0x5778fd._0x5b5321)](_0x86ba1e['sourceDir'],_0x2dde62)['replace'](/\\/g,'/'),_0x2ba0a8={};_0x2ba0a8[_0xd02e53(_0x5778fd._0xbbaab5)]=_0x40b35c,_0x2ba0a8[_0xd02e53(_0x5778fd._0x8cb864)]=_0x47116d,_0x2ba0a8[_0xd02e53(0x135)]=_0xd02e53(_0x5778fd._0x4253d8)+_0x47da2e+_0xd02e53(0x176)+_0x3f2782+'%\x20of\x20commits\x20('+_0x1e6e28['coChangeCount']+'\x20times)\x20--\x20consider\x20reviewing',_0x457f89['push'](_0x2ba0a8);}}}}catch{}}const _0x25e438=_0x457f89['some'](_0x2549ce=>_0x2549ce['severity']==='CRITICAL'),_0x1e4d6a=_0x457f89[_0xd02e53(0x152)](_0x2b6b24=>_0x2b6b24['severity']===_0xd02e53(0x123)),_0x306174=_0x4049eb['bqHWO'](_0x1e4d6a['length'],0x0)&&_0x24deb1[_0xd02e53(0x17e)](_0x19fe7e=>_0x19fe7e['riskLevel']===_0xd02e53(0x123)&&_0x19fe7e['brokenImports']['length']>0x0),_0x58d3b6=_0x4049eb[_0xd02e53(0x156)](_0x5a3d74['length'],0x0);let _0xc89f01,_0x4d8668,_0x3eb25f,_0x55c203=0x0;if(_0x4049eb[_0xd02e53(_0x5778fd._0x4e7406)](_0x25e438,_0x306174)||_0x58d3b6){_0xc89f01=_0x4049eb[_0xd02e53(_0x5778fd._0x170915)];const _0x301fcd=[];if(_0x25e438)_0x301fcd[_0xd02e53(_0x5778fd._0x1585b4)](_0xd02e53(_0x5778fd._0x1d434e));if(_0x306174)_0x301fcd['push']('HIGH\x20warnings\x20with\x20broken\x20imports');if(_0x58d3b6)_0x301fcd[_0xd02e53(_0x5778fd._0x1585b4)](_0x5a3d74['length']+'\x20circular\x20dependency(ies)');_0x4d8668='BUILD\x20BLOCKED\x20—\x20'+_0x301fcd['join'](',\x20'),_0x3eb25f=_0x4049eb['hzXGb'];}else _0x4049eb[_0xd02e53(_0x5778fd._0x161cb5)](_0x1e4d6a['length'],0x0)||_0x457f89['some'](_0x217199=>_0x217199['severity']==='MEDIUM')?(_0xc89f01=_0x4049eb[_0xd02e53(_0x5778fd._0x4bb4bb)],_0x4d8668=_0xd02e53(0x17b)+_0x457f89[_0xd02e53(_0x5778fd._0x19b1d4)]+'\x20issue(s)\x20detected',_0x3eb25f='Review\x20the\x20issues.\x20If\x20you\x27ve\x20verified\x20they\x27re\x20safe,\x20proceed\x20with\x20the\x20build.\x20Use\x20`check_warnings\x20acknowledge=true`\x20to\x20clear\x20warnings.'):(_0xc89f01=_0x4049eb[_0xd02e53(_0x5778fd._0x3aad8b)],_0x4d8668=_0x4049eb['xyxXW'],_0x3eb25f='No\x20issues\x20detected.\x20You\x20may\x20proceed\x20with\x20build/deploy.',_0x55c203=(0x0,server_1['acknowledgeWarnings'])());const _0x38b7b2={};return _0x38b7b2['verdict']=_0xc89f01,_0x38b7b2[_0xd02e53(0x11c)]=_0x4d8668,_0x38b7b2[_0xd02e53(_0x5778fd._0xb5111a)]=_0x457f89,_0x38b7b2['recommendation']=_0x3eb25f,_0x38b7b2[_0xd02e53(0x101)]=_0x4ccae0,_0x38b7b2['autoAcknowledged']=_0x55c203,_0x38b7b2['riskScores']=_0x3e46b2['size']>0x0?_0x3e46b2:undefined,_0x38b7b2;}function formatGateResult(_0x4b3403){const _0x18dde3={_0x1cfa47:0x10a,_0x1b50df:0x172,_0x30cfd6:0x174,_0x17406f:0x131,_0x452c72:0x169,_0x4eb088:0x144,_0x317179:0x136,_0x315911:0x167,_0xb7e1a6:0x179,_0x1fbc36:0x13b,_0x28df12:0x146,_0x3efdbb:0x172,_0x5e8342:0x15d,_0x5c4333:0x112,_0x449cc4:0x122,_0x582a25:0x101,_0x1cb3f1:0x101,_0x516f7b:0x16d,_0xa135dc:0x15a,_0x5be89e:0x166,_0x7bc7e4:0x117},_0x5e7390=_0x312c3b,_0xe9a45b={};_0xe9a45b['CySYb']=function(_0x5d9e69,_0x16ed8f){return _0x5d9e69===_0x16ed8f;},_0xe9a45b[_0x5e7390(0x136)]='PASS',_0xe9a45b['wUkHc']=_0x5e7390(_0x18dde3._0x1cfa47),_0xe9a45b['KrLOh']=function(_0x553840,_0x4f89a2){return _0x553840>_0x4f89a2;},_0xe9a45b[_0x5e7390(_0x18dde3._0x1b50df)]=_0x5e7390(0x119),_0xe9a45b['idjtY']=function(_0x307d0f,_0xd97793){return _0x307d0f===_0xd97793;},_0xe9a45b['LmhHY']=_0x5e7390(_0x18dde3._0x30cfd6),_0xe9a45b[_0x5e7390(_0x18dde3._0x17406f)]=_0x5e7390(_0x18dde3._0x452c72),_0xe9a45b['EBEfj']=function(_0x4e2b1a,_0x580456){return _0x4e2b1a!==_0x580456;},_0xe9a45b['tmCLv']=_0x5e7390(_0x18dde3._0x4eb088);const _0x3fd408=_0xe9a45b,_0x5d1f9e=_0x3fd408['CySYb'](_0x4b3403['verdict'],_0x3fd408[_0x5e7390(_0x18dde3._0x317179)])?'✅':_0x4b3403['verdict']===_0x5e7390(0x159)?'⚠️':'🚫',_0x1d46e0=[_0x5e7390(_0x18dde3._0x315911)+_0x5d1f9e+'\x20'+_0x4b3403['verdict'],'',_0x3fd408[_0x5e7390(_0x18dde3._0xb7e1a6)],_0x4b3403['statusLine']];if(_0x3fd408['KrLOh'](_0x4b3403[_0x5e7390(_0x18dde3._0x1fbc36)][_0x5e7390(0x161)],0x0)){_0x1d46e0[_0x5e7390(_0x18dde3._0x28df12)]('',_0x3fd408[_0x5e7390(_0x18dde3._0x3efdbb)]);for(const _0x22c129 of _0x4b3403['issues']){const _0x57fec5=_0x3fd408[_0x5e7390(0x15d)](_0x22c129[_0x5e7390(0x16c)],'CRITICAL')?'🚫':_0x3fd408[_0x5e7390(0x14b)](_0x22c129['severity'],'HIGH')?'🔴':_0x3fd408[_0x5e7390(_0x18dde3._0x5e8342)](_0x22c129['severity'],_0x5e7390(0x111))?'🟡':'🔵';_0x1d46e0['push']('-\x20'+_0x57fec5+_0x5e7390(0x165)+_0x22c129[_0x5e7390(0x16c)]+']**\x20'+_0x22c129['file']+':\x20'+_0x22c129['description']);}}_0x1d46e0['push']('',_0x3fd408[_0x5e7390(_0x18dde3._0x5c4333)],_0x4b3403['recommendation']),_0x1d46e0[_0x5e7390(0x146)]('',_0x3fd408['PinPC'],_0x5e7390(0x150)+_0x4b3403['stats'][_0x5e7390(_0x18dde3._0x449cc4)],_0x5e7390(0x11a)+_0x4b3403[_0x5e7390(_0x18dde3._0x582a25)]['unresolvedWarnings']);_0x4b3403[_0x5e7390(_0x18dde3._0x1cb3f1)]['sccCount']!==undefined&&_0x1d46e0['push'](_0x5e7390(0x17c)+_0x4b3403[_0x5e7390(_0x18dde3._0x582a25)]['sccCount']);_0x3fd408['EBEfj'](_0x4b3403['stats']['cyclicSCCs'],undefined)&&_0x4b3403[_0x5e7390(0x101)]['cyclicSCCs']>0x0&&_0x1d46e0['push'](_0x5e7390(_0x18dde3._0x516f7b)+_0x4b3403['stats']['cyclicSCCs']);_0x4b3403[_0x5e7390(0x16a)]>0x0&&_0x1d46e0['push']('-\x20Auto-acknowledged:\x20'+_0x4b3403[_0x5e7390(0x16a)]+_0x5e7390(_0x18dde3._0xa135dc));if(_0x4b3403['riskScores']&&_0x3fd408['KrLOh'](_0x4b3403[_0x5e7390(0x166)]['size'],0x0)){_0x1d46e0[_0x5e7390(0x146)]('',_0x3fd408['tmCLv']);for(const [_0x101348,_0x5eaadc]of _0x4b3403[_0x5e7390(_0x18dde3._0x5be89e)]){_0x1d46e0['push']('**'+_0x101348+_0x5e7390(0x17a)),_0x1d46e0[_0x5e7390(0x146)]((0x0,risk_scorer_1[_0x5e7390(0x10d)])(_0x5eaadc)),_0x1d46e0['push']('');}}return _0x1d46e0[_0x5e7390(_0x18dde3._0x7bc7e4)]('\x0a');}function mapRiskToSeverity(_0x3d34c1){const _0x5f48cc={_0x420ebc:0x12e,_0x3dd1a8:0x123,_0x4dc662:0x111},_0xc61c5e=_0x312c3b,_0x2a7e65={};_0x2a7e65['txodP']='CRITICAL',_0x2a7e65[_0xc61c5e(0x130)]=_0xc61c5e(_0x5f48cc._0x420ebc);const _0x2c5a18=_0x2a7e65;switch(_0x3d34c1){case _0x2c5a18[_0xc61c5e(0x113)]:return _0xc61c5e(0x162);case'HIGH':return _0xc61c5e(_0x5f48cc._0x3dd1a8);case _0xc61c5e(0x111):return _0xc61c5e(_0x5f48cc._0x4dc662);case _0x2c5a18['SZsts']:return _0x2c5a18['SZsts'];default:return null;}}
|
|
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.gateCheck = gateCheck;
|
|
37
|
+
exports.formatGateResult = formatGateResult;
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const server_1 = require("../web/server");
|
|
40
|
+
const change_coupling_1 = require("../git/change-coupling");
|
|
41
|
+
/**
|
|
42
|
+
* Detect circular dependencies using SCC data.
|
|
43
|
+
* Much faster and more complete than DFS-based cycle detection.
|
|
44
|
+
* Returns all cyclic SCCs that contain any of the specified files.
|
|
45
|
+
*/
|
|
46
|
+
function detectCyclesWithSCC(files, graph) {
|
|
47
|
+
const scc = graph.scc;
|
|
48
|
+
if (!scc) {
|
|
49
|
+
// Fallback to old DFS if SCC data not available
|
|
50
|
+
return detectCyclesForFilesDFS(files, graph, 10);
|
|
51
|
+
}
|
|
52
|
+
const cycles = [];
|
|
53
|
+
const reportedSCCs = new Set();
|
|
54
|
+
for (const file of files) {
|
|
55
|
+
if (!graph.files.has(file))
|
|
56
|
+
continue;
|
|
57
|
+
const sccIndex = scc.nodeToComponent.get(file);
|
|
58
|
+
if (sccIndex === undefined)
|
|
59
|
+
continue;
|
|
60
|
+
const node = scc.condensed.nodes[sccIndex];
|
|
61
|
+
if (!node.isCyclic)
|
|
62
|
+
continue;
|
|
63
|
+
// Only report each cyclic SCC once
|
|
64
|
+
if (reportedSCCs.has(sccIndex))
|
|
65
|
+
continue;
|
|
66
|
+
reportedSCCs.add(sccIndex);
|
|
67
|
+
// Build a cycle representation: all files in the SCC form a cycle
|
|
68
|
+
// For display, show the circular path by appending the first file at the end
|
|
69
|
+
const cyclePath = [...node.files, node.files[0]];
|
|
70
|
+
cycles.push({
|
|
71
|
+
cycle: cyclePath,
|
|
72
|
+
file,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return cycles;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Also scan the entire graph for cyclic SCCs (not just specified files).
|
|
79
|
+
* Returns summary info about all cycles in the project.
|
|
80
|
+
*/
|
|
81
|
+
function detectAllCycles(graph) {
|
|
82
|
+
const scc = graph.scc;
|
|
83
|
+
if (!scc)
|
|
84
|
+
return [];
|
|
85
|
+
const cycles = [];
|
|
86
|
+
for (const node of scc.condensed.nodes) {
|
|
87
|
+
if (!node.isCyclic)
|
|
88
|
+
continue;
|
|
89
|
+
const cyclePath = [...node.files, node.files[0]];
|
|
90
|
+
cycles.push({
|
|
91
|
+
cycle: cyclePath,
|
|
92
|
+
file: node.files[0],
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return cycles;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Legacy DFS forward traversal from specified files to detect circular dependencies.
|
|
99
|
+
* Used as fallback when SCC data is not available.
|
|
100
|
+
*/
|
|
101
|
+
function detectCyclesForFilesDFS(files, graph, maxCycles = 10) {
|
|
102
|
+
const cycles = [];
|
|
103
|
+
const globalVisited = new Set();
|
|
104
|
+
for (const startFile of files) {
|
|
105
|
+
if (!graph.files.has(startFile))
|
|
106
|
+
continue;
|
|
107
|
+
const stack = new Set();
|
|
108
|
+
const pathStack = [];
|
|
109
|
+
function dfs(file) {
|
|
110
|
+
if (cycles.length >= maxCycles)
|
|
111
|
+
return;
|
|
112
|
+
if (globalVisited.has(file))
|
|
113
|
+
return;
|
|
114
|
+
stack.add(file);
|
|
115
|
+
pathStack.push(file);
|
|
116
|
+
const deps = graph.forward.get(file) || [];
|
|
117
|
+
for (const dep of deps) {
|
|
118
|
+
if (cycles.length >= maxCycles)
|
|
119
|
+
break;
|
|
120
|
+
if (stack.has(dep)) {
|
|
121
|
+
// Back-edge found: cycle
|
|
122
|
+
const idx = pathStack.indexOf(dep);
|
|
123
|
+
if (idx >= 0) {
|
|
124
|
+
cycles.push({
|
|
125
|
+
cycle: [...pathStack.slice(idx), dep],
|
|
126
|
+
file: startFile,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else if (!globalVisited.has(dep)) {
|
|
131
|
+
dfs(dep);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
stack.delete(file);
|
|
135
|
+
pathStack.pop();
|
|
136
|
+
}
|
|
137
|
+
dfs(startFile);
|
|
138
|
+
for (const f of stack)
|
|
139
|
+
globalVisited.add(f);
|
|
140
|
+
}
|
|
141
|
+
return cycles.slice(0, maxCycles);
|
|
142
|
+
}
|
|
143
|
+
// ── Gate Check ──
|
|
144
|
+
/**
|
|
145
|
+
* Run the build gate check.
|
|
146
|
+
* If `specifiedFiles` is provided, only warnings for those files are considered.
|
|
147
|
+
* Cycle detection uses SCC data when available (faster and more complete).
|
|
148
|
+
*/
|
|
149
|
+
async function gateCheck(graph, specifiedFiles) {
|
|
150
|
+
const allWarnings = (0, server_1.getUnacknowledgedWarnings)();
|
|
151
|
+
const sccCount = graph.scc?.condensed.nodes.length;
|
|
152
|
+
const cyclicSCCs = graph.scc?.condensed.nodes.filter(n => n.isCyclic).length;
|
|
153
|
+
const stats = {
|
|
154
|
+
filesInGraph: graph.files.size,
|
|
155
|
+
unresolvedWarnings: allWarnings.length,
|
|
156
|
+
sccCount,
|
|
157
|
+
cyclicSCCs,
|
|
158
|
+
};
|
|
159
|
+
// Filter warnings to specified files if provided
|
|
160
|
+
const warnings = specifiedFiles
|
|
161
|
+
? allWarnings.filter((w) => specifiedFiles.some((f) => w.file === f ||
|
|
162
|
+
f.endsWith(w.file) ||
|
|
163
|
+
w.file.endsWith(f.replace(/\\/g, "/"))))
|
|
164
|
+
: allWarnings;
|
|
165
|
+
const issues = [];
|
|
166
|
+
// 1. Check warnings by severity
|
|
167
|
+
for (const w of warnings) {
|
|
168
|
+
const severity = mapRiskToSeverity(w.riskLevel);
|
|
169
|
+
if (severity) {
|
|
170
|
+
issues.push({
|
|
171
|
+
file: w.file,
|
|
172
|
+
severity,
|
|
173
|
+
description: w.summary +
|
|
174
|
+
(w.brokenImports.length > 0
|
|
175
|
+
? ` (broken imports: ${w.brokenImports.join(", ")})`
|
|
176
|
+
: ""),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// 2. Detect cycles using SCC (or fallback to DFS)
|
|
181
|
+
const filesToCheck = specifiedFiles || [];
|
|
182
|
+
const cycles = detectCyclesWithSCC(filesToCheck, graph);
|
|
183
|
+
for (const c of cycles) {
|
|
184
|
+
const cyclePath = c.cycle
|
|
185
|
+
.map((f) => path.relative(graph.sourceDir, f).replace(/\\/g, "/"))
|
|
186
|
+
.join(" -> ");
|
|
187
|
+
issues.push({
|
|
188
|
+
file: path.relative(graph.sourceDir, c.file).replace(/\\/g, "/"),
|
|
189
|
+
severity: "CRITICAL",
|
|
190
|
+
description: `Circular dependency detected (${c.cycle.length - 1} files): ${cyclePath}`,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
// 3. Check if hub files were modified (simplified — no Pro scoring)
|
|
194
|
+
if (specifiedFiles) {
|
|
195
|
+
// Simple hub detection: files with most reverse dependents
|
|
196
|
+
const hubEntries = [];
|
|
197
|
+
for (const f of graph.files) {
|
|
198
|
+
const revDeps = graph.reverse.get(f) || [];
|
|
199
|
+
hubEntries.push({ file: f, count: revDeps.length });
|
|
200
|
+
}
|
|
201
|
+
hubEntries.sort((a, b) => b.count - a.count);
|
|
202
|
+
const top5 = hubEntries.slice(0, 5);
|
|
203
|
+
const hubPathSet = new Set(top5.map(h => path.relative(graph.sourceDir, h.file).replace(/\\/g, "/")));
|
|
204
|
+
for (const f of specifiedFiles) {
|
|
205
|
+
if (!graph.files.has(f))
|
|
206
|
+
continue;
|
|
207
|
+
const rel = path.relative(graph.sourceDir, f).replace(/\\/g, "/");
|
|
208
|
+
// Check if this file is a hub file
|
|
209
|
+
if (hubPathSet.has(rel)) {
|
|
210
|
+
const hub = top5.find(h => path.relative(graph.sourceDir, h.file).replace(/\\/g, "/") === rel);
|
|
211
|
+
if (hub) {
|
|
212
|
+
const riskLevel = hub.count >= 10 ? "HIGH" : hub.count >= 5 ? "MEDIUM" : "LOW";
|
|
213
|
+
issues.push({
|
|
214
|
+
file: rel,
|
|
215
|
+
severity: riskLevel === "HIGH" ? "HIGH" : "MEDIUM",
|
|
216
|
+
description: `Hub file modified (${hub.count} dependents, ${riskLevel} risk)`,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// 4. Check historical change coupling for modified files
|
|
222
|
+
try {
|
|
223
|
+
const couplingResult = await (0, change_coupling_1.mineGitHistory)(graph.projectRoot);
|
|
224
|
+
if (couplingResult.totalCommitsAnalyzed > 0) {
|
|
225
|
+
const modifiedSet = new Set(specifiedFiles.map((f) => path.relative(graph.projectRoot, f).replace(/\\/g, "/")));
|
|
226
|
+
for (const f of specifiedFiles) {
|
|
227
|
+
if (!graph.files.has(f))
|
|
228
|
+
continue;
|
|
229
|
+
const gitRelPath = path
|
|
230
|
+
.relative(graph.projectRoot, f)
|
|
231
|
+
.replace(/\\/g, "/");
|
|
232
|
+
const couplings = (0, change_coupling_1.getCoupledFiles)(gitRelPath, couplingResult);
|
|
233
|
+
for (const coupling of couplings) {
|
|
234
|
+
const otherFile = coupling.file1 === gitRelPath ? coupling.file2 : coupling.file1;
|
|
235
|
+
if (modifiedSet.has(otherFile))
|
|
236
|
+
continue;
|
|
237
|
+
const otherAbsolute = path.normalize(path.join(graph.projectRoot, otherFile));
|
|
238
|
+
const forwardDeps = graph.forward.get(f) || [];
|
|
239
|
+
const reverseDeps = graph.reverse.get(f) || [];
|
|
240
|
+
const isInGraph = forwardDeps.includes(otherAbsolute) ||
|
|
241
|
+
reverseDeps.includes(otherAbsolute);
|
|
242
|
+
if (isInGraph)
|
|
243
|
+
continue;
|
|
244
|
+
if (coupling.confidence < 0.3)
|
|
245
|
+
continue;
|
|
246
|
+
const severity = coupling.confidence >= 0.5 ? "MEDIUM" : "LOW";
|
|
247
|
+
const pct = Math.round(coupling.confidence * 100);
|
|
248
|
+
const rel = path.relative(graph.sourceDir, f).replace(/\\/g, "/");
|
|
249
|
+
issues.push({
|
|
250
|
+
file: rel,
|
|
251
|
+
severity,
|
|
252
|
+
description: `Historical coupling: ${otherFile} changes with this file in ${pct}% of commits (${coupling.coChangeCount} times) -- consider reviewing`,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
// Non-critical: coupling analysis failure should not block build gate
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// ── Determine verdict ──
|
|
263
|
+
const hasCritical = issues.some((i) => i.severity === "CRITICAL");
|
|
264
|
+
const highIssues = issues.filter((i) => i.severity === "HIGH");
|
|
265
|
+
const hasHighWithBroken = highIssues.length > 0 &&
|
|
266
|
+
warnings.some((w) => w.riskLevel === "HIGH" && w.brokenImports.length > 0);
|
|
267
|
+
const hasCycles = cycles.length > 0;
|
|
268
|
+
let verdict;
|
|
269
|
+
let statusLine;
|
|
270
|
+
let recommendation;
|
|
271
|
+
let autoAcknowledged = 0;
|
|
272
|
+
if (hasCritical || hasHighWithBroken || hasCycles) {
|
|
273
|
+
verdict = "FAIL";
|
|
274
|
+
const reasons = [];
|
|
275
|
+
if (hasCritical)
|
|
276
|
+
reasons.push("CRITICAL warnings");
|
|
277
|
+
if (hasHighWithBroken)
|
|
278
|
+
reasons.push("HIGH warnings with broken imports");
|
|
279
|
+
if (hasCycles)
|
|
280
|
+
reasons.push(`${cycles.length} circular dependency(ies)`);
|
|
281
|
+
statusLine = `BUILD BLOCKED — ${reasons.join(", ")}`;
|
|
282
|
+
recommendation =
|
|
283
|
+
"Fix the issues above before building. Use `check_warnings` for details, then `analyze_impact` on affected files.";
|
|
284
|
+
}
|
|
285
|
+
else if (highIssues.length > 0 ||
|
|
286
|
+
issues.some((i) => i.severity === "MEDIUM")) {
|
|
287
|
+
verdict = "WARN";
|
|
288
|
+
statusLine = `PROCEED WITH CAUTION — ${issues.length} issue(s) detected`;
|
|
289
|
+
recommendation =
|
|
290
|
+
"Review the issues. If you've verified they're safe, proceed with the build. Use `check_warnings acknowledge=true` to clear warnings.";
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
verdict = "PASS";
|
|
294
|
+
statusLine = "All clear — safe to build";
|
|
295
|
+
recommendation = "No issues detected. You may proceed with build/deploy.";
|
|
296
|
+
// Auto-acknowledge warnings on PASS
|
|
297
|
+
autoAcknowledged = (0, server_1.acknowledgeWarnings)();
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
verdict,
|
|
301
|
+
statusLine,
|
|
302
|
+
issues,
|
|
303
|
+
recommendation,
|
|
304
|
+
stats,
|
|
305
|
+
autoAcknowledged,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
// ── Formatting ──
|
|
309
|
+
function formatGateResult(result) {
|
|
310
|
+
const icon = result.verdict === "PASS"
|
|
311
|
+
? "✅"
|
|
312
|
+
: result.verdict === "WARN"
|
|
313
|
+
? "⚠️"
|
|
314
|
+
: "🚫";
|
|
315
|
+
const lines = [
|
|
316
|
+
`## SYKE Build Gate — ${icon} ${result.verdict}`,
|
|
317
|
+
"",
|
|
318
|
+
"### Status",
|
|
319
|
+
result.statusLine,
|
|
320
|
+
];
|
|
321
|
+
if (result.issues.length > 0) {
|
|
322
|
+
lines.push("", "### Issues");
|
|
323
|
+
for (const issue of result.issues) {
|
|
324
|
+
const issueIcon = issue.severity === "CRITICAL"
|
|
325
|
+
? "🚫"
|
|
326
|
+
: issue.severity === "HIGH"
|
|
327
|
+
? "🔴"
|
|
328
|
+
: issue.severity === "MEDIUM"
|
|
329
|
+
? "🟡"
|
|
330
|
+
: "🔵";
|
|
331
|
+
lines.push(`- ${issueIcon} **[${issue.severity}]** ${issue.file}: ${issue.description}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
lines.push("", "### Recommendation", result.recommendation);
|
|
335
|
+
lines.push("", "### Stats", `- Files in graph: ${result.stats.filesInGraph}`, `- Unresolved warnings: ${result.stats.unresolvedWarnings}`);
|
|
336
|
+
if (result.stats.sccCount !== undefined) {
|
|
337
|
+
lines.push(`- Strongly Connected Components: ${result.stats.sccCount}`);
|
|
338
|
+
}
|
|
339
|
+
if (result.stats.cyclicSCCs !== undefined && result.stats.cyclicSCCs > 0) {
|
|
340
|
+
lines.push(`- Circular dependency clusters: ${result.stats.cyclicSCCs}`);
|
|
341
|
+
}
|
|
342
|
+
if (result.autoAcknowledged > 0) {
|
|
343
|
+
lines.push(`- Auto-acknowledged: ${result.autoAcknowledged} warning(s)`);
|
|
344
|
+
}
|
|
345
|
+
return lines.join("\n");
|
|
346
|
+
}
|
|
347
|
+
// ── Helpers ──
|
|
348
|
+
function mapRiskToSeverity(riskLevel) {
|
|
349
|
+
switch (riskLevel) {
|
|
350
|
+
case "CRITICAL":
|
|
351
|
+
return "CRITICAL";
|
|
352
|
+
case "HIGH":
|
|
353
|
+
return "HIGH";
|
|
354
|
+
case "MEDIUM":
|
|
355
|
+
return "MEDIUM";
|
|
356
|
+
case "LOW":
|
|
357
|
+
return "LOW";
|
|
358
|
+
default:
|
|
359
|
+
return null; // SAFE → no issue
|
|
360
|
+
}
|
|
361
|
+
}
|