pumuki 6.3.307 → 6.3.309

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.
@@ -218,6 +218,25 @@ export const iosRules: RuleSet = [
218
218
  code: 'HEURISTICS_IOS_TASK_DETACHED_AST',
219
219
  },
220
220
  },
221
+ {
222
+ id: 'heuristics.ios.concurrency.long-task-without-cancellation-check.ast',
223
+ description: 'Detects long-running async Swift loops without Task cancellation checks.',
224
+ severity: 'WARN',
225
+ platform: 'ios',
226
+ locked: true,
227
+ when: {
228
+ kind: 'Heuristic',
229
+ where: {
230
+ ruleId: 'heuristics.ios.concurrency.long-task-without-cancellation-check.ast',
231
+ },
232
+ },
233
+ then: {
234
+ kind: 'Finding',
235
+ message:
236
+ 'AST heuristic detected a long async operation without cooperative Task cancellation checks.',
237
+ code: 'HEURISTICS_IOS_CONCURRENCY_LONG_TASK_WITHOUT_CANCELLATION_CHECK_AST',
238
+ },
239
+ },
221
240
  {
222
241
  id: 'heuristics.ios.concurrency.async-without-await.ast',
223
242
  description: 'Detects private async functions that do not await in iOS production code.',
@@ -237,6 +256,24 @@ export const iosRules: RuleSet = [
237
256
  code: 'HEURISTICS_IOS_CONCURRENCY_ASYNC_WITHOUT_AWAIT_AST',
238
257
  },
239
258
  },
259
+ {
260
+ id: 'heuristics.ios.concurrency.dummy-await.ast',
261
+ description: 'Detects dummy awaits inserted to silence async_without_await instead of fixing the async boundary.',
262
+ severity: 'WARN',
263
+ platform: 'ios',
264
+ locked: true,
265
+ when: {
266
+ kind: 'Heuristic',
267
+ where: {
268
+ ruleId: 'heuristics.ios.concurrency.dummy-await.ast',
269
+ },
270
+ },
271
+ then: {
272
+ kind: 'Finding',
273
+ message: 'AST heuristic detected a dummy await used as a Swift concurrency lint workaround.',
274
+ code: 'HEURISTICS_IOS_CONCURRENCY_DUMMY_AWAIT_AST',
275
+ },
276
+ },
240
277
  {
241
278
  id: 'heuristics.ios.error.empty-catch.ast',
242
279
  description: 'Detects Swift catch blocks that silently swallow errors.',
@@ -273,6 +310,25 @@ export const iosRules: RuleSet = [
273
310
  code: 'HEURISTICS_IOS_ERROR_NSERROR_THROW_AST',
274
311
  },
275
312
  },
313
+ {
314
+ id: 'heuristics.ios.networking.endpoint-enum-ocp.ast',
315
+ description: 'Detects API endpoint catalogs modeled as Swift enums instead of data-driven endpoint values.',
316
+ severity: 'WARN',
317
+ platform: 'ios',
318
+ locked: true,
319
+ when: {
320
+ kind: 'Heuristic',
321
+ where: {
322
+ ruleId: 'heuristics.ios.networking.endpoint-enum-ocp.ast',
323
+ },
324
+ },
325
+ then: {
326
+ kind: 'Finding',
327
+ message:
328
+ 'AST heuristic detected API endpoint modeled as enum; use a data-driven APIEndpoint struct to preserve OCP.',
329
+ code: 'HEURISTICS_IOS_NETWORKING_ENDPOINT_ENUM_OCP_AST',
330
+ },
331
+ },
276
332
  {
277
333
  id: 'heuristics.ios.swiftui.onappear-task.ast',
278
334
  description: 'Detects Task launches from SwiftUI onAppear where .task can provide lifecycle cancellation.',
@@ -349,6 +405,61 @@ export const iosRules: RuleSet = [
349
405
  code: 'HEURISTICS_IOS_MEMORY_STRONG_DELEGATE_AST',
350
406
  },
351
407
  },
