@ultrst-armada/krnl 1.0.2 → 1.0.4
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 +67 -65
- package/package.json +15 -8
- package/packages/cli/dist/bin/krnl.cjs +808 -331
- package/packages/cli/dist/bin/krnl.js +50 -65
- package/packages/cli/dist/chunk-GHWYEAPD.js +1642 -0
- package/packages/cli/dist/index.cjs +761 -263
- package/packages/cli/dist/index.d.cts +45 -2
- package/packages/cli/dist/index.d.ts +45 -2
- package/packages/cli/dist/index.js +5 -1
- package/packages/cli/package.json +17 -10
- package/packages/core/dist/index.cjs +2912 -140
- package/packages/core/dist/index.d.cts +614 -27
- package/packages/core/dist/index.d.ts +614 -27
- package/packages/core/dist/index.js +2903 -140
- package/packages/core/package.json +15 -6
- package/packages/create-krnl/dist/index.cjs +102 -65
- package/packages/create-krnl/dist/index.js +102 -65
- package/packages/create-krnl/package.json +5 -3
- package/packages/eslint-plugin/dist/index.cjs +17 -55
- package/packages/eslint-plugin/dist/index.d.cts +8 -43
- package/packages/eslint-plugin/dist/index.d.ts +8 -43
- package/packages/eslint-plugin/dist/index.js +17 -55
- package/packages/eslint-plugin/package.json +5 -4
- package/packages/validate/dist/index.cjs +378 -85
- package/packages/validate/dist/index.d.cts +11 -1
- package/packages/validate/dist/index.d.ts +11 -1
- package/packages/validate/dist/index.js +375 -82
- package/packages/validate/package.json +14 -7
- package/packages/cli/dist/K_ENT_Entity-PQ5MURQY-ZG6FZXXX.js +0 -13
- package/packages/cli/dist/K_LIB_Krnl_Aiko_Client-OPZAVZCW-K4CRQYA5.js +0 -8
- package/packages/cli/dist/K_LIB_Krnl_Ep_Tools-ROOE2TQF-LNPXZYOE.js +0 -110
- package/packages/cli/dist/K_LIB_Krnl_Frontend_Builder-2ZDUH6PF-3ALZPNX4.js +0 -11
- package/packages/cli/dist/K_LIB_Krnl_Frontend_Generator-UYNRNX2X-PJTICYSW.js +0 -11
- package/packages/cli/dist/K_LIB_Krnl_Registry_Client-NXV6D2QW-M5TYU55O.js +0 -8
- package/packages/cli/dist/K_LIB_Krnl_SubApp_Engine-7HR5HWW2-H6STOXRK.js +0 -20
- package/packages/cli/dist/K_LIB_Krnl_SubApp_Registry-7XYGDKJK-XPJXSF7D.js +0 -19
- package/packages/cli/dist/K_LIB_Krnl_SubApp_Worker_Host-CQVTGGG7-CUYGTWOW.js +0 -7
- package/packages/cli/dist/K_LIB_Krnl_System_App_Adapter-M6FJKLGU-VR6T4N6J.js +0 -17
- package/packages/cli/dist/K_LIB_Krnl_System_Base_Functionality_APIs-ZZUZ6ZG5-RLJ4QWDP.js +0 -58
- package/packages/cli/dist/K_LIB_Krnl_System_Magnetic_Loader-XBQO2KXF-BOQGUASC.js +0 -22
- package/packages/cli/dist/K_LIB_Krnl_System_Unified_Http_Adapter-RCEGP3OG-XJI7KIT5.js +0 -8
- package/packages/cli/dist/K_LIB_Krnl_Telemetry-77FRZ3KV-K5VCWAFW.js +0 -9
- package/packages/cli/dist/chunk-3TRM6CYL.js +0 -152
- package/packages/cli/dist/chunk-5JDK35TG.js +0 -3872
- package/packages/cli/dist/chunk-63PTK33I.js +0 -997
- package/packages/cli/dist/chunk-6NIKAMUZ.js +0 -82
- package/packages/cli/dist/chunk-BOXWWXQG.js +0 -400
- package/packages/cli/dist/chunk-EEKLK7QJ.js +0 -565
- package/packages/cli/dist/chunk-EG7T2IAD.js +0 -107
- package/packages/cli/dist/chunk-ESTKOQ7T.js +0 -1146
- package/packages/cli/dist/chunk-F5EHXE2O.js +0 -1036
- package/packages/cli/dist/chunk-F65ANSQG.js +0 -269
- package/packages/cli/dist/chunk-FDNCADFE.js +0 -71
- package/packages/cli/dist/chunk-FZ6X7PHR.js +0 -1146
- package/packages/cli/dist/chunk-GDLRMDAN.js +0 -127
- package/packages/cli/dist/chunk-HWMTCMOS.js +0 -656
- package/packages/cli/dist/chunk-I74QIQOD.js +0 -5536
- package/packages/cli/dist/chunk-JTLSTO25.js +0 -71
- package/packages/cli/dist/chunk-JULBBJ27.js +0 -1033
- package/packages/cli/dist/chunk-OHVMVRBP.js +0 -117
- package/packages/cli/dist/chunk-P2PCLEKX.js +0 -666
- package/packages/cli/dist/chunk-PJQIUOX2.js +0 -7767
- package/packages/cli/dist/chunk-PPOF3DJW.js +0 -471
- package/packages/cli/dist/chunk-Q45257P6.js +0 -173
- package/packages/cli/dist/chunk-QNROWGBI.js +0 -1036
- package/packages/cli/dist/chunk-RJNYUXZD.js +0 -977
- package/packages/cli/dist/chunk-SRTOPJ5W.js +0 -104
- package/packages/cli/dist/chunk-TCEX3MPS.js +0 -702
- package/packages/cli/dist/chunk-TNOAJO2J.js +0 -675
- package/packages/cli/dist/chunk-UR2SUCSF.js +0 -701
- package/packages/cli/dist/chunk-X5LOIFM7.js +0 -68
- package/packages/cli/dist/chunk-XIRFOO3H.js +0 -589
- package/packages/cli/dist/chunk-ZAAV3JXQ.js +0 -809
- package/packages/core/dist/K_ENT_Entity-4MB7CU4A.js +0 -12
- package/packages/core/dist/K_ENT_Entity-DEJGIDGH.js +0 -12
- package/packages/core/dist/K_ENT_Entity-FXZO5UZ2.js +0 -12
- package/packages/core/dist/K_ENT_Entity-HDSCXC5F.js +0 -12
- package/packages/core/dist/K_ENT_Entity-JILABHLW.js +0 -12
- package/packages/core/dist/K_ENT_Entity-PQ5MURQY.js +0 -13
- package/packages/core/dist/K_ENT_Entity-ROAKDIHW.js +0 -12
- package/packages/core/dist/K_ENT_Entity-TBVFSKDV.js +0 -12
- package/packages/core/dist/K_ENT_Entity-ZFLKG3JO.js +0 -12
- package/packages/core/dist/K_LIB_Krnl_Aiko_Client-OPZAVZCW.js +0 -8
- package/packages/core/dist/K_LIB_Krnl_Ep_Tools-ROOE2TQF.js +0 -110
- package/packages/core/dist/K_LIB_Krnl_Frontend_Builder-2ZDUH6PF.js +0 -9
- package/packages/core/dist/K_LIB_Krnl_Frontend_Generator-UYNRNX2X.js +0 -9
- package/packages/core/dist/K_LIB_Krnl_Registry_Client-NXV6D2QW.js +0 -8
- package/packages/core/dist/K_LIB_Krnl_SubApp_Engine-7HR5HWW2.js +0 -20
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-4C6GBQAG.js +0 -18
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-6V23A6F6.js +0 -18
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-7XYGDKJK.js +0 -19
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-DYLLC5G2.js +0 -18
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-F4FOFAUP.js +0 -18
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-FBOXXMI3.js +0 -18
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-Q73BWLNP.js +0 -18
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-QM2C4MVA.js +0 -18
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-QUGI6SMP.js +0 -18
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-RGMTBHNP.js +0 -18
- package/packages/core/dist/K_LIB_Krnl_SubApp_Registry-RWR7UNDW.js +0 -18
- package/packages/core/dist/K_LIB_Krnl_SubApp_Worker_Host-CQVTGGG7.js +0 -7
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-32MFJJ5Z.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-4J4CEWRY.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-A366YHF2.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-LK4LYJHI.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-M6FJKLGU.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-NW3K63II.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-QDHTI5ZV.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-VHCT6VIW.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-WBRKF24R.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-XKYQYT6Q.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_App_Adapter-Z2PWZYDZ.js +0 -17
- package/packages/core/dist/K_LIB_Krnl_System_Base_Functionality_APIs-ZZUZ6ZG5.js +0 -58
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-2EZU7QF4.js +0 -21
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-6G3AQNAV.js +0 -21
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-B2NZMQUG.js +0 -21
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-C2RABMZP.js +0 -21
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-HHE3NZ4F.js +0 -21
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-LHFGR6WK.js +0 -21
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-M74BLM3N.js +0 -21
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-PT6ZA6EA.js +0 -21
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-SP52V3CX.js +0 -21
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-XBQO2KXF.js +0 -22
- package/packages/core/dist/K_LIB_Krnl_System_Magnetic_Loader-YNSEUHJJ.js +0 -21
- package/packages/core/dist/K_LIB_Krnl_System_Unified_Http_Adapter-M6SBHIVA.js +0 -8
- package/packages/core/dist/K_LIB_Krnl_System_Unified_Http_Adapter-RCEGP3OG.js +0 -8
- package/packages/core/dist/K_LIB_Krnl_Telemetry-77FRZ3KV.js +0 -9
- package/packages/core/dist/chunk-33L2J7V7.js +0 -82
- package/packages/core/dist/chunk-3ES4K2ZP.js +0 -817
- package/packages/core/dist/chunk-3SMHVVLL.js +0 -82
- package/packages/core/dist/chunk-3UEZ7JQA.js +0 -4877
- package/packages/core/dist/chunk-3XIE6KBD.js +0 -4877
- package/packages/core/dist/chunk-46ZLCML6.js +0 -107
- package/packages/core/dist/chunk-4UEL3DWJ.js +0 -107
- package/packages/core/dist/chunk-54GWZ5PC.js +0 -82
- package/packages/core/dist/chunk-6QCYRS5L.js +0 -127
- package/packages/core/dist/chunk-6ULMHNXR.js +0 -104
- package/packages/core/dist/chunk-7WUETJEV.js +0 -117
- package/packages/core/dist/chunk-A5KRAYDB.js +0 -107
- package/packages/core/dist/chunk-ANEAZ3PO.js +0 -107
- package/packages/core/dist/chunk-BE76RL6F.js +0 -82
- package/packages/core/dist/chunk-CIARVYDO.js +0 -107
- package/packages/core/dist/chunk-CR2ANE62.js +0 -107
- package/packages/core/dist/chunk-DI27MOR7.js +0 -173
- package/packages/core/dist/chunk-E6RLFHM5.js +0 -596
- package/packages/core/dist/chunk-EELAPMNV.js +0 -4877
- package/packages/core/dist/chunk-ENZ2RQVJ.js +0 -107
- package/packages/core/dist/chunk-F2U6CX4F.js +0 -4877
- package/packages/core/dist/chunk-FKG64OHL.js +0 -82
- package/packages/core/dist/chunk-FYAZJYM5.js +0 -772
- package/packages/core/dist/chunk-G4NP4RDQ.js +0 -82
- package/packages/core/dist/chunk-GADIRLRS.js +0 -473
- package/packages/core/dist/chunk-GR6CSLQJ.js +0 -772
- package/packages/core/dist/chunk-HDS7AT6O.js +0 -772
- package/packages/core/dist/chunk-HIMEZUU2.js +0 -71
- package/packages/core/dist/chunk-IB4UHG5I.js +0 -596
- package/packages/core/dist/chunk-J7ZYNVRS.js +0 -772
- package/packages/core/dist/chunk-JVLZU4K7.js +0 -604
- package/packages/core/dist/chunk-JYXXI7Q3.js +0 -82
- package/packages/core/dist/chunk-K54K2KZW.js +0 -192
- package/packages/core/dist/chunk-K6VHLBNH.js +0 -3316
- package/packages/core/dist/chunk-KCBP7ZYA.js +0 -596
- package/packages/core/dist/chunk-KFQGP6VL.js +0 -33
- package/packages/core/dist/chunk-KIUEUI7K.js +0 -82
- package/packages/core/dist/chunk-LB67NIZP.js +0 -949
- package/packages/core/dist/chunk-LDTYFUNW.js +0 -596
- package/packages/core/dist/chunk-MLVWARD4.js +0 -596
- package/packages/core/dist/chunk-MPYVXHKO.js +0 -2777
- package/packages/core/dist/chunk-MRQ3MITU.js +0 -772
- package/packages/core/dist/chunk-MVUN7I7O.js +0 -107
- package/packages/core/dist/chunk-NDDOIRW7.js +0 -596
- package/packages/core/dist/chunk-O3KDB5MH.js +0 -3330
- package/packages/core/dist/chunk-OEINUDSE.js +0 -400
- package/packages/core/dist/chunk-OPDENPT4.js +0 -4877
- package/packages/core/dist/chunk-P6XEM2LA.js +0 -429
- package/packages/core/dist/chunk-QKMRSQV4.js +0 -82
- package/packages/core/dist/chunk-R6CCWALL.js +0 -4877
- package/packages/core/dist/chunk-RAMMOO73.js +0 -774
- package/packages/core/dist/chunk-S3FTZFG6.js +0 -772
- package/packages/core/dist/chunk-T2ZVN434.js +0 -4877
- package/packages/core/dist/chunk-TFHLDMIA.js +0 -107
- package/packages/core/dist/chunk-TI3QUCIJ.js +0 -107
- package/packages/core/dist/chunk-TR2BAIGI.js +0 -107
- package/packages/core/dist/chunk-UGVVJKC6.js +0 -4877
- package/packages/core/dist/chunk-V2DX7YIU.js +0 -984
- package/packages/core/dist/chunk-W4IHYUYD.js +0 -772
- package/packages/core/dist/chunk-W6WBG5OY.js +0 -4877
- package/packages/core/dist/chunk-WN3M7O7H.js +0 -3312
- package/packages/core/dist/chunk-WR3NCU7U.js +0 -4877
- package/packages/core/dist/chunk-XC6B6L27.js +0 -82
- package/packages/core/dist/chunk-XNSE64ZY.js +0 -3316
- package/packages/core/dist/chunk-XROES2WN.js +0 -634
- package/packages/core/dist/chunk-XSCKNRCZ.js +0 -5020
- package/packages/core/dist/chunk-XVABPAUZ.js +0 -82
- package/packages/core/dist/chunk-YOBCB5C5.js +0 -596
- package/packages/core/dist/chunk-YUK6Q563.js +0 -666
- package/packages/core/dist/chunk-YXGL3ZEU.js +0 -1030
- package/packages/core/dist/chunk-ZINJ5OUX.js +0 -596
- package/packages/core/dist/chunk-ZPFD4BIQ.js +0 -604
- package/packages/core/dist/chunk-ZQZBFG6F.js +0 -4826
- package/packages/core/dist/chunk-ZZFRJGXM.js +0 -4877
- package/packages/create-krnl/dist/K_ENT_Entity-PQ5MURQY-R2OH4VXE.js +0 -14
- package/packages/create-krnl/dist/K_LIB_Krnl_Aiko_Client-OPZAVZCW-AZM5HF4M.js +0 -9
- package/packages/create-krnl/dist/K_LIB_Krnl_Ep_Tools-ROOE2TQF-X5N6SV2S.js +0 -111
- package/packages/create-krnl/dist/K_LIB_Krnl_Frontend_Builder-2ZDUH6PF-5PFHF4JU.js +0 -12
- package/packages/create-krnl/dist/K_LIB_Krnl_Frontend_Generator-UYNRNX2X-ED33OQPH.js +0 -12
- package/packages/create-krnl/dist/K_LIB_Krnl_Registry_Client-NXV6D2QW-YGQLVR4P.js +0 -9
- package/packages/create-krnl/dist/K_LIB_Krnl_SubApp_Engine-7HR5HWW2-VM7CTU2L.js +0 -21
- package/packages/create-krnl/dist/K_LIB_Krnl_SubApp_Registry-7XYGDKJK-Y2GQFJ7I.js +0 -21
- package/packages/create-krnl/dist/K_LIB_Krnl_SubApp_Worker_Host-CQVTGGG7-L3JQWO54.js +0 -8
- package/packages/create-krnl/dist/K_LIB_Krnl_System_App_Adapter-M6FJKLGU-KQARASPR.js +0 -19
- package/packages/create-krnl/dist/K_LIB_Krnl_System_Base_Functionality_APIs-ZZUZ6ZG5-OF3IGLVL.js +0 -59
- package/packages/create-krnl/dist/K_LIB_Krnl_System_Magnetic_Loader-XBQO2KXF-JOLHKOEX.js +0 -24
- package/packages/create-krnl/dist/K_LIB_Krnl_System_Unified_Http_Adapter-RCEGP3OG-L46LSHKQ.js +0 -10
- package/packages/create-krnl/dist/K_LIB_Krnl_Telemetry-77FRZ3KV-4JUPRR3X.js +0 -10
- package/packages/create-krnl/dist/chunk-3TRM6CYL.js +0 -152
- package/packages/create-krnl/dist/chunk-3URCB3QS.js +0 -127
- package/packages/create-krnl/dist/chunk-5JDK35TG.js +0 -3872
- package/packages/create-krnl/dist/chunk-A2XAXDOW.js +0 -812
- package/packages/create-krnl/dist/chunk-AN6TMQHG.js +0 -1033
- package/packages/create-krnl/dist/chunk-BOXWWXQG.js +0 -400
- package/packages/create-krnl/dist/chunk-BPTBREBG.js +0 -38
- package/packages/create-krnl/dist/chunk-FDNCADFE.js +0 -71
- package/packages/create-krnl/dist/chunk-JTLSTO25.js +0 -71
- package/packages/create-krnl/dist/chunk-M3NCUIPL.js +0 -107
- package/packages/create-krnl/dist/chunk-N2EONSOC.js +0 -7769
- package/packages/create-krnl/dist/chunk-OHVMVRBP.js +0 -117
- package/packages/create-krnl/dist/chunk-Q45257P6.js +0 -173
- package/packages/create-krnl/dist/chunk-QGM4M3NI.js +0 -37
- package/packages/create-krnl/dist/chunk-RJNYUXZD.js +0 -977
- package/packages/create-krnl/dist/chunk-SRTOPJ5W.js +0 -104
- package/packages/create-krnl/dist/chunk-UPBIGEC3.js +0 -666
- package/packages/create-krnl/dist/chunk-V2DB7UD7.js +0 -82
- package/packages/create-krnl/dist/chunk-WMHLIUI6.js +0 -3644
- package/packages/create-krnl/dist/chunk-XIRFOO3H.js +0 -589
- package/packages/create-krnl/dist/chunk-Y2CEEVZP.js +0 -5536
- package/packages/create-krnl/dist/main-DXUMPBND.js +0 -2217
- package/packages/create-krnl/dist/wrapper-SDF2VKX3.js +0 -31
|
@@ -36,15 +36,15 @@ module.exports = __toCommonJS(index_exports);
|
|
|
36
36
|
|
|
37
37
|
// src/KrnlValidatorEngine.ts
|
|
38
38
|
var fs2 = __toESM(require("fs"), 1);
|
|
39
|
-
var
|
|
40
|
-
var
|
|
39
|
+
var path3 = __toESM(require("path"), 1);
|
|
40
|
+
var import_ts_morph5 = require("ts-morph");
|
|
41
41
|
|
|
42
42
|
// src/rules/fileLimits.ts
|
|
43
43
|
function checkFileLimits(sf, options) {
|
|
44
44
|
const errors = [];
|
|
45
45
|
const warnings = [];
|
|
46
46
|
const filePath = sf.getFilePath();
|
|
47
|
-
const sourceText = sf.
|
|
47
|
+
const sourceText = sf.getFullText();
|
|
48
48
|
const lines = sourceText.split("\n");
|
|
49
49
|
if (lines.length > options.maxFileLineLimit) {
|
|
50
50
|
errors.push({
|
|
@@ -159,7 +159,7 @@ function checkComponentRules(sf) {
|
|
|
159
159
|
ruleId: "krnl/helper-purity",
|
|
160
160
|
filePath,
|
|
161
161
|
line: decl.getStartLineNumber(),
|
|
162
|
-
message: `Helper functions (Layer 1) cannot directly import I/O modules ('${spec}'). Delegate to Layer 0 libraries or
|
|
162
|
+
message: `Helper functions (Layer 1) cannot directly import I/O modules ('${spec}'). Delegate to Layer 0 libraries or ServiceFacade context.`,
|
|
163
163
|
severity: "error"
|
|
164
164
|
});
|
|
165
165
|
}
|
|
@@ -168,15 +168,13 @@ function checkComponentRules(sf) {
|
|
|
168
168
|
return { errors, warnings };
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
// src/rules/
|
|
172
|
-
var path2 = __toESM(require("path"), 1);
|
|
171
|
+
// src/rules/orchestrationRules.ts
|
|
173
172
|
var import_ts_morph2 = require("ts-morph");
|
|
174
|
-
function
|
|
173
|
+
function checkOrchestrationRules(sf) {
|
|
175
174
|
const errors = [];
|
|
176
175
|
const warnings = [];
|
|
177
176
|
const filePath = sf.getFilePath();
|
|
178
177
|
const sourceText = sf.getText();
|
|
179
|
-
const baseName = path2.basename(filePath);
|
|
180
178
|
const calls = sf.getDescendantsOfKind(import_ts_morph2.SyntaxKind.CallExpression);
|
|
181
179
|
for (const call of calls) {
|
|
182
180
|
const exprText = call.getExpression().getText();
|
|
@@ -185,7 +183,7 @@ function checkEntityRules(sf) {
|
|
|
185
183
|
ruleId: "krnl/no-polling",
|
|
186
184
|
filePath,
|
|
187
185
|
line: call.getStartLineNumber(),
|
|
188
|
-
message: `Prohibited use of 'setInterval'. Krnl applications must use reactive event streams
|
|
186
|
+
message: `Prohibited use of 'setInterval'. Krnl applications must use reactive event streams or triggers.`,
|
|
189
187
|
severity: "error"
|
|
190
188
|
});
|
|
191
189
|
}
|
|
@@ -194,65 +192,36 @@ function checkEntityRules(sf) {
|
|
|
194
192
|
const match = sourceText.match(/main\s*=\s*async\s*\([^,]+,\s*\{([^}]*)\}\s*\)/);
|
|
195
193
|
if (match) {
|
|
196
194
|
const destructured = match[1];
|
|
197
|
-
if (/\bsystem\b/.test(destructured)
|
|
195
|
+
if (/\bsystem\b/.test(destructured)) {
|
|
198
196
|
errors.push({
|
|
199
197
|
ruleId: "krnl/context-destructuring",
|
|
200
198
|
filePath,
|
|
201
|
-
message: `Functionality context parameter destructures 'system'. Functionality passes { state,
|
|
199
|
+
message: `Functionality context parameter destructures 'system'. Functionality passes { state, orchestration } or service context.`,
|
|
202
200
|
severity: "error"
|
|
203
201
|
});
|
|
204
202
|
}
|
|
205
203
|
}
|
|
206
204
|
}
|
|
207
|
-
const
|
|
205
|
+
const isOrchestrationClass = sf.getClasses().some((c) => {
|
|
208
206
|
const ext = c.getExtends();
|
|
209
|
-
return ext && (ext.getText().includes("
|
|
207
|
+
return ext && (ext.getText().includes("FunctionalityOrchestration") || ext.getText().includes("Orchestration") || ext.getText().includes("krnlOrchestrationBase"));
|
|
210
208
|
});
|
|
211
|
-
if (
|
|
209
|
+
if (isOrchestrationClass) {
|
|
212
210
|
for (const decl of sf.getImportDeclarations()) {
|
|
213
211
|
const spec = decl.getModuleSpecifierValue();
|
|
214
212
|
if (spec.includes("libraries/") || spec.includes("Concepts")) {
|
|
215
213
|
errors.push({
|
|
216
|
-
ruleId: "krnl/
|
|
214
|
+
ruleId: "krnl/orchestration-no-libraries",
|
|
217
215
|
filePath,
|
|
218
216
|
line: decl.getStartLineNumber(),
|
|
219
|
-
message: `
|
|
217
|
+
message: `FunctionalityOrchestration class violates Library Calling Invariant. FunctionalityOrchestrations must not call or import libraries directly ('${spec}'). Only functionalities are permitted to call shared libraries.`,
|
|
220
218
|
severity: "error"
|
|
221
219
|
});
|
|
222
220
|
}
|
|
223
221
|
}
|
|
224
|
-
let loadAllLine = -1;
|
|
225
|
-
const addLocalLines = [];
|
|
226
|
-
for (const call of calls) {
|
|
227
|
-
const txt = call.getText();
|
|
228
|
-
if (txt.includes("MagneticLoader.loadAll") || txt.includes("KrnlMagneticLoader.loadAll")) {
|
|
229
|
-
loadAllLine = call.getStartLineNumber();
|
|
230
|
-
} else if (txt.startsWith("this.addLocal(")) {
|
|
231
|
-
const hasUiSpec = txt.includes("uiSpec");
|
|
232
|
-
const idMatch = txt.match(/id\s*:\s*["']([^"']+)["']/);
|
|
233
|
-
addLocalLines.push({
|
|
234
|
-
line: call.getStartLineNumber(),
|
|
235
|
-
hasUiSpec,
|
|
236
|
-
id: idMatch ? idMatch[1] : "unknown"
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
if (loadAllLine !== -1) {
|
|
241
|
-
for (const al of addLocalLines) {
|
|
242
|
-
if (al.hasUiSpec && al.line > loadAllLine) {
|
|
243
|
-
errors.push({
|
|
244
|
-
ruleId: "krnl/boot-order",
|
|
245
|
-
filePath,
|
|
246
|
-
line: al.line,
|
|
247
|
-
message: `addLocal('${al.id}') with uiSpec at line ${al.line} appears AFTER loadAll() at line ${loadAllLine}. All addLocal() with UI must precede loadAll().`,
|
|
248
|
-
severity: "error"
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
222
|
for (const cls of sf.getClasses()) {
|
|
254
223
|
const ext = cls.getExtends();
|
|
255
|
-
if (ext && (ext.getText().includes("
|
|
224
|
+
if (ext && (ext.getText().includes("FunctionalityOrchestration") || ext.getText().includes("Orchestration") || ext.getText().includes("krnlOrchestrationBase"))) {
|
|
256
225
|
const loops = [
|
|
257
226
|
...cls.getDescendantsOfKind(import_ts_morph2.SyntaxKind.ForStatement),
|
|
258
227
|
...cls.getDescendantsOfKind(import_ts_morph2.SyntaxKind.ForOfStatement),
|
|
@@ -262,21 +231,34 @@ function checkEntityRules(sf) {
|
|
|
262
231
|
];
|
|
263
232
|
for (const loop of loops) {
|
|
264
233
|
errors.push({
|
|
265
|
-
ruleId: "krnl/
|
|
234
|
+
ruleId: "krnl/orchestration-purity",
|
|
266
235
|
filePath,
|
|
267
236
|
line: loop.getStartLineNumber(),
|
|
268
|
-
message: `
|
|
237
|
+
message: `FunctionalityOrchestration '${cls.getName() || "Anonymous"}' violates Orchestration Purity Law. Loops and procedural algorithms are prohibited inside orchestrations. Move logic to a functionality or a global library function.`,
|
|
269
238
|
severity: "error"
|
|
270
239
|
});
|
|
271
240
|
}
|
|
241
|
+
const allowedMethods = /* @__PURE__ */ new Set([
|
|
242
|
+
"flow",
|
|
243
|
+
"getFlow",
|
|
244
|
+
"listFlows",
|
|
245
|
+
"clearFlows",
|
|
246
|
+
"thenFunctionality",
|
|
247
|
+
"parallel",
|
|
248
|
+
"branch",
|
|
249
|
+
"fanOut",
|
|
250
|
+
"thenFunctionalityOrchestration",
|
|
251
|
+
"getSteps",
|
|
252
|
+
"assertServiceBoundary"
|
|
253
|
+
]);
|
|
272
254
|
for (const method of cls.getMethods()) {
|
|
273
255
|
const methodName = method.getName();
|
|
274
|
-
if (!
|
|
256
|
+
if (!allowedMethods.has(methodName)) {
|
|
275
257
|
errors.push({
|
|
276
|
-
ruleId: "krnl/
|
|
258
|
+
ruleId: "krnl/orchestration-purity",
|
|
277
259
|
filePath,
|
|
278
260
|
line: method.getStartLineNumber(),
|
|
279
|
-
message: `
|
|
261
|
+
message: `FunctionalityOrchestration '${cls.getName() || "Anonymous"}' defines custom method '${methodName}'. FunctionalityOrchestrations are purely declarative compositors. Define capabilities as functionalities or global library functions.`,
|
|
280
262
|
severity: "error"
|
|
281
263
|
});
|
|
282
264
|
}
|
|
@@ -285,7 +267,7 @@ function checkEntityRules(sf) {
|
|
|
285
267
|
}
|
|
286
268
|
for (const call of calls) {
|
|
287
269
|
const callText = call.getText();
|
|
288
|
-
if (callText.startsWith("this.
|
|
270
|
+
if (callText.startsWith("this.flow(") || callText.startsWith("orchestration.flow(")) {
|
|
289
271
|
let currentExpr = call;
|
|
290
272
|
const chainCalls = [];
|
|
291
273
|
while (currentExpr && import_ts_morph2.Node.isCallExpression(currentExpr)) {
|
|
@@ -302,14 +284,22 @@ function checkEntityRules(sf) {
|
|
|
302
284
|
}
|
|
303
285
|
let chainId = "orchestration";
|
|
304
286
|
for (const step of chainCalls) {
|
|
305
|
-
if (step.name === "
|
|
287
|
+
if (step.name === "flow") {
|
|
306
288
|
chainId = step.argText ? step.argText.replace(/['"]/g, "") : "orchestration";
|
|
307
289
|
} else if (step.name === "thenFunction") {
|
|
308
290
|
errors.push({
|
|
309
|
-
ruleId: "krnl/
|
|
291
|
+
ruleId: "krnl/orchestration-no-direct-library-calls",
|
|
310
292
|
filePath,
|
|
311
293
|
line: step.node.getStartLineNumber(),
|
|
312
|
-
message: `
|
|
294
|
+
message: `FunctionalityOrchestration flow '${chainId}' violates Orchestration Purity Law. Orchestrations cannot chain direct library functions via thenFunction(). Orchestrations must only sequence functionalities (thenFunctionality) and peer functionality orchestrations (thenFunctionalityOrchestration).`,
|
|
295
|
+
severity: "error"
|
|
296
|
+
});
|
|
297
|
+
} else if (step.name === "thenService") {
|
|
298
|
+
errors.push({
|
|
299
|
+
ruleId: "krnl/orchestration-no-external-services",
|
|
300
|
+
filePath,
|
|
301
|
+
line: step.node.getStartLineNumber(),
|
|
302
|
+
message: `FunctionalityOrchestration flow '${chainId}' violates Plane Isolation Law L1. A service-level FunctionalityOrchestration cannot compose external services. Use Skipo ServiceOrchestration at the application layer instead.`,
|
|
313
303
|
severity: "error"
|
|
314
304
|
});
|
|
315
305
|
}
|
|
@@ -322,15 +312,15 @@ function checkEntityRules(sf) {
|
|
|
322
312
|
|
|
323
313
|
// src/rules/workspaceRules.ts
|
|
324
314
|
var fs = __toESM(require("fs"), 1);
|
|
325
|
-
var
|
|
315
|
+
var path2 = __toESM(require("path"), 1);
|
|
326
316
|
var import_ts_morph3 = require("ts-morph");
|
|
327
317
|
function checkTopLevelPurity(sf) {
|
|
328
318
|
const errors = [];
|
|
329
319
|
const warnings = [];
|
|
330
320
|
const filePath = sf.getFilePath();
|
|
331
|
-
const baseName =
|
|
321
|
+
const baseName = path2.basename(filePath);
|
|
332
322
|
const isUiTopLevel = /^(App|main|index|_app|root)\.(tsx|jsx)$/i.test(baseName);
|
|
333
|
-
const isBackendTopLevel = /^(server|app)\.(ts|js)$/i.test(baseName) && !filePath.includes("/components/") && !filePath.includes("/
|
|
323
|
+
const isBackendTopLevel = /^(server|app|index)\.(ts|js)$/i.test(baseName) && !filePath.includes("/components/") && !filePath.includes("/orchestrations/") && !filePath.includes("/services/") && !filePath.includes("/libraries/");
|
|
334
324
|
if (isUiTopLevel) {
|
|
335
325
|
const jsxElements = sf.getDescendantsOfKind(import_ts_morph3.SyntaxKind.JsxOpeningElement);
|
|
336
326
|
const jsxSelfClosing = sf.getDescendantsOfKind(import_ts_morph3.SyntaxKind.JsxSelfClosingElement);
|
|
@@ -388,19 +378,56 @@ function checkTopLevelPurity(sf) {
|
|
|
388
378
|
return { errors, warnings };
|
|
389
379
|
}
|
|
390
380
|
function checkWorkspaceLayout(projectRoot, errors) {
|
|
391
|
-
const krnlDir =
|
|
392
|
-
const srcDir =
|
|
381
|
+
const krnlDir = path2.join(projectRoot, "krnl");
|
|
382
|
+
const srcDir = path2.join(projectRoot, "src");
|
|
393
383
|
const targetDir = fs.existsSync(krnlDir) ? krnlDir : fs.existsSync(srcDir) ? srcDir : null;
|
|
394
384
|
if (!targetDir) return;
|
|
395
|
-
const backendDir =
|
|
396
|
-
const frontendDir =
|
|
385
|
+
const backendDir = path2.join(targetDir, "backend");
|
|
386
|
+
const frontendDir = path2.join(targetDir, "frontend");
|
|
397
387
|
if (fs.existsSync(backendDir)) {
|
|
398
|
-
const
|
|
388
|
+
const bServices = path2.join(backendDir, "services");
|
|
389
|
+
if (fs.existsSync(bServices)) {
|
|
390
|
+
for (const sEntry of fs.readdirSync(bServices, { withFileTypes: true })) {
|
|
391
|
+
if (!sEntry.isDirectory()) continue;
|
|
392
|
+
const sDir = path2.join(bServices, sEntry.name);
|
|
393
|
+
const sLibs = path2.join(sDir, "libraries");
|
|
394
|
+
if (fs.existsSync(sLibs)) {
|
|
395
|
+
for (const entry of fs.readdirSync(sLibs, { withFileTypes: true })) {
|
|
396
|
+
if (!entry.isDirectory()) continue;
|
|
397
|
+
const libPath = path2.join(sLibs, entry.name);
|
|
398
|
+
if (!fs.existsSync(path2.join(libPath, "manifest.json"))) {
|
|
399
|
+
errors.push({
|
|
400
|
+
ruleId: "krnl/concept-manifest-required",
|
|
401
|
+
filePath: libPath,
|
|
402
|
+
message: `Service-owned concept library "${sEntry.name}/${entry.name}" is missing a manifest.json file.`,
|
|
403
|
+
severity: "error"
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
const sFuncs = path2.join(sDir, "functionalities");
|
|
409
|
+
if (fs.existsSync(sFuncs)) {
|
|
410
|
+
for (const entry of fs.readdirSync(sFuncs, { withFileTypes: true })) {
|
|
411
|
+
if (!entry.isDirectory()) continue;
|
|
412
|
+
const funcPath = path2.join(sFuncs, entry.name);
|
|
413
|
+
if (!fs.existsSync(path2.join(funcPath, "manifest.json"))) {
|
|
414
|
+
errors.push({
|
|
415
|
+
ruleId: "krnl/functionality-manifest-required",
|
|
416
|
+
filePath: funcPath,
|
|
417
|
+
message: `Service-owned functionality "${sEntry.name}/${entry.name}" is missing a manifest.json file.`,
|
|
418
|
+
severity: "error"
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
const bLibs = path2.join(backendDir, "libraries");
|
|
399
426
|
if (fs.existsSync(bLibs)) {
|
|
400
427
|
for (const entry of fs.readdirSync(bLibs, { withFileTypes: true })) {
|
|
401
428
|
if (!entry.isDirectory()) continue;
|
|
402
|
-
const libPath =
|
|
403
|
-
if (!fs.existsSync(
|
|
429
|
+
const libPath = path2.join(bLibs, entry.name);
|
|
430
|
+
if (!fs.existsSync(path2.join(libPath, "manifest.json"))) {
|
|
404
431
|
errors.push({
|
|
405
432
|
ruleId: "krnl/concept-manifest-required",
|
|
406
433
|
filePath: libPath,
|
|
@@ -410,12 +437,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
|
|
|
410
437
|
}
|
|
411
438
|
}
|
|
412
439
|
}
|
|
413
|
-
const bFuncs =
|
|
440
|
+
const bFuncs = path2.join(backendDir, "functionalities");
|
|
414
441
|
if (fs.existsSync(bFuncs)) {
|
|
415
442
|
for (const entry of fs.readdirSync(bFuncs, { withFileTypes: true })) {
|
|
416
443
|
if (!entry.isDirectory()) continue;
|
|
417
|
-
const funcPath =
|
|
418
|
-
if (!fs.existsSync(
|
|
444
|
+
const funcPath = path2.join(bFuncs, entry.name);
|
|
445
|
+
if (!fs.existsSync(path2.join(funcPath, "manifest.json"))) {
|
|
419
446
|
errors.push({
|
|
420
447
|
ruleId: "krnl/functionality-manifest-required",
|
|
421
448
|
filePath: funcPath,
|
|
@@ -427,12 +454,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
|
|
|
427
454
|
}
|
|
428
455
|
}
|
|
429
456
|
if (fs.existsSync(frontendDir)) {
|
|
430
|
-
const fLibs =
|
|
457
|
+
const fLibs = path2.join(frontendDir, "libraries");
|
|
431
458
|
if (fs.existsSync(fLibs)) {
|
|
432
459
|
for (const entry of fs.readdirSync(fLibs, { withFileTypes: true })) {
|
|
433
460
|
if (!entry.isDirectory()) continue;
|
|
434
|
-
const libPath =
|
|
435
|
-
if (!fs.existsSync(
|
|
461
|
+
const libPath = path2.join(fLibs, entry.name);
|
|
462
|
+
if (!fs.existsSync(path2.join(libPath, "manifest.json"))) {
|
|
436
463
|
errors.push({
|
|
437
464
|
ruleId: "krnl/frontend-concept-manifest-required",
|
|
438
465
|
filePath: libPath,
|
|
@@ -442,12 +469,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
|
|
|
442
469
|
}
|
|
443
470
|
}
|
|
444
471
|
}
|
|
445
|
-
const fFuncs =
|
|
472
|
+
const fFuncs = path2.join(frontendDir, "functionalities");
|
|
446
473
|
if (fs.existsSync(fFuncs)) {
|
|
447
474
|
for (const entry of fs.readdirSync(fFuncs, { withFileTypes: true })) {
|
|
448
475
|
if (!entry.isDirectory()) continue;
|
|
449
|
-
const funcPath =
|
|
450
|
-
if (!fs.existsSync(
|
|
476
|
+
const funcPath = path2.join(fFuncs, entry.name);
|
|
477
|
+
if (!fs.existsSync(path2.join(funcPath, "manifest.json"))) {
|
|
451
478
|
errors.push({
|
|
452
479
|
ruleId: "krnl/frontend-functionality-manifest-required",
|
|
453
480
|
filePath: funcPath,
|
|
@@ -460,6 +487,250 @@ function checkWorkspaceLayout(projectRoot, errors) {
|
|
|
460
487
|
}
|
|
461
488
|
}
|
|
462
489
|
|
|
490
|
+
// src/rules/serviceBoundaryRules.ts
|
|
491
|
+
function checkServiceBoundaries(sf) {
|
|
492
|
+
const errors = [];
|
|
493
|
+
const warnings = [];
|
|
494
|
+
const filePath = sf.getFilePath().replace(/\\/g, "/");
|
|
495
|
+
const serviceMatch = filePath.match(/\/services\/([^/]+)\//);
|
|
496
|
+
if (!serviceMatch) {
|
|
497
|
+
return { errors, warnings };
|
|
498
|
+
}
|
|
499
|
+
const currentService = serviceMatch[1];
|
|
500
|
+
const imports = sf.getImportDeclarations();
|
|
501
|
+
for (const imp of imports) {
|
|
502
|
+
const spec = imp.getModuleSpecifierValue();
|
|
503
|
+
const crossServiceLibMatch = spec.match(/(?:^|\/|\.\.\/)services\/([^/]+)\/libraries\//) || spec.match(/\.\.\/(?:(?:\.\.\/)+)?([^/]+)\/libraries\//);
|
|
504
|
+
if (crossServiceLibMatch) {
|
|
505
|
+
const targetService = crossServiceLibMatch[1];
|
|
506
|
+
if (targetService !== currentService && targetService !== "." && targetService !== "..") {
|
|
507
|
+
errors.push({
|
|
508
|
+
ruleId: "krnl/no-cross-service-library-imports",
|
|
509
|
+
filePath,
|
|
510
|
+
line: imp.getStartLineNumber(),
|
|
511
|
+
message: `Cross-service library import forbidden: '${spec}'. Service '${currentService}' cannot import '${targetService}' libraries directly via filesystem. Access libraries through the '${targetService}' ServiceFacade (e.g. ${targetService}Facade.libraries).`,
|
|
512
|
+
severity: "error"
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return { errors, warnings };
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// src/rules/scopedLibraryRules.ts
|
|
521
|
+
var import_ts_morph4 = require("ts-morph");
|
|
522
|
+
var PRIMITIVE_AND_BUILTIN_TYPES = /* @__PURE__ */ new Set([
|
|
523
|
+
"string",
|
|
524
|
+
"number",
|
|
525
|
+
"boolean",
|
|
526
|
+
"symbol",
|
|
527
|
+
"bigint",
|
|
528
|
+
"void",
|
|
529
|
+
"undefined",
|
|
530
|
+
"null",
|
|
531
|
+
"never",
|
|
532
|
+
"unknown",
|
|
533
|
+
"any",
|
|
534
|
+
"object",
|
|
535
|
+
"Record",
|
|
536
|
+
"Array",
|
|
537
|
+
"ReadonlyArray",
|
|
538
|
+
"Map",
|
|
539
|
+
"Set",
|
|
540
|
+
"WeakMap",
|
|
541
|
+
"WeakSet",
|
|
542
|
+
"Promise",
|
|
543
|
+
"Date",
|
|
544
|
+
"RegExp",
|
|
545
|
+
"Error",
|
|
546
|
+
"Uint8Array",
|
|
547
|
+
"Int8Array",
|
|
548
|
+
"Uint16Array",
|
|
549
|
+
"Int16Array",
|
|
550
|
+
"Uint32Array",
|
|
551
|
+
"Int32Array",
|
|
552
|
+
"Float32Array",
|
|
553
|
+
"Float64Array",
|
|
554
|
+
"ArrayBuffer",
|
|
555
|
+
"Buffer",
|
|
556
|
+
"Iterable",
|
|
557
|
+
"AsyncIterable",
|
|
558
|
+
"Iterator",
|
|
559
|
+
"AsyncIterator",
|
|
560
|
+
"Partial",
|
|
561
|
+
"Required",
|
|
562
|
+
"Readonly",
|
|
563
|
+
"Pick",
|
|
564
|
+
"Omit",
|
|
565
|
+
"Exclude",
|
|
566
|
+
"Extract",
|
|
567
|
+
"NonNullable",
|
|
568
|
+
"Parameters",
|
|
569
|
+
"ConstructorParameters",
|
|
570
|
+
"ReturnType",
|
|
571
|
+
"InstanceType"
|
|
572
|
+
]);
|
|
573
|
+
function detectServiceContext(filePath) {
|
|
574
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
575
|
+
const match = normalized.match(/(?:^|\/)services\/([^/]+)\/libraries\/([^/]+)/);
|
|
576
|
+
if (match) {
|
|
577
|
+
return { serviceName: match[1], libraryName: match[2] };
|
|
578
|
+
}
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
function containsIdentifier(name, target) {
|
|
582
|
+
return name.toLowerCase().includes(target.toLowerCase());
|
|
583
|
+
}
|
|
584
|
+
function isCustomContextualType(typeName, serviceName, localTypes) {
|
|
585
|
+
if (PRIMITIVE_AND_BUILTIN_TYPES.has(typeName)) return false;
|
|
586
|
+
if (localTypes.has(typeName)) return true;
|
|
587
|
+
if (containsIdentifier(typeName, serviceName)) return true;
|
|
588
|
+
if (/^[A-Z][a-zA-Z0-9]+$/.test(typeName)) return true;
|
|
589
|
+
return false;
|
|
590
|
+
}
|
|
591
|
+
function hasContextualTypeReference(node, serviceName, localTypes) {
|
|
592
|
+
const typeRefs = node.getDescendantsOfKind(import_ts_morph4.SyntaxKind.TypeReference);
|
|
593
|
+
for (const ref of typeRefs) {
|
|
594
|
+
const text = ref.getTypeName().getText().trim();
|
|
595
|
+
if (isCustomContextualType(text, serviceName, localTypes)) {
|
|
596
|
+
return true;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
return false;
|
|
600
|
+
}
|
|
601
|
+
function checkScopedLibraryRules(sf) {
|
|
602
|
+
const errors = [];
|
|
603
|
+
const warnings = [];
|
|
604
|
+
const promotableAssets = [];
|
|
605
|
+
const filePath = sf.getFilePath().replace(/\\/g, "/");
|
|
606
|
+
const context = detectServiceContext(filePath);
|
|
607
|
+
if (!context) {
|
|
608
|
+
return { errors, warnings, promotableAssets };
|
|
609
|
+
}
|
|
610
|
+
const { serviceName, libraryName } = context;
|
|
611
|
+
const localTypes = /* @__PURE__ */ new Set();
|
|
612
|
+
sf.getInterfaces().forEach((i) => localTypes.add(i.getName()));
|
|
613
|
+
sf.getTypeAliases().forEach((t) => localTypes.add(t.getName()));
|
|
614
|
+
sf.getClasses().forEach((c) => {
|
|
615
|
+
const n = c.getName();
|
|
616
|
+
if (n) localTypes.add(n);
|
|
617
|
+
});
|
|
618
|
+
sf.getEnums().forEach((e) => localTypes.add(e.getName()));
|
|
619
|
+
const functions = sf.getFunctions();
|
|
620
|
+
for (const fn of functions) {
|
|
621
|
+
const fnName = fn.getName();
|
|
622
|
+
if (!fnName) continue;
|
|
623
|
+
const isContextual = hasContextualTypeReference(fn, serviceName, localTypes);
|
|
624
|
+
const hasServiceName = containsIdentifier(fnName, serviceName);
|
|
625
|
+
if (isContextual) {
|
|
626
|
+
if (!hasServiceName) {
|
|
627
|
+
errors.push({
|
|
628
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
629
|
+
filePath,
|
|
630
|
+
line: fn.getStartLineNumber(),
|
|
631
|
+
message: `Service library asset '${fnName}' in service '${serviceName}' violates scoped library naming convention. Custom library asset identifiers must contain the owning service name ('${serviceName}'). Expected name containing '${serviceName}' (e.g. '${serviceName.toLowerCase()}${fnName[0].toUpperCase()}${fnName.slice(1)}'), or eliminate contextual custom type dependencies to make it a generic promotable utility.`,
|
|
632
|
+
severity: "error"
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
} else {
|
|
636
|
+
promotableAssets.push({
|
|
637
|
+
name: fnName,
|
|
638
|
+
kind: "function",
|
|
639
|
+
filePath,
|
|
640
|
+
scope: "service",
|
|
641
|
+
scopeName: serviceName,
|
|
642
|
+
target: "GutTS"
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
for (const stmt of sf.getVariableStatements()) {
|
|
647
|
+
for (const decl of stmt.getDeclarations()) {
|
|
648
|
+
const varName = decl.getName();
|
|
649
|
+
const init = decl.getInitializer();
|
|
650
|
+
const isFunction = init && (init.getKind() === import_ts_morph4.SyntaxKind.ArrowFunction || init.getKind() === import_ts_morph4.SyntaxKind.FunctionExpression);
|
|
651
|
+
if (isFunction) {
|
|
652
|
+
const isContextual = hasContextualTypeReference(decl, serviceName, localTypes);
|
|
653
|
+
const hasServiceName = containsIdentifier(varName, serviceName);
|
|
654
|
+
if (isContextual) {
|
|
655
|
+
if (!hasServiceName) {
|
|
656
|
+
errors.push({
|
|
657
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
658
|
+
filePath,
|
|
659
|
+
line: decl.getStartLineNumber(),
|
|
660
|
+
message: `Service library asset '${varName}' in service '${serviceName}' violates scoped library naming convention. Custom library asset identifiers must contain the owning service name ('${serviceName}'). Expected name containing '${serviceName}', or eliminate contextual custom type dependencies to make it a generic promotable utility.`,
|
|
661
|
+
severity: "error"
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
} else {
|
|
665
|
+
promotableAssets.push({
|
|
666
|
+
name: varName,
|
|
667
|
+
kind: "function",
|
|
668
|
+
filePath,
|
|
669
|
+
scope: "service",
|
|
670
|
+
scopeName: serviceName,
|
|
671
|
+
target: "GutTS"
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
} else {
|
|
675
|
+
const isContextual = hasContextualTypeReference(decl, serviceName, localTypes);
|
|
676
|
+
const hasServiceName = containsIdentifier(varName, serviceName);
|
|
677
|
+
if (isContextual && !hasServiceName) {
|
|
678
|
+
errors.push({
|
|
679
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
680
|
+
filePath,
|
|
681
|
+
line: decl.getStartLineNumber(),
|
|
682
|
+
message: `Service library asset '${varName}' in service '${serviceName}' violates scoped library naming convention. Custom library asset identifiers must contain the owning service name ('${serviceName}').`,
|
|
683
|
+
severity: "error"
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
for (const iface of sf.getInterfaces()) {
|
|
690
|
+
const name = iface.getName();
|
|
691
|
+
const hasServiceName = containsIdentifier(name, serviceName);
|
|
692
|
+
const hasProps = iface.getProperties().length > 0;
|
|
693
|
+
if (hasProps && !hasServiceName) {
|
|
694
|
+
errors.push({
|
|
695
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
696
|
+
filePath,
|
|
697
|
+
line: iface.getStartLineNumber(),
|
|
698
|
+
message: `Service library interface '${name}' in service '${serviceName}' violates scoped library naming convention. Custom library asset identifiers must contain the owning service name ('${serviceName}'). Expected name like '${serviceName}${name}'.`,
|
|
699
|
+
severity: "error"
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
for (const t of sf.getTypeAliases()) {
|
|
704
|
+
const name = t.getName();
|
|
705
|
+
const hasServiceName = containsIdentifier(name, serviceName);
|
|
706
|
+
const isContextual = hasContextualTypeReference(t, serviceName, localTypes);
|
|
707
|
+
if (isContextual && !hasServiceName) {
|
|
708
|
+
errors.push({
|
|
709
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
710
|
+
filePath,
|
|
711
|
+
line: t.getStartLineNumber(),
|
|
712
|
+
message: `Service library type alias '${name}' in service '${serviceName}' violates scoped library naming convention. Custom library asset identifiers must contain the owning service name ('${serviceName}'). Expected name like '${serviceName}${name}'.`,
|
|
713
|
+
severity: "error"
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
for (const cls of sf.getClasses()) {
|
|
718
|
+
const name = cls.getName();
|
|
719
|
+
if (!name) continue;
|
|
720
|
+
const hasServiceName = containsIdentifier(name, serviceName);
|
|
721
|
+
if (!hasServiceName) {
|
|
722
|
+
errors.push({
|
|
723
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
724
|
+
filePath,
|
|
725
|
+
line: cls.getStartLineNumber(),
|
|
726
|
+
message: `Service library class '${name}' in service '${serviceName}' violates scoped library naming convention. Custom library asset identifiers must contain the owning service name ('${serviceName}'). Expected name like '${serviceName}${name}'.`,
|
|
727
|
+
severity: "error"
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return { errors, warnings, promotableAssets };
|
|
732
|
+
}
|
|
733
|
+
|
|
463
734
|
// src/KrnlValidatorEngine.ts
|
|
464
735
|
var KrnlValidatorEngine = class {
|
|
465
736
|
project;
|
|
@@ -467,17 +738,17 @@ var KrnlValidatorEngine = class {
|
|
|
467
738
|
limitOptions;
|
|
468
739
|
constructor(optionsOrRoot) {
|
|
469
740
|
const options = typeof optionsOrRoot === "string" ? { projectRoot: optionsOrRoot } : optionsOrRoot;
|
|
470
|
-
this.projectRoot =
|
|
741
|
+
this.projectRoot = path3.resolve(options.projectRoot || process.cwd());
|
|
471
742
|
this.limitOptions = {
|
|
472
743
|
maxFileLineLimit: options.maxFileLineLimit ?? 200,
|
|
473
744
|
maxMainLogicLimit: options.maxMainLogicLimit ?? 20,
|
|
474
745
|
maxHelperLineLimit: options.maxHelperLineLimit ?? 30
|
|
475
746
|
};
|
|
476
|
-
const tsConfigPath =
|
|
747
|
+
const tsConfigPath = path3.join(this.projectRoot, "tsconfig.json");
|
|
477
748
|
if (fs2.existsSync(tsConfigPath)) {
|
|
478
|
-
this.project = new
|
|
749
|
+
this.project = new import_ts_morph5.Project({ tsConfigFilePath: tsConfigPath, skipAddingFilesFromTsConfig: true });
|
|
479
750
|
} else {
|
|
480
|
-
this.project = new
|
|
751
|
+
this.project = new import_ts_morph5.Project({ compilerOptions: {
|
|
481
752
|
target: 99
|
|
482
753
|
/* ESNext */
|
|
483
754
|
} });
|
|
@@ -487,33 +758,55 @@ var KrnlValidatorEngine = class {
|
|
|
487
758
|
const files = this.collectSourceFiles(this.projectRoot);
|
|
488
759
|
const errors = [];
|
|
489
760
|
const warnings = [];
|
|
761
|
+
const promotableAssets = [];
|
|
490
762
|
checkWorkspaceLayout(this.projectRoot, errors);
|
|
491
763
|
for (const f of files) {
|
|
492
764
|
const sf = this.project.addSourceFileAtPath(f);
|
|
493
765
|
const fileReport = this.validateSourceFile(sf);
|
|
494
766
|
errors.push(...fileReport.errors);
|
|
495
767
|
warnings.push(...fileReport.warnings);
|
|
768
|
+
if (fileReport.promotableAssets) {
|
|
769
|
+
promotableAssets.push(...fileReport.promotableAssets);
|
|
770
|
+
}
|
|
496
771
|
}
|
|
497
772
|
return {
|
|
498
773
|
valid: errors.length === 0,
|
|
499
774
|
totalFiles: files.length,
|
|
500
775
|
errors,
|
|
501
|
-
warnings
|
|
776
|
+
warnings,
|
|
777
|
+
promotableAssets
|
|
502
778
|
};
|
|
503
779
|
}
|
|
504
780
|
validateSourceFile(sf) {
|
|
505
781
|
const filePath = sf.getFilePath();
|
|
506
|
-
const baseName =
|
|
782
|
+
const baseName = path3.basename(filePath);
|
|
507
783
|
if (baseName.includes("_pb.") || baseName.endsWith(".d.ts")) {
|
|
508
|
-
return { errors: [], warnings: [] };
|
|
784
|
+
return { errors: [], warnings: [], promotableAssets: [] };
|
|
509
785
|
}
|
|
510
786
|
const limits = checkFileLimits(sf, this.limitOptions);
|
|
511
787
|
const purity = checkTopLevelPurity(sf);
|
|
512
788
|
const components = checkComponentRules(sf);
|
|
513
|
-
const
|
|
789
|
+
const orchestration = checkOrchestrationRules(sf);
|
|
790
|
+
const boundaries = checkServiceBoundaries(sf);
|
|
791
|
+
const scopedLibraries = checkScopedLibraryRules(sf);
|
|
514
792
|
return {
|
|
515
|
-
errors: [
|
|
516
|
-
|
|
793
|
+
errors: [
|
|
794
|
+
...limits.errors,
|
|
795
|
+
...purity.errors,
|
|
796
|
+
...components.errors,
|
|
797
|
+
...orchestration.errors,
|
|
798
|
+
...boundaries.errors,
|
|
799
|
+
...scopedLibraries.errors
|
|
800
|
+
],
|
|
801
|
+
warnings: [
|
|
802
|
+
...limits.warnings,
|
|
803
|
+
...purity.warnings,
|
|
804
|
+
...components.warnings,
|
|
805
|
+
...orchestration.warnings,
|
|
806
|
+
...boundaries.warnings,
|
|
807
|
+
...scopedLibraries.warnings
|
|
808
|
+
],
|
|
809
|
+
promotableAssets: scopedLibraries.promotableAssets
|
|
517
810
|
};
|
|
518
811
|
}
|
|
519
812
|
collectSourceFiles(dir, collected = []) {
|
|
@@ -521,7 +814,7 @@ var KrnlValidatorEngine = class {
|
|
|
521
814
|
const entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
522
815
|
for (const entry of entries) {
|
|
523
816
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git") continue;
|
|
524
|
-
const full =
|
|
817
|
+
const full = path3.join(dir, entry.name);
|
|
525
818
|
if (entry.isDirectory()) {
|
|
526
819
|
this.collectSourceFiles(full, collected);
|
|
527
820
|
} else if (entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".js") || entry.name.endsWith(".tsx") || entry.name.endsWith(".jsx"))) {
|