pumuki 6.3.152 → 6.3.154
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/core/facts/detectors/text/ios.test.ts +14 -4
- package/core/facts/detectors/text/ios.ts +26 -3
- package/core/rules/presets/heuristics/android.test.ts +32 -2
- package/core/rules/presets/heuristics/android.ts +110 -0
- package/integrations/lifecycle/preWriteAutomation.ts +1 -1
- package/package.json +1 -1
- package/skills.lock.json +15 -26
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
hasSwiftDispatchGroupUsage,
|
|
14
14
|
hasSwiftDispatchQueueUsage,
|
|
15
15
|
hasSwiftDispatchSemaphoreUsage,
|
|
16
|
+
hasSwiftExplicitColorStaticMemberUsage,
|
|
16
17
|
hasSwiftForEachIndicesUsage,
|
|
17
18
|
hasSwiftForceCastUsage,
|
|
18
19
|
hasSwiftFontWeightBoldUsage,
|
|
@@ -20,6 +21,7 @@ import {
|
|
|
20
21
|
hasSwiftForceTryUsage,
|
|
21
22
|
hasSwiftForceUnwrap,
|
|
22
23
|
hasSwiftGeometryReaderUsage,
|
|
24
|
+
hasSwiftInlineFilteringInForEachUsage,
|
|
23
25
|
hasSwiftLegacyOnChangeUsage,
|
|
24
26
|
hasSwiftLegacyExpectationDescriptionUsage,
|
|
25
27
|
hasSwiftLegacySwiftUiObservableWrapperUsage,
|
|
@@ -243,7 +245,9 @@ MainActor.assumeIsolated { reload() }
|
|
|
243
245
|
assert.equal(hasSwiftNonisolatedUnsafeUsage(source), true);
|
|
244
246
|
assert.equal(hasSwiftAssumeIsolatedUsage(source), true);
|
|
245
247
|
assert.equal(hasSwiftForEachIndicesUsage(source), true);
|
|
248
|
+
assert.equal(hasSwiftInlineFilteringInForEachUsage('ForEach(items.filter { $0.isActive }) { item in Text(item.title) }'), true);
|
|
246
249
|
assert.equal(hasSwiftContainsUserFilterUsage(source), true);
|
|
250
|
+
assert.equal(hasSwiftExplicitColorStaticMemberUsage('Text("A").foregroundStyle(Color.blue)'), true);
|
|
247
251
|
assert.equal(hasSwiftGeometryReaderUsage(source), true);
|
|
248
252
|
assert.equal(hasSwiftFontWeightBoldUsage(source), true);
|
|
249
253
|
assert.equal(hasSwiftObservableObjectUsage(source), true);
|
|
@@ -289,7 +293,9 @@ let t = "MainActor.assumeIsolated { reload() }"
|
|
|
289
293
|
assert.equal(hasSwiftNonisolatedUnsafeUsage(source), false);
|
|
290
294
|
assert.equal(hasSwiftAssumeIsolatedUsage(source), false);
|
|
291
295
|
assert.equal(hasSwiftForEachIndicesUsage(source), false);
|
|
296
|
+
assert.equal(hasSwiftInlineFilteringInForEachUsage(source), false);
|
|
292
297
|
assert.equal(hasSwiftContainsUserFilterUsage(source), false);
|
|
298
|
+
assert.equal(hasSwiftExplicitColorStaticMemberUsage('Text("A").foregroundStyle(.blue)'), false);
|
|
293
299
|
assert.equal(hasSwiftGeometryReaderUsage(source), false);
|
|
294
300
|
assert.equal(hasSwiftFontWeightBoldUsage(source), false);
|
|
295
301
|
assert.equal(hasSwiftTaskDetachedUsage(source), false);
|
|
@@ -400,7 +406,7 @@ final class LoginModelTests: XCTestCase {
|
|
|
400
406
|
}
|
|
401
407
|
`;
|
|
402
408
|
|
|
403
|
-
assert.equal(hasSwiftLegacyXCTestImportUsage(unitTest),
|
|
409
|
+
assert.equal(hasSwiftLegacyXCTestImportUsage(unitTest), false);
|
|
404
410
|
assert.equal(hasSwiftLegacyXCTestImportUsage(uiTest), false);
|
|
405
411
|
assert.equal(hasSwiftLegacyXCTestImportUsage(performanceTest), false);
|
|
406
412
|
assert.equal(hasSwiftLegacyXCTestImportUsage(brownfieldCompatibleUnitTest), false);
|
|
@@ -524,7 +530,7 @@ final class LoginModelTests: XCTestCase {
|
|
|
524
530
|
}
|
|
525
531
|
`;
|
|
526
532
|
|
|
527
|
-
assert.equal(hasSwiftModernizableXCTestSuiteUsage(legacySuite),
|
|
533
|
+
assert.equal(hasSwiftModernizableXCTestSuiteUsage(legacySuite), false);
|
|
528
534
|
assert.equal(hasSwiftModernizableXCTestSuiteUsage(mixedSuite), false);
|
|
529
535
|
assert.equal(hasSwiftModernizableXCTestSuiteUsage(uiSuite), false);
|
|
530
536
|
assert.equal(hasSwiftModernizableXCTestSuiteUsage(brownfieldCompatibleSuite), false);
|
|
@@ -596,7 +602,7 @@ final class BuyerCommerceUISmokeTests: XCTestCase {
|
|
|
596
602
|
assert.equal(hasSwiftXCTUnwrapUsage(`${uiSource}\nlet value = try XCTUnwrap(optional)`), false);
|
|
597
603
|
});
|
|
598
604
|
|
|
599
|
-
test('
|
|
605
|
+
test('detectores Swift Testing excluyen XCTest brownfield y dejan la calidad a su guard dedicado', () => {
|
|
600
606
|
const compatibleSource = `
|
|
601
607
|
import XCTest
|
|
602
608
|
|
|
@@ -633,7 +639,11 @@ final class LoginModelTests: XCTestCase {
|
|
|
633
639
|
|
|
634
640
|
assert.equal(hasSwiftXCTestAssertionUsage(compatibleSource), false);
|
|
635
641
|
assert.equal(hasSwiftXCTUnwrapUsage(compatibleSource), false);
|
|
636
|
-
assert.equal(
|
|
642
|
+
assert.equal(hasSwiftLegacyXCTestImportUsage(compatibleSource), false);
|
|
643
|
+
assert.equal(hasSwiftModernizableXCTestSuiteUsage(compatibleSource), false);
|
|
644
|
+
assert.equal(hasSwiftXCTestAssertionUsage(missingQualityContract), false);
|
|
645
|
+
assert.equal(hasSwiftLegacyXCTestImportUsage(missingQualityContract), false);
|
|
646
|
+
assert.equal(hasSwiftModernizableXCTestSuiteUsage(missingQualityContract), false);
|
|
637
647
|
});
|
|
638
648
|
|
|
639
649
|
test('hasSwiftXCTUnwrapUsage detecta XCTUnwrap real y evita strings', () => {
|
|
@@ -479,6 +479,17 @@ export const hasSwiftForEachIndicesUsage = (source: string): boolean => {
|
|
|
479
479
|
);
|
|
480
480
|
};
|
|
481
481
|
|
|
482
|
+
export const hasSwiftInlineFilteringInForEachUsage = (source: string): boolean => {
|
|
483
|
+
return hasSwiftSanitizedRegexMatch(
|
|
484
|
+
source,
|
|
485
|
+
/\bForEach\s*\(\s*[A-Za-z_][A-Za-z0-9_.]*\s*\.\s*filter\s*\{/g
|
|
486
|
+
);
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
export const hasSwiftExplicitColorStaticMemberUsage = (source: string): boolean => {
|
|
490
|
+
return hasSwiftSanitizedRegexMatch(source, /\bColor\s*\.\s*[a-z][A-Za-z0-9_]*\b/g);
|
|
491
|
+
};
|
|
492
|
+
|
|
482
493
|
const isUserSearchIdentifier = (value: string): boolean => {
|
|
483
494
|
return /^(?:query|search(?:Text|Term|Query|Value)?|filter(?:Text|Value)?|text|term|input)$/i.test(
|
|
484
495
|
value
|
|
@@ -756,6 +767,18 @@ const hasSwiftBrownfieldCompatibleXCTestUsage = (source: string): boolean => {
|
|
|
756
767
|
return hasSwiftMakeSutUsage(source) && hasSwiftMemoryLeakTrackingUsage(source);
|
|
757
768
|
};
|
|
758
769
|
|
|
770
|
+
const hasSwiftXCTestOnlyBrownfieldSuiteUsage = (source: string): boolean => {
|
|
771
|
+
if (!hasSwiftXCTestImportUsage(source) || !hasSwiftXCTestCaseSubclassUsage(source)) {
|
|
772
|
+
return false;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
if (hasSwiftLegacyXCTestUiOrPerformanceUsage(source)) {
|
|
776
|
+
return false;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
return !hasSwiftTestingImportUsage(source) && !hasSwiftTestingSuiteAttributeUsage(source);
|
|
780
|
+
};
|
|
781
|
+
|
|
759
782
|
export const hasSwiftLegacyXCTestImportUsage = (source: string): boolean => {
|
|
760
783
|
if (!hasSwiftXCTestImportUsage(source)) {
|
|
761
784
|
return false;
|
|
@@ -765,7 +788,7 @@ export const hasSwiftLegacyXCTestImportUsage = (source: string): boolean => {
|
|
|
765
788
|
return false;
|
|
766
789
|
}
|
|
767
790
|
|
|
768
|
-
if (
|
|
791
|
+
if (hasSwiftXCTestOnlyBrownfieldSuiteUsage(source)) {
|
|
769
792
|
return false;
|
|
770
793
|
}
|
|
771
794
|
|
|
@@ -801,7 +824,7 @@ export const hasSwiftXCTestAssertionUsage = (source: string): boolean => {
|
|
|
801
824
|
return false;
|
|
802
825
|
}
|
|
803
826
|
|
|
804
|
-
if (
|
|
827
|
+
if (hasSwiftXCTestOnlyBrownfieldSuiteUsage(source)) {
|
|
805
828
|
return false;
|
|
806
829
|
}
|
|
807
830
|
|
|
@@ -816,7 +839,7 @@ export const hasSwiftXCTUnwrapUsage = (source: string): boolean => {
|
|
|
816
839
|
return false;
|
|
817
840
|
}
|
|
818
841
|
|
|
819
|
-
if (
|
|
842
|
+
if (hasSwiftXCTestOnlyBrownfieldSuiteUsage(source)) {
|
|
820
843
|
return false;
|
|
821
844
|
}
|
|
822
845
|
|
|
@@ -3,7 +3,7 @@ import test from 'node:test';
|
|
|
3
3
|
import { androidRules } from './android';
|
|
4
4
|
|
|
5
5
|
test('androidRules define reglas heurísticas locked para plataforma android', () => {
|
|
6
|
-
assert.equal(androidRules.length,
|
|
6
|
+
assert.equal(androidRules.length, 82);
|
|
7
7
|
|
|
8
8
|
const ids = androidRules.map((rule) => rule.id);
|
|
9
9
|
assert.deepEqual(ids, [
|
|
@@ -39,9 +39,15 @@ test('androidRules define reglas heurísticas locked para plataforma android', (
|
|
|
39
39
|
'heuristics.android.single-source-of-truth-viewmodel-es-la-fuente.ast',
|
|
40
40
|
'heuristics.android.skip-recomposition-para-metros-inmutables-o-estables.ast',
|
|
41
41
|
'heuristics.android.stability-composables-estables-recomponen-menos.ast',
|
|
42
|
-
|
|
42
|
+
'heuristics.android.string-formatting-1-s-2-d-para-argumentos.ast',
|
|
43
43
|
'heuristics.android.binds-para-implementaciones-de-interfaces-ma-s-eficiente.ast',
|
|
44
44
|
'heuristics.android.provides-para-interfaces-o-third-party.ast',
|
|
45
|
+
'heuristics.android.hilt-di-framework-no-manual-factories.ast',
|
|
46
|
+
'heuristics.android.hiltandroidapp-application-class.ast',
|
|
47
|
+
'heuristics.android.androidentrypoint-activity-fragment-viewmodel.ast',
|
|
48
|
+
'heuristics.android.inject-constructor-constructor-injection.ast',
|
|
49
|
+
'heuristics.android.module-installin-provide-dependencies.ast',
|
|
50
|
+
'heuristics.android.viewmodelscoped-para-dependencias-de-viewmodel.ast',
|
|
45
51
|
'heuristics.android.workmanager-androidx-work-work-runtime-ktx.ast',
|
|
46
52
|
'heuristics.android.version-catalogs-libs-versions-toml-para-dependencias.ast',
|
|
47
53
|
'heuristics.android.workmanager-background-tasks.ast',
|
|
@@ -179,6 +185,30 @@ test('androidRules define reglas heurísticas locked para plataforma android', (
|
|
|
179
185
|
byId.get('heuristics.android.provides-para-interfaces-o-third-party.ast')?.then.code,
|
|
180
186
|
'HEURISTICS_ANDROID_PROVIDES_PARA_INTERFACES_O_THIRD_PARTY_AST'
|
|
181
187
|
);
|
|
188
|
+
assert.equal(
|
|
189
|
+
byId.get('heuristics.android.hilt-di-framework-no-manual-factories.ast')?.then.code,
|
|
190
|
+
'HEURISTICS_ANDROID_HILT_DI_FRAMEWORK_NO_MANUAL_FACTORIES_AST'
|
|
191
|
+
);
|
|
192
|
+
assert.equal(
|
|
193
|
+
byId.get('heuristics.android.hiltandroidapp-application-class.ast')?.then.code,
|
|
194
|
+
'HEURISTICS_ANDROID_HILTANDROIDAPP_APPLICATION_CLASS_AST'
|
|
195
|
+
);
|
|
196
|
+
assert.equal(
|
|
197
|
+
byId.get('heuristics.android.androidentrypoint-activity-fragment-viewmodel.ast')?.then.code,
|
|
198
|
+
'HEURISTICS_ANDROID_ANDROIDENTRYPOINT_ACTIVITY_FRAGMENT_VIEWMODEL_AST'
|
|
199
|
+
);
|
|
200
|
+
assert.equal(
|
|
201
|
+
byId.get('heuristics.android.inject-constructor-constructor-injection.ast')?.then.code,
|
|
202
|
+
'HEURISTICS_ANDROID_INJECT_CONSTRUCTOR_CONSTRUCTOR_INJECTION_AST'
|
|
203
|
+
);
|
|
204
|
+
assert.equal(
|
|
205
|
+
byId.get('heuristics.android.module-installin-provide-dependencies.ast')?.then.code,
|
|
206
|
+
'HEURISTICS_ANDROID_MODULE_INSTALLIN_PROVIDE_DEPENDENCIES_AST'
|
|
207
|
+
);
|
|
208
|
+
assert.equal(
|
|
209
|
+
byId.get('heuristics.android.viewmodelscoped-para-dependencias-de-viewmodel.ast')?.then.code,
|
|
210
|
+
'HEURISTICS_ANDROID_VIEWMODELSCOPED_PARA_DEPENDENCIAS_DE_VIEWMODEL_AST'
|
|
211
|
+
);
|
|
182
212
|
assert.equal(
|
|
183
213
|
byId.get('heuristics.android.workmanager-androidx-work-work-runtime-ktx.ast')?.then.code,
|
|
184
214
|
'HEURISTICS_ANDROID_WORKMANAGER_ANDROIDX_WORK_WORK_RUNTIME_KTX_AST'
|
|
@@ -663,6 +663,116 @@ export const androidRules: RuleSet = [
|
|
|
663
663
|
code: 'HEURISTICS_ANDROID_PROVIDES_PARA_INTERFACES_O_THIRD_PARTY_AST',
|
|
664
664
|
},
|
|
665
665
|
},
|
|
666
|
+
{
|
|
667
|
+
id: 'heuristics.android.hilt-di-framework-no-manual-factories.ast',
|
|
668
|
+
description: 'Detects Hilt DI framework usage in Android production Kotlin files.',
|
|
669
|
+
severity: 'WARN',
|
|
670
|
+
platform: 'android',
|
|
671
|
+
locked: true,
|
|
672
|
+
when: {
|
|
673
|
+
kind: 'Heuristic',
|
|
674
|
+
where: {
|
|
675
|
+
ruleId: 'heuristics.android.hilt-di-framework-no-manual-factories.ast',
|
|
676
|
+
},
|
|
677
|
+
},
|
|
678
|
+
then: {
|
|
679
|
+
kind: 'Finding',
|
|
680
|
+
message:
|
|
681
|
+
'AST heuristic detected Hilt DI framework usage instead of manual factories in Android production code.',
|
|
682
|
+
code: 'HEURISTICS_ANDROID_HILT_DI_FRAMEWORK_NO_MANUAL_FACTORIES_AST',
|
|
683
|
+
},
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
id: 'heuristics.android.hiltandroidapp-application-class.ast',
|
|
687
|
+
description: 'Detects @HiltAndroidApp usage in Android production Kotlin files.',
|
|
688
|
+
severity: 'WARN',
|
|
689
|
+
platform: 'android',
|
|
690
|
+
locked: true,
|
|
691
|
+
when: {
|
|
692
|
+
kind: 'Heuristic',
|
|
693
|
+
where: {
|
|
694
|
+
ruleId: 'heuristics.android.hiltandroidapp-application-class.ast',
|
|
695
|
+
},
|
|
696
|
+
},
|
|
697
|
+
then: {
|
|
698
|
+
kind: 'Finding',
|
|
699
|
+
message: 'AST heuristic detected @HiltAndroidApp usage in Android production code.',
|
|
700
|
+
code: 'HEURISTICS_ANDROID_HILTANDROIDAPP_APPLICATION_CLASS_AST',
|
|
701
|
+
},
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
id: 'heuristics.android.androidentrypoint-activity-fragment-viewmodel.ast',
|
|
705
|
+
description: 'Detects @AndroidEntryPoint usage in Android production Kotlin files.',
|
|
706
|
+
severity: 'WARN',
|
|
707
|
+
platform: 'android',
|
|
708
|
+
locked: true,
|
|
709
|
+
when: {
|
|
710
|
+
kind: 'Heuristic',
|
|
711
|
+
where: {
|
|
712
|
+
ruleId: 'heuristics.android.androidentrypoint-activity-fragment-viewmodel.ast',
|
|
713
|
+
},
|
|
714
|
+
},
|
|
715
|
+
then: {
|
|
716
|
+
kind: 'Finding',
|
|
717
|
+
message:
|
|
718
|
+
'AST heuristic detected @AndroidEntryPoint usage in Android production code where Activity, Fragment, and ViewModel injection boundaries should remain explicit.',
|
|
719
|
+
code: 'HEURISTICS_ANDROID_ANDROIDENTRYPOINT_ACTIVITY_FRAGMENT_VIEWMODEL_AST',
|
|
720
|
+
},
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
id: 'heuristics.android.inject-constructor-constructor-injection.ast',
|
|
724
|
+
description: 'Detects @Inject constructor usage in Android production Kotlin files.',
|
|
725
|
+
severity: 'WARN',
|
|
726
|
+
platform: 'android',
|
|
727
|
+
locked: true,
|
|
728
|
+
when: {
|
|
729
|
+
kind: 'Heuristic',
|
|
730
|
+
where: {
|
|
731
|
+
ruleId: 'heuristics.android.inject-constructor-constructor-injection.ast',
|
|
732
|
+
},
|
|
733
|
+
},
|
|
734
|
+
then: {
|
|
735
|
+
kind: 'Finding',
|
|
736
|
+
message: 'AST heuristic detected @Inject constructor usage in Android production code.',
|
|
737
|
+
code: 'HEURISTICS_ANDROID_INJECT_CONSTRUCTOR_CONSTRUCTOR_INJECTION_AST',
|
|
738
|
+
},
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
id: 'heuristics.android.module-installin-provide-dependencies.ast',
|
|
742
|
+
description: 'Detects @Module + @InstallIn usage in Android production Kotlin files.',
|
|
743
|
+
severity: 'WARN',
|
|
744
|
+
platform: 'android',
|
|
745
|
+
locked: true,
|
|
746
|
+
when: {
|
|
747
|
+
kind: 'Heuristic',
|
|
748
|
+
where: {
|
|
749
|
+
ruleId: 'heuristics.android.module-installin-provide-dependencies.ast',
|
|
750
|
+
},
|
|
751
|
+
},
|
|
752
|
+
then: {
|
|
753
|
+
kind: 'Finding',
|
|
754
|
+
message: 'AST heuristic detected @Module + @InstallIn usage in Android production code.',
|
|
755
|
+
code: 'HEURISTICS_ANDROID_MODULE_INSTALLIN_PROVIDE_DEPENDENCIES_AST',
|
|
756
|
+
},
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
id: 'heuristics.android.viewmodelscoped-para-dependencias-de-viewmodel.ast',
|
|
760
|
+
description: 'Detects @ViewModelScoped usage in Android production Kotlin files.',
|
|
761
|
+
severity: 'WARN',
|
|
762
|
+
platform: 'android',
|
|
763
|
+
locked: true,
|
|
764
|
+
when: {
|
|
765
|
+
kind: 'Heuristic',
|
|
766
|
+
where: {
|
|
767
|
+
ruleId: 'heuristics.android.viewmodelscoped-para-dependencias-de-viewmodel.ast',
|
|
768
|
+
},
|
|
769
|
+
},
|
|
770
|
+
then: {
|
|
771
|
+
kind: 'Finding',
|
|
772
|
+
message: 'AST heuristic detected @ViewModelScoped usage in Android production code.',
|
|
773
|
+
code: 'HEURISTICS_ANDROID_VIEWMODELSCOPED_PARA_DEPENDENCIAS_DE_VIEWMODEL_AST',
|
|
774
|
+
},
|
|
775
|
+
},
|
|
666
776
|
{
|
|
667
777
|
id: 'heuristics.android.workmanager-androidx-work-work-runtime-ktx.ast',
|
|
668
778
|
description: 'Detects WorkManager dependency usage in Android build files.',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.154",
|
|
4
4
|
"description": "Enterprise-grade AST Intelligence System with multi-platform support (iOS, Android, Backend, Frontend) and Feature-First + DDD + Clean Architecture enforcement. Includes dynamic violations API for intelligent querying.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
package/skills.lock.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.0",
|
|
3
3
|
"compilerVersion": "1.0.0",
|
|
4
|
-
"generatedAt": "2026-05-
|
|
4
|
+
"generatedAt": "2026-05-05T20:36:04.017Z",
|
|
5
5
|
"bundles": [
|
|
6
6
|
{
|
|
7
7
|
"name": "android-guidelines",
|
|
@@ -5298,7 +5298,7 @@
|
|
|
5298
5298
|
"name": "ios-guidelines",
|
|
5299
5299
|
"version": "1.0.0",
|
|
5300
5300
|
"source": "file:vendor/skills/ios-enterprise-rules/SKILL.md",
|
|
5301
|
-
"hash": "
|
|
5301
|
+
"hash": "3c15fbec440154ff12f4ca998166a3faed9d943831bf34e8c80969bbcd0f94e5",
|
|
5302
5302
|
"rules": [
|
|
5303
5303
|
{
|
|
5304
5304
|
"id": "skills.ios.guideline.ios.accessibility-identifiers-para-localizar-elementos",
|
|
@@ -5384,18 +5384,6 @@
|
|
|
5384
5384
|
"evaluationMode": "DECLARATIVE",
|
|
5385
5385
|
"origin": "core"
|
|
5386
5386
|
},
|
|
5387
|
-
{
|
|
5388
|
-
"id": "skills.ios.guideline.ios.apiendpoint-como-struct-data-driven-ocp-endpoints-en-features-no-enum-",
|
|
5389
|
-
"description": "APIEndpoint como struct data-driven - OCP: endpoints en features, no enum central",
|
|
5390
|
-
"severity": "WARN",
|
|
5391
|
-
"platform": "ios",
|
|
5392
|
-
"sourceSkill": "ios-guidelines",
|
|
5393
|
-
"sourcePath": "vendor/skills/ios-enterprise-rules/SKILL.md",
|
|
5394
|
-
"confidence": "MEDIUM",
|
|
5395
|
-
"locked": true,
|
|
5396
|
-
"evaluationMode": "DECLARATIVE",
|
|
5397
|
-
"origin": "core"
|
|
5398
|
-
},
|
|
5399
5387
|
{
|
|
5400
5388
|
"id": "skills.ios.guideline.ios.app-transport-security-ats-https-por-defecto",
|
|
5401
5389
|
"description": "App Transport Security (ATS) - HTTPS por defecto",
|
|
@@ -7761,18 +7749,6 @@
|
|
|
7761
7749
|
"evaluationMode": "DECLARATIVE",
|
|
7762
7750
|
"origin": "core"
|
|
7763
7751
|
},
|
|
7764
|
-
{
|
|
7765
|
-
"id": "skills.ios.guideline.ios.verificar-que-no-viole-solid-srp-ocp-lsp-isp-dip",
|
|
7766
|
-
"description": "Verificar que NO viole SOLID (SRP, OCP, LSP, ISP, DIP)",
|
|
7767
|
-
"severity": "WARN",
|
|
7768
|
-
"platform": "ios",
|
|
7769
|
-
"sourceSkill": "ios-guidelines",
|
|
7770
|
-
"sourcePath": "vendor/skills/ios-enterprise-rules/SKILL.md",
|
|
7771
|
-
"confidence": "MEDIUM",
|
|
7772
|
-
"locked": true,
|
|
7773
|
-
"evaluationMode": "DECLARATIVE",
|
|
7774
|
-
"origin": "core"
|
|
7775
|
-
},
|
|
7776
7752
|
{
|
|
7777
7753
|
"id": "skills.ios.guideline.ios.viewmodels-por-pantalla-orderslistviewmodel-orderdetailviewmodel",
|
|
7778
7754
|
"description": "ViewModels por pantalla - OrdersListViewModel, OrderDetailViewModel",
|
|
@@ -8098,6 +8074,19 @@
|
|
|
8098
8074
|
"evaluationMode": "AUTO",
|
|
8099
8075
|
"origin": "core"
|
|
8100
8076
|
},
|
|
8077
|
+
{
|
|
8078
|
+
"id": "skills.ios.no-solid-violations",
|
|
8079
|
+
"description": "Verificar que NO viole SOLID (SRP, OCP, LSP, ISP, DIP)",
|
|
8080
|
+
"severity": "WARN",
|
|
8081
|
+
"platform": "ios",
|
|
8082
|
+
"sourceSkill": "ios-guidelines",
|
|
8083
|
+
"sourcePath": "vendor/skills/ios-enterprise-rules/SKILL.md",
|
|
8084
|
+
"stage": "PRE_WRITE",
|
|
8085
|
+
"confidence": "MEDIUM",
|
|
8086
|
+
"locked": true,
|
|
8087
|
+
"evaluationMode": "AUTO",
|
|
8088
|
+
"origin": "core"
|
|
8089
|
+
},
|
|
8101
8090
|
{
|
|
8102
8091
|
"id": "skills.ios.no-string-format",
|
|
8103
8092
|
"description": "String(localized:) + Text format en lugar de String(format:)",
|