408
+ {
409
+ id: 'heuristics.ios.architecture.cross-feature-import.ast',
410
+ description: 'Detects Swift feature modules importing sibling feature modules directly.',
411
+ severity: 'WARN',
412
+ platform: 'ios',
413
+ locked: true,
414
+ when: {
415
+ kind: 'Heuristic',
416
+ where: {
417
+ ruleId: 'heuristics.ios.architecture.cross-feature-import.ast',
418
+ },
419
+ },
420
+ then: {
421
+ kind: 'Finding',
422
+ message: 'AST heuristic detected a Swift feature importing another feature module directly.',
423
+ code: 'HEURISTICS_IOS_ARCHITECTURE_CROSS_FEATURE_IMPORT_AST',
424
+ },
425
+ },
426
+ {
427
+ id: 'heuristics.ios.architecture.layer-direction-violation.ast',
428
+ description: 'Detects Swift imports that violate iOS Clean Architecture layer direction.',
429
+ severity: 'WARN',
430
+ platform: 'ios',
431
+ locked: true,
432
+ when: {
433
+ kind: 'Heuristic',
434
+ where: {
435
+ ruleId: 'heuristics.ios.architecture.layer-direction-violation.ast',
436
+ },
437
+ },
438
+ then: {
439
+ kind: 'Finding',
440
+ message:
441
+ 'AST heuristic detected an import that violates Clean Architecture layer direction in iOS code.',
442
+ code: 'HEURISTICS_IOS_ARCHITECTURE_LAYER_DIRECTION_VIOLATION_AST',
443
+ },
444
+ },
445
+ {
446
+ id: 'heuristics.ios.architecture.excessive-public-api.ast',
447
+ description: 'Detects excessive public/open API surface in iOS app implementation files.',
448
+ severity: 'WARN',
449
+ platform: 'ios',
450
+ locked: true,
451
+ when: {
452
+ kind: 'Heuristic',
453
+ where: {
454
+ ruleId: 'heuristics.ios.architecture.excessive-public-api.ast',
455
+ },
456
+ },
457
+ then: {
458
+ kind: 'Finding',
459
+ message: 'AST heuristic detected excessive public/open Swift API surface in iOS app code.',
460
+ code: 'HEURISTICS_IOS_ARCHITECTURE_EXCESSIVE_PUBLIC_API_AST',
461
+ },
462
+ },
352
463
  {
353
464
  id: 'heuristics.ios.memory.strong-self-escaping-closure.ast',
354
465
  description: 'Detects strong self captures in escaping iOS closures.',
@@ -817,6 +928,42 @@ export const iosRules: RuleSet = [
817
928
  code: 'HEURISTICS_IOS_DEPENDENCIES_SWIFT_TOOLS_VERSION_BELOW_6_2_AST',
818
929
  },
819
930
  },
931
+ {
932
+ id: 'heuristics.ios.concurrency.swiftpm-default-isolation-not-mainactor.ast',
933
+ description: 'Detects SwiftPM iOS manifests whose default isolation is not MainActor.',
934
+ severity: 'WARN',
935
+ platform: 'ios',
936
+ locked: true,
937
+ when: {
938
+ kind: 'Heuristic',
939
+ where: {
940
+ ruleId: 'heuristics.ios.concurrency.swiftpm-default-isolation-not-mainactor.ast',
941
+ },
942
+ },
943
+ then: {
944
+ kind: 'Finding',
945
+ message: 'AST heuristic detected Package.swift .defaultIsolation not set to MainActor.',
946
+ code: 'HEURISTICS_IOS_CONCURRENCY_SWIFTPM_DEFAULT_ISOLATION_NOT_MAINACTOR_AST',
947
+ },
948
+ },
949
+ {
950
+ id: 'heuristics.ios.concurrency.swiftpm-strict-concurrency-below-complete.ast',
951
+ description: 'Detects SwiftPM iOS manifests using targeted/minimal StrictConcurrency.',
952
+ severity: 'WARN',
953
+ platform: 'ios',
954
+ locked: true,
955
+ when: {
956
+ kind: 'Heuristic',
957
+ where: {
958
+ ruleId: 'heuristics.ios.concurrency.swiftpm-strict-concurrency-below-complete.ast',
959
+ },
960
+ },
961
+ then: {
962
+ kind: 'Finding',
963
+ message: 'AST heuristic detected Package.swift StrictConcurrency below complete.',
964
+ code: 'HEURISTICS_IOS_CONCURRENCY_SWIFTPM_STRICT_CONCURRENCY_BELOW_COMPLETE_AST',
965
+ },
966
+ },
820
967
  {
821
968
  id: 'heuristics.ios.concurrency.strict-concurrency-below-complete.ast',
822
969
  description: 'Detects Xcode iOS targets with strict concurrency checking below complete.',
@@ -835,6 +982,97 @@ export const iosRules: RuleSet = [
835
982
  code: 'HEURISTICS_IOS_CONCURRENCY_STRICT_CONCURRENCY_BELOW_COMPLETE_AST',
836
983
  },
837
984
  },
