pumuki 6.3.246 → 6.3.248

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.
@@ -233,6 +233,13 @@ const normalizeKnownRuleTarget = (
233
233
  if (includes('task detached') || includes('task.detached')) {
234
234
  return 'skills.ios.no-task-detached';
235
235
  }
236
+ if (
237
+ includes('remove async if not required') ||
238
+ includes('async without await') ||
239
+ includes('async_without_await')
240
+ ) {
241
+ return 'skills.ios.no-async-without-await';
242
+ }
236
243
  if (includes('unchecked sendable')) {
237
244
  return 'skills.ios.no-unchecked-sendable';
238
245
  }
@@ -330,6 +337,13 @@ const normalizeKnownRuleTarget = (
330
337
  ) {
331
338
  return 'skills.ios.guideline.ios-swiftui-expert.prefer-modifiers-over-conditional-views-for-state-changes-maintains-vi';
332
339
  }
340
+ if (
341
+ includes('sheets should own their actions') ||
342
+ (includes('call dismiss internally') && includes('sheet')) ||
343
+ (includes('avoid passing dismiss') && includes('callbacks to sheets'))
344
+ ) {
345
+ return 'skills.ios.guideline.ios-swiftui-expert.sheets-should-own-their-actions-and-call-dismiss-internally';
346
+ }
333
347
  if (
334
348
  (includes('foreach') && includes('indices')) ||
335
349
  includes('stable identity for foreach') ||
@@ -484,6 +498,12 @@ const normalizeKnownRuleTarget = (
484
498
  if (includes('uiscreen main bounds') || includes('uiscreen.main.bounds')) {
485
499
  return 'skills.ios.no-uiscreen-main-bounds';
486
500
  }
501
+ if (
502
+ (includes('task id') && includes('value dependent')) ||
503
+ (includes('task id') && includes('value-dependent'))
504
+ ) {
505
+ return 'skills.ios.guideline.ios-swiftui-expert.use-task-id-for-value-dependent-tasks';
506
+ }
487
507
  if (
488
508
  includes('task/.task(id') ||
489
509
  includes('trabajos async con cancelacion automatica') ||
@@ -493,15 +513,127 @@ const normalizeKnownRuleTarget = (
493
513
  ) {
494
514
  return 'skills.ios.guideline.ios-swiftui-expert.use-task-modifier-for-automatic-cancellation-of-async-work';
495
515
  }
516
+ if (includes('jsonserialization')) {
517
+ if (includes('decodificacion automatica') || includes('decoding')) {
518
+ return 'skills.ios.guideline.ios.codable-decodificacio-n-automa-tica-de-json-nunca-jsonserialization';
519
+ }
520
+ if (includes('codable')) {
521
+ return 'skills.ios.guideline.ios.codable-para-serializacio-n-json-nunca-jsonserialization';
522
+ }
523
+ }
524
+ if (
525
+ (includes('keychain') && includes('userdefaults')) ||
526
+ (includes('passwords') && includes('tokens') && includes('userdefaults'))
527
+ ) {
528
+ return 'skills.ios.guideline.ios.keychain-passwords-tokens-no-userdefaults';
529
+ }
530
+ if (includes('userdefaults') && includes('no datos sensibles')) {
531
+ return 'skills.ios.guideline.ios.userdefaults-settings-simples-no-datos-sensibles';
532
+ }
533
+ if (
534
+ includes('print y logs ad hoc') ||
535
+ includes('print() y logs ad hoc') ||
536
+ includes('logs ad hoc')
537
+ ) {
538
+ return 'skills.ios.guideline.ios.prohibido-print-y-logs-ad-hoc';
539
+ }
540
+ if (
541
+ includes('catch vac') ||
542
+ includes('catch vaci') ||
543
+ includes('emptycatch') ||
544
+ includes('empty catch')
545
+ ) {
546
+ return 'skills.ios.guideline.ios.catch-vaci-os-prohibido-silenciar-errores-ast-common-error-emptycatch';
547
+ }
548
+ if (includes('no loggear pii') || includes('tokens emails ids sensibles')) {
549
+ return 'skills.ios.guideline.ios.no-loggear-pii-tokens-emails-ids-sensibles';
550
+ }
551
+ if (includes('obfuscation') && includes('strings sensibles')) {
552
+ return 'skills.ios.guideline.ios.obfuscation-strings-sensibles-en-co-digo';
553
+ }
554
+ if (includes('dateformatter') && includes('fechas localizadas')) {
555
+ return 'skills.ios.guideline.ios.dateformatter-fechas-localizadas';
556
+ }
557
+ if (includes('strings hardcodeadas') && includes('ui')) {
558
+ return 'skills.ios.guideline.ios.cero-strings-hardcodeadas-en-ui';
559
+ }
560
+ if (includes('assets en asset catalogs')) {
561
+ return 'skills.ios.guideline.ios.assets-en-asset-catalogs-con-soporte-para-todos-los-taman-os';
562
+ }
563
+ if (includes('dynamic type') && includes('font scaling')) {
564
+ return 'skills.ios.guideline.ios.dynamic-type-font-scaling-automa-tico';
565
+ }
566
+ if (includes('dynamic type') && includes('fuentes escalables')) {
567
+ return 'skills.ios.guideline.ios.dynamic-type-fuentes-escalables-y-layouts-adaptativos';
568
+ }
569
+ if (includes('rtl support') || includes('right to left')) {
570
+ return 'skills.ios.guideline.ios.rtl-support-right-to-left-para-a-rabe-hebreo';
571
+ }
572
+ if (includes('background threads') && includes('no bloquear main thread')) {
573
+ return 'skills.ios.guideline.ios.background-threads-no-bloquear-main-thread';
574
+ }
575
+ if (includes('accessibility labels') || includes('accessibilitylabel')) {
576
+ return 'skills.ios.guideline.ios.accessibility-labels-accessibilitylabel';
577
+ }
578
+ if (includes('delegation pattern') && includes('weak delegates')) {
579
+ return 'skills.ios.guideline.ios.delegation-pattern-weak-delegates-para-evitar-retain-cycles';
580
+ }
581
+ if (includes('retain cycles') && includes('memory leaks')) {
582
+ return 'skills.ios.guideline.ios.retain-cycles-memory-leaks';
583
+ }
584
+ if (includes('retain cycles') && includes('closures')) {
585
+ return 'skills.ios.guideline.ios.evitar-retain-cycles-especialmente-en-closures-delegates';
586
+ }
587
+ if (includes('no singleton') || includes('no singletons')) {
588
+ return 'skills.ios.guideline.ios.no-singleton-usar-inyeccio-n-de-dependencias-no-compartir-instancias-g';
589
+ }
590
+ if (includes('massive view controllers')) {
591
+ return 'skills.ios.guideline.ios.massive-view-controllers-viewcontrollers-que-mezclan-presentacio-n-nav';
592
+ }
593
+ if (includes('implicitly unwrapped')) {
594
+ return 'skills.ios.guideline.ios.implicitly-unwrapped-solo-para-iboutlets-y-casos-muy-especi-ficos';
595
+ }
596
+ if (includes('magic numbers')) {
597
+ return 'skills.ios.guideline.ios.magic-numbers-usar-constantes-con-nombres';
598
+ }
599
+ if (includes('swinject')) {
600
+ return 'skills.ios.guideline.ios.swinject-prohibido-di-manual-o-environment';
601
+ }
602
+ if (
603
+ includes('navigationstack navigationpath') ||
604
+ includes('navigationstack + navigationpath')
605
+ ) {
606
+ return 'skills.ios.no-navigation-view';
607
+ }
608
+ if (
609
+ includes('onchange') &&
610
+ (includes('2 parametros') || includes('2 para metros') || includes('sin parametros'))
611
+ ) {
612
+ return 'skills.ios.no-legacy-onchange';
613
+ }
614
+ if (
615
+ includes('lazyvstack lazyhstack') ||
616
+ (includes('lazy loading') && includes('lazyvstack'))
617
+ ) {
618
+ return 'skills.ios.guideline.ios-swiftui-expert.use-lazyvstack-lazyhstack-for-large-lists';
619
+ }
620
+ if (includes('singletons') && includes('dificultan testing')) {
621
+ return 'skills.ios.guideline.ios.singletons-dificultan-testing';
622
+ }
496
623
  if (
497
624
  includes('swift testing over xctest') ||
498
625
  includes('prefer import testing') ||
499
626
  includes('prefer test functions over test methods') ||
500
627
  includes('test functions over test methods') ||
501
628
  includes('xctest-only unit tests') ||
629
+ includes('xctest only unit tests') ||
502
630
  includes('new xctest-only unit tests') ||
631
+ includes('new xctest only unit tests') ||
503
632
  includes('xctest only for ui') ||
504
- includes('xctest only for ui performance')
633
+ includes('xctest only for ui performance') ||
634
+ (includes('xctest solo') && includes('legacy')) ||
635
+ (includes('xctest') && includes('solo para proyectos legacy')) ||
636
+ (includes('xctest') && includes('ui tests'))
505
637
  ) {
506
638
  return 'skills.ios.prefer-swift-testing';
507
639
  }
@@ -532,13 +664,6 @@ const normalizeKnownRuleTarget = (
532
664
  ) {
533
665
  return 'skills.ios.guideline.ios.app-transport-security-ats-https-por-defecto';
534
666
  }
535
- if (
536
- includes('localizable strings') ||
537
- includes('string catalogs') ||
538
- includes('xcstrings')
539
- ) {
540
- return 'skills.ios.guideline.ios.localizable-strings-deprecado-usar-string-catalogs';
541
- }
542
667
  if (includes('strings hardcodeadas') || includes('string localized')) {
543
668
  return 'skills.ios.guideline.ios.cero-strings-hardcodeadas-en-ui';
544
669
  }
@@ -639,9 +764,16 @@ const normalizeKnownRuleTarget = (
639
764
  }
640
765
  if (
641
766
  includes('nsmanagedobject across boundaries') ||
767
+ includes('nsmanagedobjectid or mapped dto') ||
768
+ includes('mapped dto domain models') ||
642
769
  includes('passing nsmanagedobject') ||
770
+ includes('pass nsmanagedobjectid when a different context') ||
643
771
  includes('nsmanagedobject through service') ||
644
- includes('nsmanagedobject in shared function and property boundaries')
772
+ includes('nsmanagedobject in shared function and property boundaries') ||
773
+ includes('managed objects as context scoped references') ||
774
+ includes('not as portable domain entities') ||
775
+ includes('managed objects into domain models before crossing module boundaries') ||
776
+ includes('map managed objects into domain models')
645
777
  ) {
646
778
  return 'skills.ios.no-nsmanagedobject-boundary';
647
779
  }
@@ -663,6 +795,8 @@ const normalizeKnownRuleTarget = (
663
795
  }
664
796
  if (
665
797
  includes('core data orchestration inside infrastructure') ||
798
+ includes('make context ownership explicit') ||
799
+ includes('merge boundaries controlled') ||
666
800
  includes('instead of presentation code') ||
667
801
  includes('core data apis in application or presentation code') ||
668
802
  includes('avoid core data apis in application or presentation code') ||
@@ -151,7 +151,7 @@ const PLATFORM_REQUIRED_SKILLS_BUNDLES: Readonly<Record<PreWriteSkillsPlatform,
151
151
  frontend: ['frontend-guidelines'],
152
152
  };
153
153
  const PREWRITE_CRITICAL_SKILLS_RULES: Readonly<Record<PreWriteSkillsPlatform, ReadonlyArray<string>>> = {
154
- ios: [],
154
+ ios: ['skills.ios.critical-test-quality'],
155
155
  android: [],
156
156
  backend: [],
157
157
  frontend: [],
@@ -644,7 +644,8 @@ const collectPreWritePlatformSkillsViolations = (params: {
644
644
 
645
645
  if (missingCriticalRulesByPlatform.length > 0) {
646
646
  violations.push(
647
- toCriticalSkillsViolation(
647
+ toSkillsViolation(
648
+ params.skillsEnforcement,
648
649
  'EVIDENCE_PLATFORM_CRITICAL_SKILLS_RULES_MISSING',
649
650
  `Detected platforms missing critical skill-rule enforcement in PRE_WRITE: ${missingCriticalRulesByPlatform.join(' | ')}.`
650
651
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki",
3
- "version": "6.3.246",
3
+ "version": "6.3.248",
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": {
@@ -156,6 +156,11 @@ const runMenuAuditGate = async (
156
156
  await defaultDependencies.runPlatformGate({
157
157
  ...gateParams,
158
158
  auditMode: 'engine',
159
+ sddDecisionOverride: {
160
+ allowed: true,
161
+ code: 'ALLOWED',
162
+ message: 'Framework menu audit gate runs without implicit SDD/OpenSpec bootstrap.',
163
+ },
159
164
  dependencies: {
160
165
  printGateFindings: () => {},
161
166
  evaluatePlatformGateFindings: (params) =>
@@ -5,12 +5,24 @@ import type {
5
5
  } from './framework-menu-system-notifications-types';
6
6
  import { isTruthyEnvValue } from './framework-menu-system-notifications-env';
7
7
 
8
+ const isDisabledEnvValue = (value?: string): boolean => {
9
+ if (!value) {
10
+ return false;
11
+ }
12
+ const normalized = value.trim().toLowerCase();
13
+ return normalized === '0' || normalized === 'false' || normalized === 'no' || normalized === 'off';
14
+ };
15
+
8
16
  export const resolveSystemNotificationGate = (params: {
9
17
  config: SystemNotificationsConfig;
10
18
  nowMs: number;
11
19
  env?: NodeJS.ProcessEnv;
12
20
  }): SystemNotificationEmitResult | null => {
13
- if (isTruthyEnvValue(params.env?.PUMUKI_DISABLE_SYSTEM_NOTIFICATIONS)) {
21
+ if (
22
+ isTruthyEnvValue(params.env?.PUMUKI_DISABLE_SYSTEM_NOTIFICATIONS) ||
23
+ isDisabledEnvValue(params.env?.PUMUKI_SYSTEM_NOTIFICATIONS) ||
24
+ isDisabledEnvValue(params.env?.PUMUKI_NOTIFICATIONS)
25
+ ) {
14
26
  return { delivered: false, reason: 'disabled' };
15
27
  }
16
28
  if (!params.config.enabled) {
@@ -13,7 +13,11 @@ export const commitBaseline = (
13
13
  ): void => {
14
14
  writeBaselineFile(workspace.consumerRepo);
15
15
  runGitStep(workspace, ['add', '.'], 'git add baseline');
16
- runGitStep(workspace, ['commit', '-m', 'chore: baseline'], 'git commit baseline');
16
+ runGitStep(
17
+ workspace,
18
+ ['commit', '--no-verify', '-m', 'chore: baseline'],
19
+ 'git commit baseline'
20
+ );
17
21
  };
18
22
 
19
23
  export const writeAndCommitRangePayloadForBlockMode = (
@@ -28,7 +32,7 @@ export const writeAndCommitRangePayloadForBlockMode = (
28
32
  runGitStep(workspace, ['add', '.'], 'git add range payload');
29
33
  runGitStep(
30
34
  workspace,
31
- ['commit', '-m', 'test: range payload for package smoke'],
35
+ ['commit', '--no-verify', '-m', 'test: range payload for package smoke'],
32
36
  'git commit range payload'
33
37
  );
34
38
  };
@@ -39,7 +39,7 @@ export const configureRemoteAndFeatureBranch = (
39
39
  workspace.tmpRoot
40
40
  );
41
41
  runGitStep(workspace, ['remote', 'add', 'origin', workspace.bareRemote], 'git remote add origin');
42
- runGitStep(workspace, ['push', '-u', 'origin', 'main'], 'git push origin main');
42
+ runGitStep(workspace, ['push', '--no-verify', '-u', 'origin', 'main'], 'git push origin main');
43
43
  runGitStep(workspace, ['checkout', '-b', 'feature/package-smoke'], 'git checkout feature branch');
44
44
  runGitStep(
45
45
  workspace,