@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/KrnlValidatorEngine.ts
|
|
2
2
|
import * as fs2 from "fs";
|
|
3
|
-
import * as
|
|
3
|
+
import * as path3 from "path";
|
|
4
4
|
import { Project } from "ts-morph";
|
|
5
5
|
|
|
6
6
|
// src/rules/fileLimits.ts
|
|
@@ -8,7 +8,7 @@ function checkFileLimits(sf, options) {
|
|
|
8
8
|
const errors = [];
|
|
9
9
|
const warnings = [];
|
|
10
10
|
const filePath = sf.getFilePath();
|
|
11
|
-
const sourceText = sf.
|
|
11
|
+
const sourceText = sf.getFullText();
|
|
12
12
|
const lines = sourceText.split("\n");
|
|
13
13
|
if (lines.length > options.maxFileLineLimit) {
|
|
14
14
|
errors.push({
|
|
@@ -123,7 +123,7 @@ function checkComponentRules(sf) {
|
|
|
123
123
|
ruleId: "krnl/helper-purity",
|
|
124
124
|
filePath,
|
|
125
125
|
line: decl.getStartLineNumber(),
|
|
126
|
-
message: `Helper functions (Layer 1) cannot directly import I/O modules ('${spec}'). Delegate to Layer 0 libraries or
|
|
126
|
+
message: `Helper functions (Layer 1) cannot directly import I/O modules ('${spec}'). Delegate to Layer 0 libraries or ServiceFacade context.`,
|
|
127
127
|
severity: "error"
|
|
128
128
|
});
|
|
129
129
|
}
|
|
@@ -132,15 +132,13 @@ function checkComponentRules(sf) {
|
|
|
132
132
|
return { errors, warnings };
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
// src/rules/
|
|
136
|
-
import * as path2 from "path";
|
|
135
|
+
// src/rules/orchestrationRules.ts
|
|
137
136
|
import { SyntaxKind as SyntaxKind2, Node } from "ts-morph";
|
|
138
|
-
function
|
|
137
|
+
function checkOrchestrationRules(sf) {
|
|
139
138
|
const errors = [];
|
|
140
139
|
const warnings = [];
|
|
141
140
|
const filePath = sf.getFilePath();
|
|
142
141
|
const sourceText = sf.getText();
|
|
143
|
-
const baseName = path2.basename(filePath);
|
|
144
142
|
const calls = sf.getDescendantsOfKind(SyntaxKind2.CallExpression);
|
|
145
143
|
for (const call of calls) {
|
|
146
144
|
const exprText = call.getExpression().getText();
|
|
@@ -149,7 +147,7 @@ function checkEntityRules(sf) {
|
|
|
149
147
|
ruleId: "krnl/no-polling",
|
|
150
148
|
filePath,
|
|
151
149
|
line: call.getStartLineNumber(),
|
|
152
|
-
message: `Prohibited use of 'setInterval'. Krnl applications must use reactive event streams
|
|
150
|
+
message: `Prohibited use of 'setInterval'. Krnl applications must use reactive event streams or triggers.`,
|
|
153
151
|
severity: "error"
|
|
154
152
|
});
|
|
155
153
|
}
|
|
@@ -158,65 +156,36 @@ function checkEntityRules(sf) {
|
|
|
158
156
|
const match = sourceText.match(/main\s*=\s*async\s*\([^,]+,\s*\{([^}]*)\}\s*\)/);
|
|
159
157
|
if (match) {
|
|
160
158
|
const destructured = match[1];
|
|
161
|
-
if (/\bsystem\b/.test(destructured)
|
|
159
|
+
if (/\bsystem\b/.test(destructured)) {
|
|
162
160
|
errors.push({
|
|
163
161
|
ruleId: "krnl/context-destructuring",
|
|
164
162
|
filePath,
|
|
165
|
-
message: `Functionality context parameter destructures 'system'. Functionality passes { state,
|
|
163
|
+
message: `Functionality context parameter destructures 'system'. Functionality passes { state, orchestration } or service context.`,
|
|
166
164
|
severity: "error"
|
|
167
165
|
});
|
|
168
166
|
}
|
|
169
167
|
}
|
|
170
168
|
}
|
|
171
|
-
const
|
|
169
|
+
const isOrchestrationClass = sf.getClasses().some((c) => {
|
|
172
170
|
const ext = c.getExtends();
|
|
173
|
-
return ext && (ext.getText().includes("
|
|
171
|
+
return ext && (ext.getText().includes("FunctionalityOrchestration") || ext.getText().includes("Orchestration") || ext.getText().includes("krnlOrchestrationBase"));
|
|
174
172
|
});
|
|
175
|
-
if (
|
|
173
|
+
if (isOrchestrationClass) {
|
|
176
174
|
for (const decl of sf.getImportDeclarations()) {
|
|
177
175
|
const spec = decl.getModuleSpecifierValue();
|
|
178
176
|
if (spec.includes("libraries/") || spec.includes("Concepts")) {
|
|
179
177
|
errors.push({
|
|
180
|
-
ruleId: "krnl/
|
|
178
|
+
ruleId: "krnl/orchestration-no-libraries",
|
|
181
179
|
filePath,
|
|
182
180
|
line: decl.getStartLineNumber(),
|
|
183
|
-
message: `
|
|
181
|
+
message: `FunctionalityOrchestration class violates Library Calling Invariant. FunctionalityOrchestrations must not call or import libraries directly ('${spec}'). Only functionalities are permitted to call shared libraries.`,
|
|
184
182
|
severity: "error"
|
|
185
183
|
});
|
|
186
184
|
}
|
|
187
185
|
}
|
|
188
|
-
let loadAllLine = -1;
|
|
189
|
-
const addLocalLines = [];
|
|
190
|
-
for (const call of calls) {
|
|
191
|
-
const txt = call.getText();
|
|
192
|
-
if (txt.includes("MagneticLoader.loadAll") || txt.includes("KrnlMagneticLoader.loadAll")) {
|
|
193
|
-
loadAllLine = call.getStartLineNumber();
|
|
194
|
-
} else if (txt.startsWith("this.addLocal(")) {
|
|
195
|
-
const hasUiSpec = txt.includes("uiSpec");
|
|
196
|
-
const idMatch = txt.match(/id\s*:\s*["']([^"']+)["']/);
|
|
197
|
-
addLocalLines.push({
|
|
198
|
-
line: call.getStartLineNumber(),
|
|
199
|
-
hasUiSpec,
|
|
200
|
-
id: idMatch ? idMatch[1] : "unknown"
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
if (loadAllLine !== -1) {
|
|
205
|
-
for (const al of addLocalLines) {
|
|
206
|
-
if (al.hasUiSpec && al.line > loadAllLine) {
|
|
207
|
-
errors.push({
|
|
208
|
-
ruleId: "krnl/boot-order",
|
|
209
|
-
filePath,
|
|
210
|
-
line: al.line,
|
|
211
|
-
message: `addLocal('${al.id}') with uiSpec at line ${al.line} appears AFTER loadAll() at line ${loadAllLine}. All addLocal() with UI must precede loadAll().`,
|
|
212
|
-
severity: "error"
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
186
|
for (const cls of sf.getClasses()) {
|
|
218
187
|
const ext = cls.getExtends();
|
|
219
|
-
if (ext && (ext.getText().includes("
|
|
188
|
+
if (ext && (ext.getText().includes("FunctionalityOrchestration") || ext.getText().includes("Orchestration") || ext.getText().includes("krnlOrchestrationBase"))) {
|
|
220
189
|
const loops = [
|
|
221
190
|
...cls.getDescendantsOfKind(SyntaxKind2.ForStatement),
|
|
222
191
|
...cls.getDescendantsOfKind(SyntaxKind2.ForOfStatement),
|
|
@@ -226,21 +195,34 @@ function checkEntityRules(sf) {
|
|
|
226
195
|
];
|
|
227
196
|
for (const loop of loops) {
|
|
228
197
|
errors.push({
|
|
229
|
-
ruleId: "krnl/
|
|
198
|
+
ruleId: "krnl/orchestration-purity",
|
|
230
199
|
filePath,
|
|
231
200
|
line: loop.getStartLineNumber(),
|
|
232
|
-
message: `
|
|
201
|
+
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.`,
|
|
233
202
|
severity: "error"
|
|
234
203
|
});
|
|
235
204
|
}
|
|
205
|
+
const allowedMethods = /* @__PURE__ */ new Set([
|
|
206
|
+
"flow",
|
|
207
|
+
"getFlow",
|
|
208
|
+
"listFlows",
|
|
209
|
+
"clearFlows",
|
|
210
|
+
"thenFunctionality",
|
|
211
|
+
"parallel",
|
|
212
|
+
"branch",
|
|
213
|
+
"fanOut",
|
|
214
|
+
"thenFunctionalityOrchestration",
|
|
215
|
+
"getSteps",
|
|
216
|
+
"assertServiceBoundary"
|
|
217
|
+
]);
|
|
236
218
|
for (const method of cls.getMethods()) {
|
|
237
219
|
const methodName = method.getName();
|
|
238
|
-
if (!
|
|
220
|
+
if (!allowedMethods.has(methodName)) {
|
|
239
221
|
errors.push({
|
|
240
|
-
ruleId: "krnl/
|
|
222
|
+
ruleId: "krnl/orchestration-purity",
|
|
241
223
|
filePath,
|
|
242
224
|
line: method.getStartLineNumber(),
|
|
243
|
-
message: `
|
|
225
|
+
message: `FunctionalityOrchestration '${cls.getName() || "Anonymous"}' defines custom method '${methodName}'. FunctionalityOrchestrations are purely declarative compositors. Define capabilities as functionalities or global library functions.`,
|
|
244
226
|
severity: "error"
|
|
245
227
|
});
|
|
246
228
|
}
|
|
@@ -249,7 +231,7 @@ function checkEntityRules(sf) {
|
|
|
249
231
|
}
|
|
250
232
|
for (const call of calls) {
|
|
251
233
|
const callText = call.getText();
|
|
252
|
-
if (callText.startsWith("this.
|
|
234
|
+
if (callText.startsWith("this.flow(") || callText.startsWith("orchestration.flow(")) {
|
|
253
235
|
let currentExpr = call;
|
|
254
236
|
const chainCalls = [];
|
|
255
237
|
while (currentExpr && Node.isCallExpression(currentExpr)) {
|
|
@@ -266,14 +248,22 @@ function checkEntityRules(sf) {
|
|
|
266
248
|
}
|
|
267
249
|
let chainId = "orchestration";
|
|
268
250
|
for (const step of chainCalls) {
|
|
269
|
-
if (step.name === "
|
|
251
|
+
if (step.name === "flow") {
|
|
270
252
|
chainId = step.argText ? step.argText.replace(/['"]/g, "") : "orchestration";
|
|
271
253
|
} else if (step.name === "thenFunction") {
|
|
272
254
|
errors.push({
|
|
273
|
-
ruleId: "krnl/
|
|
255
|
+
ruleId: "krnl/orchestration-no-direct-library-calls",
|
|
274
256
|
filePath,
|
|
275
257
|
line: step.node.getStartLineNumber(),
|
|
276
|
-
message: `
|
|
258
|
+
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).`,
|
|
259
|
+
severity: "error"
|
|
260
|
+
});
|
|
261
|
+
} else if (step.name === "thenService") {
|
|
262
|
+
errors.push({
|
|
263
|
+
ruleId: "krnl/orchestration-no-external-services",
|
|
264
|
+
filePath,
|
|
265
|
+
line: step.node.getStartLineNumber(),
|
|
266
|
+
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.`,
|
|
277
267
|
severity: "error"
|
|
278
268
|
});
|
|
279
269
|
}
|
|
@@ -286,15 +276,15 @@ function checkEntityRules(sf) {
|
|
|
286
276
|
|
|
287
277
|
// src/rules/workspaceRules.ts
|
|
288
278
|
import * as fs from "fs";
|
|
289
|
-
import * as
|
|
279
|
+
import * as path2 from "path";
|
|
290
280
|
import { SyntaxKind as SyntaxKind3 } from "ts-morph";
|
|
291
281
|
function checkTopLevelPurity(sf) {
|
|
292
282
|
const errors = [];
|
|
293
283
|
const warnings = [];
|
|
294
284
|
const filePath = sf.getFilePath();
|
|
295
|
-
const baseName =
|
|
285
|
+
const baseName = path2.basename(filePath);
|
|
296
286
|
const isUiTopLevel = /^(App|main|index|_app|root)\.(tsx|jsx)$/i.test(baseName);
|
|
297
|
-
const isBackendTopLevel = /^(server|app)\.(ts|js)$/i.test(baseName) && !filePath.includes("/components/") && !filePath.includes("/
|
|
287
|
+
const isBackendTopLevel = /^(server|app|index)\.(ts|js)$/i.test(baseName) && !filePath.includes("/components/") && !filePath.includes("/orchestrations/") && !filePath.includes("/services/") && !filePath.includes("/libraries/");
|
|
298
288
|
if (isUiTopLevel) {
|
|
299
289
|
const jsxElements = sf.getDescendantsOfKind(SyntaxKind3.JsxOpeningElement);
|
|
300
290
|
const jsxSelfClosing = sf.getDescendantsOfKind(SyntaxKind3.JsxSelfClosingElement);
|
|
@@ -352,19 +342,56 @@ function checkTopLevelPurity(sf) {
|
|
|
352
342
|
return { errors, warnings };
|
|
353
343
|
}
|
|
354
344
|
function checkWorkspaceLayout(projectRoot, errors) {
|
|
355
|
-
const krnlDir =
|
|
356
|
-
const srcDir =
|
|
345
|
+
const krnlDir = path2.join(projectRoot, "krnl");
|
|
346
|
+
const srcDir = path2.join(projectRoot, "src");
|
|
357
347
|
const targetDir = fs.existsSync(krnlDir) ? krnlDir : fs.existsSync(srcDir) ? srcDir : null;
|
|
358
348
|
if (!targetDir) return;
|
|
359
|
-
const backendDir =
|
|
360
|
-
const frontendDir =
|
|
349
|
+
const backendDir = path2.join(targetDir, "backend");
|
|
350
|
+
const frontendDir = path2.join(targetDir, "frontend");
|
|
361
351
|
if (fs.existsSync(backendDir)) {
|
|
362
|
-
const
|
|
352
|
+
const bServices = path2.join(backendDir, "services");
|
|
353
|
+
if (fs.existsSync(bServices)) {
|
|
354
|
+
for (const sEntry of fs.readdirSync(bServices, { withFileTypes: true })) {
|
|
355
|
+
if (!sEntry.isDirectory()) continue;
|
|
356
|
+
const sDir = path2.join(bServices, sEntry.name);
|
|
357
|
+
const sLibs = path2.join(sDir, "libraries");
|
|
358
|
+
if (fs.existsSync(sLibs)) {
|
|
359
|
+
for (const entry of fs.readdirSync(sLibs, { withFileTypes: true })) {
|
|
360
|
+
if (!entry.isDirectory()) continue;
|
|
361
|
+
const libPath = path2.join(sLibs, entry.name);
|
|
362
|
+
if (!fs.existsSync(path2.join(libPath, "manifest.json"))) {
|
|
363
|
+
errors.push({
|
|
364
|
+
ruleId: "krnl/concept-manifest-required",
|
|
365
|
+
filePath: libPath,
|
|
366
|
+
message: `Service-owned concept library "${sEntry.name}/${entry.name}" is missing a manifest.json file.`,
|
|
367
|
+
severity: "error"
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const sFuncs = path2.join(sDir, "functionalities");
|
|
373
|
+
if (fs.existsSync(sFuncs)) {
|
|
374
|
+
for (const entry of fs.readdirSync(sFuncs, { withFileTypes: true })) {
|
|
375
|
+
if (!entry.isDirectory()) continue;
|
|
376
|
+
const funcPath = path2.join(sFuncs, entry.name);
|
|
377
|
+
if (!fs.existsSync(path2.join(funcPath, "manifest.json"))) {
|
|
378
|
+
errors.push({
|
|
379
|
+
ruleId: "krnl/functionality-manifest-required",
|
|
380
|
+
filePath: funcPath,
|
|
381
|
+
message: `Service-owned functionality "${sEntry.name}/${entry.name}" is missing a manifest.json file.`,
|
|
382
|
+
severity: "error"
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const bLibs = path2.join(backendDir, "libraries");
|
|
363
390
|
if (fs.existsSync(bLibs)) {
|
|
364
391
|
for (const entry of fs.readdirSync(bLibs, { withFileTypes: true })) {
|
|
365
392
|
if (!entry.isDirectory()) continue;
|
|
366
|
-
const libPath =
|
|
367
|
-
if (!fs.existsSync(
|
|
393
|
+
const libPath = path2.join(bLibs, entry.name);
|
|
394
|
+
if (!fs.existsSync(path2.join(libPath, "manifest.json"))) {
|
|
368
395
|
errors.push({
|
|
369
396
|
ruleId: "krnl/concept-manifest-required",
|
|
370
397
|
filePath: libPath,
|
|
@@ -374,12 +401,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
|
|
|
374
401
|
}
|
|
375
402
|
}
|
|
376
403
|
}
|
|
377
|
-
const bFuncs =
|
|
404
|
+
const bFuncs = path2.join(backendDir, "functionalities");
|
|
378
405
|
if (fs.existsSync(bFuncs)) {
|
|
379
406
|
for (const entry of fs.readdirSync(bFuncs, { withFileTypes: true })) {
|
|
380
407
|
if (!entry.isDirectory()) continue;
|
|
381
|
-
const funcPath =
|
|
382
|
-
if (!fs.existsSync(
|
|
408
|
+
const funcPath = path2.join(bFuncs, entry.name);
|
|
409
|
+
if (!fs.existsSync(path2.join(funcPath, "manifest.json"))) {
|
|
383
410
|
errors.push({
|
|
384
411
|
ruleId: "krnl/functionality-manifest-required",
|
|
385
412
|
filePath: funcPath,
|
|
@@ -391,12 +418,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
|
|
|
391
418
|
}
|
|
392
419
|
}
|
|
393
420
|
if (fs.existsSync(frontendDir)) {
|
|
394
|
-
const fLibs =
|
|
421
|
+
const fLibs = path2.join(frontendDir, "libraries");
|
|
395
422
|
if (fs.existsSync(fLibs)) {
|
|
396
423
|
for (const entry of fs.readdirSync(fLibs, { withFileTypes: true })) {
|
|
397
424
|
if (!entry.isDirectory()) continue;
|
|
398
|
-
const libPath =
|
|
399
|
-
if (!fs.existsSync(
|
|
425
|
+
const libPath = path2.join(fLibs, entry.name);
|
|
426
|
+
if (!fs.existsSync(path2.join(libPath, "manifest.json"))) {
|
|
400
427
|
errors.push({
|
|
401
428
|
ruleId: "krnl/frontend-concept-manifest-required",
|
|
402
429
|
filePath: libPath,
|
|
@@ -406,12 +433,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
|
|
|
406
433
|
}
|
|
407
434
|
}
|
|
408
435
|
}
|
|
409
|
-
const fFuncs =
|
|
436
|
+
const fFuncs = path2.join(frontendDir, "functionalities");
|
|
410
437
|
if (fs.existsSync(fFuncs)) {
|
|
411
438
|
for (const entry of fs.readdirSync(fFuncs, { withFileTypes: true })) {
|
|
412
439
|
if (!entry.isDirectory()) continue;
|
|
413
|
-
const funcPath =
|
|
414
|
-
if (!fs.existsSync(
|
|
440
|
+
const funcPath = path2.join(fFuncs, entry.name);
|
|
441
|
+
if (!fs.existsSync(path2.join(funcPath, "manifest.json"))) {
|
|
415
442
|
errors.push({
|
|
416
443
|
ruleId: "krnl/frontend-functionality-manifest-required",
|
|
417
444
|
filePath: funcPath,
|
|
@@ -424,6 +451,250 @@ function checkWorkspaceLayout(projectRoot, errors) {
|
|
|
424
451
|
}
|
|
425
452
|
}
|
|
426
453
|
|
|
454
|
+
// src/rules/serviceBoundaryRules.ts
|
|
455
|
+
function checkServiceBoundaries(sf) {
|
|
456
|
+
const errors = [];
|
|
457
|
+
const warnings = [];
|
|
458
|
+
const filePath = sf.getFilePath().replace(/\\/g, "/");
|
|
459
|
+
const serviceMatch = filePath.match(/\/services\/([^/]+)\//);
|
|
460
|
+
if (!serviceMatch) {
|
|
461
|
+
return { errors, warnings };
|
|
462
|
+
}
|
|
463
|
+
const currentService = serviceMatch[1];
|
|
464
|
+
const imports = sf.getImportDeclarations();
|
|
465
|
+
for (const imp of imports) {
|
|
466
|
+
const spec = imp.getModuleSpecifierValue();
|
|
467
|
+
const crossServiceLibMatch = spec.match(/(?:^|\/|\.\.\/)services\/([^/]+)\/libraries\//) || spec.match(/\.\.\/(?:(?:\.\.\/)+)?([^/]+)\/libraries\//);
|
|
468
|
+
if (crossServiceLibMatch) {
|
|
469
|
+
const targetService = crossServiceLibMatch[1];
|
|
470
|
+
if (targetService !== currentService && targetService !== "." && targetService !== "..") {
|
|
471
|
+
errors.push({
|
|
472
|
+
ruleId: "krnl/no-cross-service-library-imports",
|
|
473
|
+
filePath,
|
|
474
|
+
line: imp.getStartLineNumber(),
|
|
475
|
+
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).`,
|
|
476
|
+
severity: "error"
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return { errors, warnings };
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// src/rules/scopedLibraryRules.ts
|
|
485
|
+
import { SyntaxKind as SyntaxKind4 } from "ts-morph";
|
|
486
|
+
var PRIMITIVE_AND_BUILTIN_TYPES = /* @__PURE__ */ new Set([
|
|
487
|
+
"string",
|
|
488
|
+
"number",
|
|
489
|
+
"boolean",
|
|
490
|
+
"symbol",
|
|
491
|
+
"bigint",
|
|
492
|
+
"void",
|
|
493
|
+
"undefined",
|
|
494
|
+
"null",
|
|
495
|
+
"never",
|
|
496
|
+
"unknown",
|
|
497
|
+
"any",
|
|
498
|
+
"object",
|
|
499
|
+
"Record",
|
|
500
|
+
"Array",
|
|
501
|
+
"ReadonlyArray",
|
|
502
|
+
"Map",
|
|
503
|
+
"Set",
|
|
504
|
+
"WeakMap",
|
|
505
|
+
"WeakSet",
|
|
506
|
+
"Promise",
|
|
507
|
+
"Date",
|
|
508
|
+
"RegExp",
|
|
509
|
+
"Error",
|
|
510
|
+
"Uint8Array",
|
|
511
|
+
"Int8Array",
|
|
512
|
+
"Uint16Array",
|
|
513
|
+
"Int16Array",
|
|
514
|
+
"Uint32Array",
|
|
515
|
+
"Int32Array",
|
|
516
|
+
"Float32Array",
|
|
517
|
+
"Float64Array",
|
|
518
|
+
"ArrayBuffer",
|
|
519
|
+
"Buffer",
|
|
520
|
+
"Iterable",
|
|
521
|
+
"AsyncIterable",
|
|
522
|
+
"Iterator",
|
|
523
|
+
"AsyncIterator",
|
|
524
|
+
"Partial",
|
|
525
|
+
"Required",
|
|
526
|
+
"Readonly",
|
|
527
|
+
"Pick",
|
|
528
|
+
"Omit",
|
|
529
|
+
"Exclude",
|
|
530
|
+
"Extract",
|
|
531
|
+
"NonNullable",
|
|
532
|
+
"Parameters",
|
|
533
|
+
"ConstructorParameters",
|
|
534
|
+
"ReturnType",
|
|
535
|
+
"InstanceType"
|
|
536
|
+
]);
|
|
537
|
+
function detectServiceContext(filePath) {
|
|
538
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
539
|
+
const match = normalized.match(/(?:^|\/)services\/([^/]+)\/libraries\/([^/]+)/);
|
|
540
|
+
if (match) {
|
|
541
|
+
return { serviceName: match[1], libraryName: match[2] };
|
|
542
|
+
}
|
|
543
|
+
return null;
|
|
544
|
+
}
|
|
545
|
+
function containsIdentifier(name, target) {
|
|
546
|
+
return name.toLowerCase().includes(target.toLowerCase());
|
|
547
|
+
}
|
|
548
|
+
function isCustomContextualType(typeName, serviceName, localTypes) {
|
|
549
|
+
if (PRIMITIVE_AND_BUILTIN_TYPES.has(typeName)) return false;
|
|
550
|
+
if (localTypes.has(typeName)) return true;
|
|
551
|
+
if (containsIdentifier(typeName, serviceName)) return true;
|
|
552
|
+
if (/^[A-Z][a-zA-Z0-9]+$/.test(typeName)) return true;
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
function hasContextualTypeReference(node, serviceName, localTypes) {
|
|
556
|
+
const typeRefs = node.getDescendantsOfKind(SyntaxKind4.TypeReference);
|
|
557
|
+
for (const ref of typeRefs) {
|
|
558
|
+
const text = ref.getTypeName().getText().trim();
|
|
559
|
+
if (isCustomContextualType(text, serviceName, localTypes)) {
|
|
560
|
+
return true;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return false;
|
|
564
|
+
}
|
|
565
|
+
function checkScopedLibraryRules(sf) {
|
|
566
|
+
const errors = [];
|
|
567
|
+
const warnings = [];
|
|
568
|
+
const promotableAssets = [];
|
|
569
|
+
const filePath = sf.getFilePath().replace(/\\/g, "/");
|
|
570
|
+
const context = detectServiceContext(filePath);
|
|
571
|
+
if (!context) {
|
|
572
|
+
return { errors, warnings, promotableAssets };
|
|
573
|
+
}
|
|
574
|
+
const { serviceName, libraryName } = context;
|
|
575
|
+
const localTypes = /* @__PURE__ */ new Set();
|
|
576
|
+
sf.getInterfaces().forEach((i) => localTypes.add(i.getName()));
|
|
577
|
+
sf.getTypeAliases().forEach((t) => localTypes.add(t.getName()));
|
|
578
|
+
sf.getClasses().forEach((c) => {
|
|
579
|
+
const n = c.getName();
|
|
580
|
+
if (n) localTypes.add(n);
|
|
581
|
+
});
|
|
582
|
+
sf.getEnums().forEach((e) => localTypes.add(e.getName()));
|
|
583
|
+
const functions = sf.getFunctions();
|
|
584
|
+
for (const fn of functions) {
|
|
585
|
+
const fnName = fn.getName();
|
|
586
|
+
if (!fnName) continue;
|
|
587
|
+
const isContextual = hasContextualTypeReference(fn, serviceName, localTypes);
|
|
588
|
+
const hasServiceName = containsIdentifier(fnName, serviceName);
|
|
589
|
+
if (isContextual) {
|
|
590
|
+
if (!hasServiceName) {
|
|
591
|
+
errors.push({
|
|
592
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
593
|
+
filePath,
|
|
594
|
+
line: fn.getStartLineNumber(),
|
|
595
|
+
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.`,
|
|
596
|
+
severity: "error"
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
} else {
|
|
600
|
+
promotableAssets.push({
|
|
601
|
+
name: fnName,
|
|
602
|
+
kind: "function",
|
|
603
|
+
filePath,
|
|
604
|
+
scope: "service",
|
|
605
|
+
scopeName: serviceName,
|
|
606
|
+
target: "GutTS"
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
for (const stmt of sf.getVariableStatements()) {
|
|
611
|
+
for (const decl of stmt.getDeclarations()) {
|
|
612
|
+
const varName = decl.getName();
|
|
613
|
+
const init = decl.getInitializer();
|
|
614
|
+
const isFunction = init && (init.getKind() === SyntaxKind4.ArrowFunction || init.getKind() === SyntaxKind4.FunctionExpression);
|
|
615
|
+
if (isFunction) {
|
|
616
|
+
const isContextual = hasContextualTypeReference(decl, serviceName, localTypes);
|
|
617
|
+
const hasServiceName = containsIdentifier(varName, serviceName);
|
|
618
|
+
if (isContextual) {
|
|
619
|
+
if (!hasServiceName) {
|
|
620
|
+
errors.push({
|
|
621
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
622
|
+
filePath,
|
|
623
|
+
line: decl.getStartLineNumber(),
|
|
624
|
+
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.`,
|
|
625
|
+
severity: "error"
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
} else {
|
|
629
|
+
promotableAssets.push({
|
|
630
|
+
name: varName,
|
|
631
|
+
kind: "function",
|
|
632
|
+
filePath,
|
|
633
|
+
scope: "service",
|
|
634
|
+
scopeName: serviceName,
|
|
635
|
+
target: "GutTS"
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
} else {
|
|
639
|
+
const isContextual = hasContextualTypeReference(decl, serviceName, localTypes);
|
|
640
|
+
const hasServiceName = containsIdentifier(varName, serviceName);
|
|
641
|
+
if (isContextual && !hasServiceName) {
|
|
642
|
+
errors.push({
|
|
643
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
644
|
+
filePath,
|
|
645
|
+
line: decl.getStartLineNumber(),
|
|
646
|
+
message: `Service library asset '${varName}' in service '${serviceName}' violates scoped library naming convention. Custom library asset identifiers must contain the owning service name ('${serviceName}').`,
|
|
647
|
+
severity: "error"
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
for (const iface of sf.getInterfaces()) {
|
|
654
|
+
const name = iface.getName();
|
|
655
|
+
const hasServiceName = containsIdentifier(name, serviceName);
|
|
656
|
+
const hasProps = iface.getProperties().length > 0;
|
|
657
|
+
if (hasProps && !hasServiceName) {
|
|
658
|
+
errors.push({
|
|
659
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
660
|
+
filePath,
|
|
661
|
+
line: iface.getStartLineNumber(),
|
|
662
|
+
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}'.`,
|
|
663
|
+
severity: "error"
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
for (const t of sf.getTypeAliases()) {
|
|
668
|
+
const name = t.getName();
|
|
669
|
+
const hasServiceName = containsIdentifier(name, serviceName);
|
|
670
|
+
const isContextual = hasContextualTypeReference(t, serviceName, localTypes);
|
|
671
|
+
if (isContextual && !hasServiceName) {
|
|
672
|
+
errors.push({
|
|
673
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
674
|
+
filePath,
|
|
675
|
+
line: t.getStartLineNumber(),
|
|
676
|
+
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}'.`,
|
|
677
|
+
severity: "error"
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
for (const cls of sf.getClasses()) {
|
|
682
|
+
const name = cls.getName();
|
|
683
|
+
if (!name) continue;
|
|
684
|
+
const hasServiceName = containsIdentifier(name, serviceName);
|
|
685
|
+
if (!hasServiceName) {
|
|
686
|
+
errors.push({
|
|
687
|
+
ruleId: "krnl/service-library-asset-naming",
|
|
688
|
+
filePath,
|
|
689
|
+
line: cls.getStartLineNumber(),
|
|
690
|
+
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}'.`,
|
|
691
|
+
severity: "error"
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return { errors, warnings, promotableAssets };
|
|
696
|
+
}
|
|
697
|
+
|
|
427
698
|
// src/KrnlValidatorEngine.ts
|
|
428
699
|
var KrnlValidatorEngine = class {
|
|
429
700
|
project;
|
|
@@ -431,13 +702,13 @@ var KrnlValidatorEngine = class {
|
|
|
431
702
|
limitOptions;
|
|
432
703
|
constructor(optionsOrRoot) {
|
|
433
704
|
const options = typeof optionsOrRoot === "string" ? { projectRoot: optionsOrRoot } : optionsOrRoot;
|
|
434
|
-
this.projectRoot =
|
|
705
|
+
this.projectRoot = path3.resolve(options.projectRoot || process.cwd());
|
|
435
706
|
this.limitOptions = {
|
|
436
707
|
maxFileLineLimit: options.maxFileLineLimit ?? 200,
|
|
437
708
|
maxMainLogicLimit: options.maxMainLogicLimit ?? 20,
|
|
438
709
|
maxHelperLineLimit: options.maxHelperLineLimit ?? 30
|
|
439
710
|
};
|
|
440
|
-
const tsConfigPath =
|
|
711
|
+
const tsConfigPath = path3.join(this.projectRoot, "tsconfig.json");
|
|
441
712
|
if (fs2.existsSync(tsConfigPath)) {
|
|
442
713
|
this.project = new Project({ tsConfigFilePath: tsConfigPath, skipAddingFilesFromTsConfig: true });
|
|
443
714
|
} else {
|
|
@@ -451,33 +722,55 @@ var KrnlValidatorEngine = class {
|
|
|
451
722
|
const files = this.collectSourceFiles(this.projectRoot);
|
|
452
723
|
const errors = [];
|
|
453
724
|
const warnings = [];
|
|
725
|
+
const promotableAssets = [];
|
|
454
726
|
checkWorkspaceLayout(this.projectRoot, errors);
|
|
455
727
|
for (const f of files) {
|
|
456
728
|
const sf = this.project.addSourceFileAtPath(f);
|
|
457
729
|
const fileReport = this.validateSourceFile(sf);
|
|
458
730
|
errors.push(...fileReport.errors);
|
|
459
731
|
warnings.push(...fileReport.warnings);
|
|
732
|
+
if (fileReport.promotableAssets) {
|
|
733
|
+
promotableAssets.push(...fileReport.promotableAssets);
|
|
734
|
+
}
|
|
460
735
|
}
|
|
461
736
|
return {
|
|
462
737
|
valid: errors.length === 0,
|
|
463
738
|
totalFiles: files.length,
|
|
464
739
|
errors,
|
|
465
|
-
warnings
|
|
740
|
+
warnings,
|
|
741
|
+
promotableAssets
|
|
466
742
|
};
|
|
467
743
|
}
|
|
468
744
|
validateSourceFile(sf) {
|
|
469
745
|
const filePath = sf.getFilePath();
|
|
470
|
-
const baseName =
|
|
746
|
+
const baseName = path3.basename(filePath);
|
|
471
747
|
if (baseName.includes("_pb.") || baseName.endsWith(".d.ts")) {
|
|
472
|
-
return { errors: [], warnings: [] };
|
|
748
|
+
return { errors: [], warnings: [], promotableAssets: [] };
|
|
473
749
|
}
|
|
474
750
|
const limits = checkFileLimits(sf, this.limitOptions);
|
|
475
751
|
const purity = checkTopLevelPurity(sf);
|
|
476
752
|
const components = checkComponentRules(sf);
|
|
477
|
-
const
|
|
753
|
+
const orchestration = checkOrchestrationRules(sf);
|
|
754
|
+
const boundaries = checkServiceBoundaries(sf);
|
|
755
|
+
const scopedLibraries = checkScopedLibraryRules(sf);
|
|
478
756
|
return {
|
|
479
|
-
errors: [
|
|
480
|
-
|
|
757
|
+
errors: [
|
|
758
|
+
...limits.errors,
|
|
759
|
+
...purity.errors,
|
|
760
|
+
...components.errors,
|
|
761
|
+
...orchestration.errors,
|
|
762
|
+
...boundaries.errors,
|
|
763
|
+
...scopedLibraries.errors
|
|
764
|
+
],
|
|
765
|
+
warnings: [
|
|
766
|
+
...limits.warnings,
|
|
767
|
+
...purity.warnings,
|
|
768
|
+
...components.warnings,
|
|
769
|
+
...orchestration.warnings,
|
|
770
|
+
...boundaries.warnings,
|
|
771
|
+
...scopedLibraries.warnings
|
|
772
|
+
],
|
|
773
|
+
promotableAssets: scopedLibraries.promotableAssets
|
|
481
774
|
};
|
|
482
775
|
}
|
|
483
776
|
collectSourceFiles(dir, collected = []) {
|
|
@@ -485,7 +778,7 @@ var KrnlValidatorEngine = class {
|
|
|
485
778
|
const entries = fs2.readdirSync(dir, { withFileTypes: true });
|
|
486
779
|
for (const entry of entries) {
|
|
487
780
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git") continue;
|
|
488
|
-
const full =
|
|
781
|
+
const full = path3.join(dir, entry.name);
|
|
489
782
|
if (entry.isDirectory()) {
|
|
490
783
|
this.collectSourceFiles(full, collected);
|
|
491
784
|
} else if (entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".js") || entry.name.endsWith(".tsx") || entry.name.endsWith(".jsx"))) {
|