pumuki 6.3.230 → 6.3.231

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.
@@ -65,6 +65,7 @@ import {
65
65
  hasSwiftSheetIsPresentedUsage,
66
66
  hasSwiftScrollViewShowsIndicatorsUsage,
67
67
  hasSwiftSensitiveLoggingUsage,
68
+ hasSwiftSelfPrintChangesUsage,
68
69
  hasSwiftSensitiveUserDefaultsStorageUsage,
69
70
  hasSwiftInsecureTransportUsage,
70
71
  hasSwiftJSONSerializationUsage,
@@ -323,6 +324,29 @@ struct FeedView: View {
323
324
  assert.equal(hasSwiftForEachSelfIdentityUsage(safe), false);
324
325
  });
325
326
 
327
+ test('hasSwiftSelfPrintChangesUsage detecta Self._printChanges y preserva strings y comentarios', () => {
328
+ const source = `
329
+ struct FeedView: View {
330
+ var body: some View {
331
+ Self._printChanges()
332
+ Text("Feed")
333
+ }
334
+ }
335
+ `;
336
+ const safe = `
337
+ struct FeedView: View {
338
+ var body: some View {
339
+ Text("Feed")
340
+ let sample = "Self._printChanges()"
341
+ // Self._printChanges()
342
+ }
343
+ }
344
+ `;
345
+
346
+ assert.equal(hasSwiftSelfPrintChangesUsage(source), true);
347
+ assert.equal(hasSwiftSelfPrintChangesUsage(safe), false);
348
+ });
349
+
326
350
  test('hasSwiftUntypedNavigationLinkDestinationUsage detecta NavigationLink no tipado y preserva value navigation', () => {
327
351
  const source = `
328
352
  struct FeedView: View {
@@ -853,6 +853,10 @@ export const hasSwiftForEachSelfIdentityUsage = (source: string): boolean => {
853
853
  return hasSwiftSanitizedRegexMatch(source, /\bForEach\s*\([^)]*\bid\s*:\s*\\\.self\b/g);
854
854
  };
855
855
 
856
+ export const hasSwiftSelfPrintChangesUsage = (source: string): boolean => {
857
+ return hasSwiftSanitizedRegexMatch(source, /\bSelf\s*\.\s*_printChanges\s*\(/g);
858
+ };
859
+
856
860
  export const hasSwiftInlineForEachTransformUsage = (source: string): boolean => {
857
861
  const sanitized = sanitizeSwiftSourceForMultilineRegex(source);
858
862
  return /\bForEach\s*\(\s*(?:Array\s*\(\s*)?[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*\s*\.\s*(?:filter|map|compactMap|sorted)\s*(?:\{|\()/g.test(
@@ -679,6 +679,7 @@ const textDetectorRegistry: ReadonlyArray<TextDetectorRegistryEntry> = [
679
679
  { platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftPassedValueStateWrapperUsage, ruleId: 'heuristics.ios.passed-value-state-wrapper.ast', code: 'HEURISTICS_IOS_PASSED_VALUE_STATE_WRAPPER_AST', message: 'AST heuristic detected a passed value stored as @State/@StateObject via init wrapper ownership.' },
680
680
  { platform: 'ios', pathCheck: isIOSPresentationPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftForEachIndicesUsage, ruleId: 'heuristics.ios.foreach-indices.ast', code: 'HEURISTICS_IOS_FOREACH_INDICES_AST', message: 'AST heuristic detected ForEach(...indices...) usage where stable element identity may be preferred.' },
681
681
  { platform: 'ios', pathCheck: isIOSPresentationPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftForEachSelfIdentityUsage, ruleId: 'heuristics.ios.swiftui.foreach-self-identity.ast', code: 'HEURISTICS_IOS_SWIFTUI_FOREACH_SELF_IDENTITY_AST', message: 'AST heuristic detected ForEach(..., id: \.self) usage; prefer a stable domain identity such as id: \.id or Identifiable models.' },
682
+ { platform: 'ios', pathCheck: isIOSPresentationPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftSelfPrintChangesUsage, ruleId: 'heuristics.ios.swiftui.self-print-changes.ast', code: 'HEURISTICS_IOS_SWIFTUI_SELF_PRINT_CHANGES_AST', message: 'AST heuristic detected Self._printChanges() in SwiftUI presentation; keep this debugging helper out of production view code.' },
682
683
  { platform: 'ios', pathCheck: isIOSPresentationPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftInlineForEachTransformUsage, ruleId: 'heuristics.ios.swiftui.inline-foreach-transform.ast', code: 'HEURISTICS_IOS_SWIFTUI_INLINE_FOREACH_TRANSFORM_AST', message: 'AST heuristic detected inline filter/map/sort work inside ForEach; prefiltered or cached collections remain the preferred baseline.' },
683
684
  { platform: 'ios', pathCheck: isIOSPresentationPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftUiForEachConditionalViewCountUsage, ruleId: 'heuristics.ios.swiftui.foreach-conditional-view-count.ast', code: 'HEURISTICS_IOS_SWIFTUI_FOREACH_CONDITIONAL_VIEW_COUNT_AST', message: 'AST heuristic detected conditional view count inside ForEach; keep a constant number of views per element by moving branching into row views or modifiers.' },
684
685
  { platform: 'ios', pathCheck: isIOSApplicationOrPresentationPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftContainsUserFilterUsage, ruleId: 'heuristics.ios.contains-user-filter.ast', code: 'HEURISTICS_IOS_CONTAINS_USER_FILTER_AST', message: 'AST heuristic detected contains() in a user-facing filter where localizedStandardContains() may be preferred.' },
@@ -822,6 +822,25 @@ export const iosRules: RuleSet = [
822
822
  code: 'HEURISTICS_IOS_SWIFTUI_INLINE_FOREACH_TRANSFORM_AST',
823
823
  },
824
824
  },
825
+ {
826
+ id: 'heuristics.ios.swiftui.self-print-changes.ast',
827
+ description: 'Detects SwiftUI Self._printChanges() debugging helpers in production views.',
828
+ severity: 'WARN',
829
+ platform: 'ios',
830
+ locked: true,
831
+ when: {
832
+ kind: 'Heuristic',
833
+ where: {
834
+ ruleId: 'heuristics.ios.swiftui.self-print-changes.ast',
835
+ },
836
+ },
837
+ then: {
838
+ kind: 'Finding',
839
+ message:
840
+ 'AST heuristic detected Self._printChanges() in SwiftUI presentation code; remove debug-only render diagnostics from production views.',
841
+ code: 'HEURISTICS_IOS_SWIFTUI_SELF_PRINT_CHANGES_AST',
842
+ },
843
+ },
825
844
  {
826
845
  id: 'heuristics.ios.swiftui.foreach-conditional-view-count.ast',
827
846
  description: 'Detects conditional view counts inside SwiftUI ForEach rows.',
@@ -241,6 +241,10 @@ const registryByRuleId: Record<string, SkillsDetectorBinding> = {
241
241
  heuristicDetector('ios.swiftui.foreach-self-identity', [
242
242
  'heuristics.ios.swiftui.foreach-self-identity.ast',
243
243
  ]),
244
+ 'skills.ios.guideline.ios-swiftui-expert.use-self-printchanges-to-debug-unexpected-view-updates':
245
+ heuristicDetector('ios.swiftui.self-print-changes', [
246
+ 'heuristics.ios.swiftui.self-print-changes.ast',
247
+ ]),
244
248
  'skills.ios.guideline.ios-swiftui-expert.avoid-inline-filtering-in-foreach-prefilter-and-cache':
245
249
  heuristicDetector('ios.swiftui.inline-foreach-transform', [
246
250
  'heuristics.ios.swiftui.inline-foreach-transform.ast',
@@ -325,6 +325,9 @@ const normalizeKnownRuleTarget = (
325
325
  }
326
326
  return 'skills.ios.guideline.ios-swiftui-expert.ensure-foreach-uses-stable-identity-see-references-list-patterns-md';
327
327
  }
328
+ if (includes('self.printchanges') || includes('unexpected view updates')) {
329
+ return 'skills.ios.guideline.ios-swiftui-expert.use-self-printchanges-to-debug-unexpected-view-updates';
330
+ }
328
331
  if (
329
332
  (includes('inline filtering') && includes('foreach')) ||
330
333
  (includes('no inline filtering') && includes('foreach')) ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki",
3
- "version": "6.3.230",
3
+ "version": "6.3.231",
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-13T16:49:25.074Z",
4
+ "generatedAt": "2026-05-13T16:57:01.364Z",
5
5
  "bundles": [
6
6
  {
7
7
  "name": "android-guidelines",
@@ -8620,7 +8620,7 @@
8620
8620
  "name": "ios-swiftui-expert-guidelines",
8621
8621
  "version": "1.0.0",
8622
8622
  "source": "file:vendor/skills/swiftui-expert-skill/SKILL.md",
8623
- "hash": "71169779d2e497e74027e271cc9ada00eb269509218964df2a2ff798b9a63f93",
8623
+ "hash": "4ea50faf9594602eefa6711b818cf4badeb2014ca64eaf00cb2f98f3e11a55f0",
8624
8624
  "rules": [
8625
8625
  {
8626
8626
  "id": "skills.ios.guideline.ios-swiftui-expert.action-handlers-should-reference-methods-not-contain-inline-logic",
@@ -8931,7 +8931,7 @@
8931
8931
  "sourcePath": "vendor/skills/swiftui-expert-skill/SKILL.md",
8932
8932
  "confidence": "MEDIUM",
8933
8933
  "locked": true,
8934
- "evaluationMode": "DECLARATIVE",
8934
+ "evaluationMode": "AUTO",
8935
8935
  "origin": "core"
8936
8936
  },
8937
8937
  {