985
+ {
986
+ id: 'heuristics.ios.concurrency.default-actor-isolation-not-mainactor.ast',
987
+ description: 'Detects Xcode iOS targets whose default actor isolation is not MainActor.',
988
+ severity: 'WARN',
989
+ platform: 'ios',
990
+ locked: true,
991
+ when: {
992
+ kind: 'Heuristic',
993
+ where: {
994
+ ruleId: 'heuristics.ios.concurrency.default-actor-isolation-not-mainactor.ast',
995
+ },
996
+ },
997
+ then: {
998
+ kind: 'Finding',
999
+ message:
1000
+ 'AST heuristic detected SWIFT_DEFAULT_ACTOR_ISOLATION not set to MainActor in an iOS Xcode project.',
1001
+ code: 'HEURISTICS_IOS_CONCURRENCY_DEFAULT_ACTOR_ISOLATION_NOT_MAINACTOR_AST',
1002
+ },
1003
+ },
1004
+ {
1005
+ id: 'heuristics.ios.concurrency.upcoming-feature-disabled.ast',
1006
+ description: 'Detects Xcode iOS targets with required Swift upcoming features disabled.',
1007
+ severity: 'WARN',
1008
+ platform: 'ios',
1009
+ locked: true,
1010
+ when: {
1011
+ kind: 'Heuristic',
1012
+ where: {
1013
+ ruleId: 'heuristics.ios.concurrency.upcoming-feature-disabled.ast',
1014
+ },
1015
+ },
1016
+ then: {
1017
+ kind: 'Finding',
1018
+ message: 'AST heuristic detected disabled Swift upcoming feature settings in an iOS Xcode project.',
1019
+ code: 'HEURISTICS_IOS_CONCURRENCY_UPCOMING_FEATURE_DISABLED_AST',
1020
+ },
1021
+ },
1022
+ {
1023
+ id: 'heuristics.ios.concurrency.ui-state-without-mainactor.ast',
1024
+ description: 'Detects observable iOS UI state owners without @MainActor isolation.',
1025
+ severity: 'WARN',
1026
+ platform: 'ios',
1027
+ locked: true,
1028
+ when: {
1029
+ kind: 'Heuristic',
1030
+ where: {
1031
+ ruleId: 'heuristics.ios.concurrency.ui-state-without-mainactor.ast',
1032
+ },
1033
+ },
1034
+ then: {
1035
+ kind: 'Finding',
1036
+ message: 'AST heuristic detected observable iOS UI state without @MainActor isolation.',
1037
+ code: 'HEURISTICS_IOS_CONCURRENCY_UI_STATE_WITHOUT_MAINACTOR_AST',
1038
+ },
1039
+ },
1040
+ {
1041
+ id: 'heuristics.ios.concurrency.shared-mutable-state-without-actor.ast',
1042
+ description: 'Detects shared mutable iOS state owners without actor isolation.',
1043
+ severity: 'WARN',
1044
+ platform: 'ios',
1045
+ locked: true,
1046
+ when: {
1047
+ kind: 'Heuristic',
1048
+ where: {
1049
+ ruleId: 'heuristics.ios.concurrency.shared-mutable-state-without-actor.ast',
1050
+ },
1051
+ },
1052
+ then: {
1053
+ kind: 'Finding',
1054
+ message: 'AST heuristic detected shared mutable iOS state without actor isolation.',
1055
+ code: 'HEURISTICS_IOS_CONCURRENCY_SHARED_MUTABLE_STATE_WITHOUT_ACTOR_AST',
1056
+ },
1057
+ },
1058
+ {
1059
+ id: 'heuristics.ios.concurrency.mainactor-run-patch.ast',
1060
+ description: 'Detects MainActor.run used as an isolation patch inside non-isolated iOS state owners.',
1061
+ severity: 'WARN',
1062
+ platform: 'ios',
1063
+ locked: true,
1064
+ when: {
1065
+ kind: 'Heuristic',
1066
+ where: {
1067
+ ruleId: 'heuristics.ios.concurrency.mainactor-run-patch.ast',
1068
+ },
1069
+ },
1070
+ then: {
1071
+ kind: 'Finding',
1072
+ message: 'AST heuristic detected MainActor.run used as an isolation patch in iOS production code.',
1073
+ code: 'HEURISTICS_IOS_CONCURRENCY_MAINACTOR_RUN_PATCH_AST',
1074
+ },
1075
+ },
838
1076
  {
839
1077
  id: 'heuristics.ios.naming.non-pascal-case-type.ast',
840
1078
  description: 'Detects Swift type declarations that are not PascalCase.',
@@ -1034,6 +1272,24 @@ export const iosRules: RuleSet = [
1034
1272
  code: 'HEURISTICS_IOS_PERFORMANCE_BLOCKING_SLEEP_AST',
1035
1273
  },
1036
1274
  },
1275
+ {
1276
+ id: 'heuristics.ios.concurrency.thread-centric-debugging.ast',
1277
+ description: 'Detects Thread.current, Thread.isMainThread and pthread thread identity checks in iOS production code.',
1278
+ severity: 'WARN',
1279
+ platform: 'ios',
1280
+ locked: true,
1281
+ when: {
1282
+ kind: 'Heuristic',
1283
+ where: {
1284
+ ruleId: 'heuristics.ios.concurrency.thread-centric-debugging.ast',
1285
+ },
1286
+ },
1287
+ then: {
1288
+ kind: 'Finding',
1289
+ message: 'AST heuristic detected thread-centric debugging in Swift Concurrency code.',
1290
+ code: 'HEURISTICS_IOS_CONCURRENCY_THREAD_CENTRIC_DEBUGGING_AST',
1291
+ },
1292
+ },
1037
1293
  {
1038
1294
  id: 'heuristics.ios.accessibility.icon-only-control-label.ast',
1039
1295
  description: 'Detects icon-only SwiftUI controls without explicit accessibility labels.',
@@ -1736,6 +1992,24 @@ export const iosRules: RuleSet = [
1736
1992
  code: 'HEURISTICS_IOS_NAVIGATION_VIEW_AST',
1737
1993
  },
1738
1994
  },
1995
+ {
1996
+ id: 'heuristics.ios.navigation.path-without-restoration.ast',
1997
+ description: 'Detects SwiftUI NavigationPath state without an explicit restoration contract.',
1998
+ severity: 'WARN',
1999
+ platform: 'ios',
2000
+ locked: true,
2001
+ when: {
2002
+ kind: 'Heuristic',
2003
+ where: {
2004
+ ruleId: 'heuristics.ios.navigation.path-without-restoration.ast',
2005
+ },
2006
+ },
2007
+ then: {
2008
+ kind: 'Finding',
2009
+ message: 'AST heuristic detected NavigationPath without an explicit restoration contract.',
2010
+ code: 'HEURISTICS_IOS_NAVIGATION_PATH_WITHOUT_RESTORATION_AST',
2011
+ },
2012
+ },
1739
2013
  {
1740
2014
  id: 'heuristics.ios.swiftui.untyped-navigation-link-destination.ast',
1741
2015
  description: 'Detects untyped SwiftUI NavigationLink destination usage.',
@@ -1845,6 +2119,42 @@ export const iosRules: RuleSet = [
1845
2119
  code: 'HEURISTICS_IOS_ACCESSIBILITY_ON_TAP_WITHOUT_BUTTON_TRAIT_AST',
1846
2120
  },
1847
2121
  },
2122
+ {
2123
+ id: 'heuristics.ios.swiftui.glass-interactive-static-element.ast',
2124
+ description: 'Detects Liquid Glass interactive styling on static SwiftUI elements.',
2125
+ severity: 'WARN',
2126
+ platform: 'ios',
2127
+ locked: true,
2128
+ when: {
2129
+ kind: 'Heuristic',
2130
+ where: {
2131
+ ruleId: 'heuristics.ios.swiftui.glass-interactive-static-element.ast',
2132
+ },
2133
+ },
2134
+ then: {
2135
+ kind: 'Finding',
2136
+ message: 'AST heuristic detected Liquid Glass .interactive() on a static SwiftUI element.',
2137
+ code: 'HEURISTICS_IOS_SWIFTUI_GLASS_INTERACTIVE_STATIC_ELEMENT_AST',
2138
+ },
2139
+ },
2140
+ {
2141
+ id: 'heuristics.ios.swiftui.glasseffectid-without-namespace.ast',
2142
+ description: 'Detects SwiftUI glassEffectID usage without @Namespace or Namespace.ID ownership.',
2143
+ severity: 'WARN',
2144
+ platform: 'ios',
2145
+ locked: true,
2146
+ when: {
2147
+ kind: 'Heuristic',
2148
+ where: {
2149
+ ruleId: 'heuristics.ios.swiftui.glasseffectid-without-namespace.ast',
2150
+ },
2151
+ },
2152
+ then: {
2153
+ kind: 'Finding',
2154
+ message: 'AST heuristic detected glassEffectID without @Namespace or Namespace.ID.',
2155
+ code: 'HEURISTICS_IOS_SWIFTUI_GLASSEFFECTID_WITHOUT_NAMESPACE_AST',
2156
+ },
2157
+ },
1848
2158
  {
1849
2159
  id: 'heuristics.ios.string-format.ast',
1850
2160
  description: 'Detects String(format:) usage in iOS production code.',
@@ -2084,6 +2394,25 @@ export const iosRules: RuleSet = [
2084
2394
  code: 'HEURISTICS_IOS_TESTING_QUICK_NIMBLE_AST',
2085
2395
  },
2086
2396
  },
2397
+ {
2398
+ id: 'heuristics.ios.testing.third-party-ui-test-framework.ast',
2399
+ description: 'Detects third-party iOS UI test frameworks where native XCUITest is required.',
2400
+ severity: 'WARN',
2401
+ platform: 'ios',
2402
+ locked: true,
2403
+ when: {
2404
+ kind: 'Heuristic',
2405
+ where: {
2406
+ ruleId: 'heuristics.ios.testing.third-party-ui-test-framework.ast',
2407
+ },
2408
+ },
2409
+ then: {
2410
+ kind: 'Finding',
2411
+ message:
2412
+ 'AST heuristic detected third-party iOS UI test framework usage; use native XCUITest.',
2413
+ code: 'HEURISTICS_IOS_TESTING_THIRD_PARTY_UI_TEST_FRAMEWORK_AST',
2414
+ },
2415
+ },
2087
2416
  {
2088
2417
  id: 'heuristics.ios.core-data.nsmanagedobject-boundary.ast',
2089
2418
  description: 'Detects NSManagedObject usage in shared iOS boundaries.',
@@ -63,11 +63,19 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
63
63
  'skills.ios.guideline.ios.mainactor-para-co-digo-que-debe-ejecutarse-en-el-hilo-principal':
64
64
  heuristicDetector('ios.concurrency.mainactor-dispatchqueue', [
65
65
  'heuristics.ios.dispatchqueue.ast',
66
+ 'heuristics.ios.concurrency.ui-state-without-mainactor.ast',
66
67
  ]),
67
68
  'skills.ios.guideline.ios.actor-para-estado-compartido-thread-safe':
68
69
  heuristicDetector('ios.concurrency.shared-state-actor-boundary', [
69
70
  'heuristics.ios.dispatchqueue.ast',
70
71
  'heuristics.ios.dispatchsemaphore.ast',
72
+ 'heuristics.ios.concurrency.shared-mutable-state-without-actor.ast',
73
+ ]),
74
+ 'skills.ios.guideline.ios.sincronizacio-n-nativa-actors-para-estado-compartido-osallocatedunfair':
75
+ heuristicDetector('ios.concurrency.shared-state-actor-boundary', [
76
+ 'heuristics.ios.dispatchqueue.ast',
77
+ 'heuristics.ios.dispatchsemaphore.ast',
78
+ 'heuristics.ios.concurrency.shared-mutable-state-without-actor.ast',
71
79
  ]),
72
80
  'skills.ios.no-dispatchgroup': heuristicDetector('ios.dispatchgroup', [
73
81
  'heuristics.ios.dispatchgroup.ast',
@@ -81,6 +89,10 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
81
89
  'skills.ios.no-task-detached': heuristicDetector('ios.task-detached', [
82
90
  'heuristics.ios.task-detached.ast',
83
91
  ]),
92
+ 'skills.ios.guideline.ios.cancelar-correctamente-comprobar-task-iscancelled-en-operaciones-larga':
93
+ heuristicDetector('ios.concurrency.long-task-cancellation-check', [
94
+ 'heuristics.ios.concurrency.long-task-without-cancellation-check.ast',
95
+ ]),
84
96
  'skills.ios.no-async-without-await': heuristicDetector('ios.concurrency.async-without-await', [
85
97
  'heuristics.ios.concurrency.async-without-await.ast',
86
98
  ]),
@@ -88,6 +100,10 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
88
100
  heuristicDetector('ios.concurrency.avoid-overuse-async-without-await', [
89
101
  'heuristics.ios.concurrency.async-without-await.ast',
90
102
  ]),
103
+ 'skills.ios.guideline.ios-concurrency.use-references-linting-md-for-rule-intent-and-preferred-fixes-avoid-du':
104
+ heuristicDetector('ios.concurrency.dummy-await', [
105
+ 'heuristics.ios.concurrency.dummy-await.ast',
106
+ ]),
91
107
  'skills.ios.guideline.ios.delegation-pattern-weak-delegates-para-evitar-retain-cycles': heuristicDetector(
92
108
  'ios.memory.strong-delegate',
93
109
  ['heuristics.ios.memory.strong-delegate.ast']
@@ -212,6 +228,10 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
212
228
  'ios.error.typed-error-enum',
213
229
  ['heuristics.ios.error.nserror-throw.ast']
214
230
  ),
231
+ 'skills.ios.guideline.ios.apiendpoint-como-struct-data-driven-ocp-endpoints-en-features-no-enum-':
232
+ heuristicDetector('ios.networking.endpoint-enum-ocp', [
233
+ 'heuristics.ios.networking.endpoint-enum-ocp.ast',
234
+ ]),
215
235
  'skills.ios.guideline.ios.no-loggear-pii-tokens-emails-ids-sensibles': heuristicDetector(
216
236
  'ios.logging.sensitive-data',
217
237
  ['heuristics.ios.logging.sensitive-data.ast']
@@ -255,6 +275,7 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
255
275
  'heuristics.ios.dependencies.carthage.ast',
256
276
  'heuristics.ios.architecture.swinject.ast',
257
277
  'heuristics.ios.architecture.tca-composable-architecture.ast',
278
+ 'heuristics.ios.testing.third-party-ui-test-framework.ast',
258
279
  ]),
259
280
  'skills.ios.guideline.ios.libreri-as-de-terceros-usar-apis-nativas': heuristicDetector(
260
281
  'ios.dependencies.third-party-native-baseline',
@@ -264,6 +285,7 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
264
285
  'heuristics.ios.dependencies.carthage.ast',
265
286
  'heuristics.ios.architecture.swinject.ast',
266
287
  'heuristics.ios.architecture.tca-composable-architecture.ast',
288
+ 'heuristics.ios.testing.third-party-ui-test-framework.ast',
267
289
  ]
268
290
  ),
269
291
  'skills.ios.guideline.ios.keychain-passwords-tokens-no-userdefaults': heuristicDetector(
@@ -330,6 +352,10 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
330
352
  'ios.performance.blocking-sleep',
331
353
  ['heuristics.ios.performance.blocking-sleep.ast']
332
354
  ),
355
+ 'skills.ios.guideline.ios-concurrency.use-references-threading-md-to-avoid-thread-centric-debugging-and-rely':
356
+ heuristicDetector('ios.concurrency.thread-centric-debugging', [
357
+ 'heuristics.ios.concurrency.thread-centric-debugging.ast',
358
+ ]),
333
359
  'skills.ios.guideline.ios.structured-concurrency-task-taskgroup-actor-asyncsequence-asyncstream':
334
360
  heuristicDetector('ios.concurrency.structured-baseline', [
335
361
  'heuristics.ios.callback-style.ast',
@@ -375,6 +401,21 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
375
401
  'ios.accessibility.on-tap-without-button-trait',
376
402
  ['heuristics.ios.accessibility.on-tap-without-button-trait.ast']
377
403
  ),
404
+ 'skills.ios.guideline.ios.voiceover-labels-hints-traits': heuristicDetector(
405
+ 'ios.accessibility.voiceover-labels-traits',
406
+ [
407
+ 'heuristics.ios.accessibility.icon-only-control-label.ast',
408
+ 'heuristics.ios.accessibility.on-tap-without-button-trait.ast',
409
+ ]
410
+ ),
411
+ 'skills.ios.guideline.ios-swiftui-expert.use-interactive-only-for-tappable-focusable-elements':
412
+ heuristicDetector('ios.swiftui.glass-interactive-static-element', [
413
+ 'heuristics.ios.swiftui.glass-interactive-static-element.ast',
414
+ ]),
415
+ 'skills.ios.guideline.ios-swiftui-expert.use-glasseffectid-with-namespace-for-morphing-transitions':
416
+ heuristicDetector('ios.swiftui.glasseffectid-namespace', [
417
+ 'heuristics.ios.swiftui.glasseffectid-without-namespace.ast',
418
+ ]),
378
419
  'skills.ios.guideline.ios.image-optimization-resize-compress-cache': heuristicDetector(
379
420
  'ios.swiftui.image-data-decoding',
380
421
  ['heuristics.ios.swiftui.image-data-decoding.ast']
@@ -415,10 +456,32 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
415
456
  heuristicDetector('ios.dependencies.swift-tools-version', [
416
457
  'heuristics.ios.dependencies.swift-tools-version-below-6-2.ast',
417
458
  ]),
459
+ 'skills.ios.guideline.ios-concurrency.use-read-on-package-swift-for-swiftpm-settings-tools-version-strict-co':
460
+ heuristicDetector('ios.dependencies.swift-tools-version', [
461
+ 'heuristics.ios.dependencies.swift-tools-version-below-6-2.ast',
462
+ 'heuristics.ios.concurrency.swiftpm-default-isolation-not-mainactor.ast',
463
+ 'heuristics.ios.concurrency.swiftpm-strict-concurrency-below-complete.ast',
464
+ ]),
418
465
  'skills.ios.guideline.ios.strict-concurrency-checking-activar-en-complete':
419
466
  heuristicDetector('ios.concurrency.strict-concurrency-below-complete', [
420
467
  'heuristics.ios.concurrency.strict-concurrency-below-complete.ast',
421
468
  ]),
469
+ 'skills.ios.guideline.ios-concurrency.use-grep-for-swiftstrictconcurrency-or-swiftdefaultactorisolation-in-p':
470
+ heuristicDetector('ios.concurrency.project-settings', [
471
+ 'heuristics.ios.concurrency.strict-concurrency-below-complete.ast',
472
+ 'heuristics.ios.concurrency.default-actor-isolation-not-mainactor.ast',
473
+ 'heuristics.ios.concurrency.upcoming-feature-disabled.ast',
474
+ 'heuristics.ios.concurrency.swiftpm-default-isolation-not-mainactor.ast',
475
+ 'heuristics.ios.concurrency.swiftpm-strict-concurrency-below-complete.ast',
476
+ ]),
477
+ 'skills.ios.guideline.ios.validar-configuracio-n-de-concurrencia-swiftstrictconcurrency-swiftdef':
478
+ heuristicDetector('ios.concurrency.project-settings', [
479
+ 'heuristics.ios.concurrency.strict-concurrency-below-complete.ast',
480
+ 'heuristics.ios.concurrency.default-actor-isolation-not-mainactor.ast',
481
+ 'heuristics.ios.concurrency.upcoming-feature-disabled.ast',
482
+ 'heuristics.ios.concurrency.swiftpm-default-isolation-not-mainactor.ast',
483
+ 'heuristics.ios.concurrency.swiftpm-strict-concurrency-below-complete.ast',
484
+ ]),
422
485
  'skills.ios.guideline.ios.file-naming-pascalcase-para-tipos': heuristicDetector(
423
486
  'ios.naming.non-pascal-case-type',
424
487
  ['heuristics.ios.naming.non-pascal-case-type.ast']
@@ -461,7 +524,10 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
461
524
  'heuristics.ios.assume-isolated.ast',
462
525
  ]),
463
526
  'skills.ios.guideline.ios.no-usar-mainactor-como-parche-justificar-el-aislamiento':
464
- heuristicDetector('ios.assume-isolated', ['heuristics.ios.assume-isolated.ast']),
527
+ heuristicDetector('ios.assume-isolated', [
528
+ 'heuristics.ios.assume-isolated.ast',
529
+ 'heuristics.ios.concurrency.mainactor-run-patch.ast',
530
+ ]),
465
531
  'skills.ios.no-observable-object': heuristicDetector('ios.observable-object', [
466
532
  'heuristics.ios.observable-object.ast',
467
533
  ]),
@@ -549,6 +615,14 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
549
615
  'skills.ios.no-navigation-view': heuristicDetector('ios.navigation-view', [
550
616
  'heuristics.ios.navigation-view.ast',
551
617
  ]),
618
+ 'skills.ios.guideline.ios.deep-links-deben-mapear-a-rutas-del-path':
619
+ heuristicDetector('ios.navigation.path-restoration', [
620
+ 'heuristics.ios.navigation.path-without-restoration.ast',
621
+ ]),
622
+ 'skills.ios.guideline.ios.state-restoration-rehidratar-path-desde-estado-persistido-si-aplica':
623
+ heuristicDetector('ios.navigation.path-restoration', [
624
+ 'heuristics.ios.navigation.path-without-restoration.ast',
625
+ ]),
552
626
  'skills.ios.guideline.ios-swiftui-expert.use-modern-apis-no-deprecated-modifiers-or-patterns-see-references-mod':
553
627
  heuristicDetector('ios.swiftui.modern-api-replacements', [
554
628
  'heuristics.ios.navigation-view.ast',
@@ -646,6 +720,10 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
646
720
  heuristicDetector('ios.swiftui.large-viewbuilder-function', [
647
721
  'heuristics.ios.swiftui.large-viewbuilder-function.ast',
648
722
  ]),
723
+ 'skills.ios.guideline.ios.composicio-n-de-views-views-pequen-os-reutilizables':
724
+ heuristicDetector('ios.swiftui.large-viewbuilder-function', [
725
+ 'heuristics.ios.swiftui.large-viewbuilder-function.ast',
726
+ ]),
649
727
  'skills.ios.guideline.ios-swiftui-expert.pass-only-needed-values-to-views-avoid-large-config-or-context-objects':
650
728
  heuristicDetector('ios.swiftui.large-config-context-prop', [
651
729
  'heuristics.ios.swiftui.large-config-context-prop.ast',
@@ -775,6 +853,10 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
775
853
  'ios.testing.quick-nimble',
776
854
  ['heuristics.ios.testing.quick-nimble.ast']
777
855
  ),
856
+ 'skills.ios.guideline.ios.xcuitest-ui-testing-nativo': heuristicDetector(
857
+ 'ios.testing.third-party-ui-test-framework',
858
+ ['heuristics.ios.testing.third-party-ui-test-framework.ast']
859
+ ),
778
860
  'skills.ios.no-nsmanagedobject-boundary': heuristicDetector(
779
861
  'ios.core-data.nsmanagedobject-boundary',
780
862
  ['heuristics.ios.core-data.nsmanagedobject-boundary.ast']
@@ -1150,6 +1232,34 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
1150
1232
  'heuristics.ios.solid.lsp.narrowed-precondition.ast',
1151
1233
  ]
1152
1234
  ),
1235
+ 'skills.ios.guideline.ios.feature-first-cada-feature-es-un-bounded-context-no-se-acoplan-entre-s':
1236
+ heuristicDetector('ios.architecture.cross-feature-import', [
1237
+ 'heuristics.ios.architecture.cross-feature-import.ast',
1238
+ ]),
1239
+ 'skills.ios.guideline.ios.las-features-no-se-importan-entre-si':
1240
+ heuristicDetector('ios.architecture.cross-feature-import', [
1241
+ 'heuristics.ios.architecture.cross-feature-import.ast',
1242
+ ]),
1243
+ 'skills.ios.guideline.ios.shared-kernel-solo-tipos-mi-nimos-compartidos-entre-features':
1244
+ heuristicDetector('ios.architecture.cross-feature-import', [
1245
+ 'heuristics.ios.architecture.cross-feature-import.ast',
1246
+ ]),
1247
+ 'skills.ios.guideline.ios.clean-por-feature-presentation-application-domain-infrastructure-domai':
1248
+ heuristicDetector('ios.architecture.layer-direction', [
1249
+ 'heuristics.ios.architecture.layer-direction-violation.ast',
1250
+ ]),
1251
+ 'skills.ios.guideline.ios.seguir-clean-architecture-domain-application-infrastructure-presentati':
1252
+ heuristicDetector('ios.architecture.layer-direction', [
1253
+ 'heuristics.ios.architecture.layer-direction-violation.ast',
1254
+ ]),
1255
+ 'skills.ios.guideline.ios.ddd-entidades-value-objects-repositorios-protocolos-eventos-de-dominio':
1256
+ heuristicDetector('ios.architecture.layer-direction', [
1257
+ 'heuristics.ios.architecture.layer-direction-violation.ast',
1258
+ ]),
1259
+ 'skills.ios.guideline.ios.public-api-solo-exponer-lo-necesario-public-internal-private':
1260
+ heuristicDetector('ios.architecture.excessive-public-api', [
1261
+ 'heuristics.ios.architecture.excessive-public-api.ast',
1262
+ ]),
1153
1263
  'skills.ios.guideline.ios.testability-inyectar-protocols-no-tipos-concretos':
1154
1264
  heuristicDetector('ios.testability.protocol-boundaries', [
1155
1265
  'heuristics.ios.solid.dip.concrete-framework-dependency.ast',