pumuki 6.3.156 → 6.3.158
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.
|
@@ -445,6 +445,11 @@ const isSkillsEnforcementImplementationPath = (path: string): boolean => {
|
|
|
445
445
|
normalized.startsWith('integrations/config/') ||
|
|
446
446
|
normalized === 'integrations/git/runplatformgate.ts' ||
|
|
447
447
|
normalized === 'integrations/git/__tests__/runplatformgate.test.ts' ||
|
|
448
|
+
normalized === 'integrations/git/gitatomicity.ts' ||
|
|
449
|
+
normalized === 'integrations/git/__tests__/gitatomicity.test.ts' ||
|
|
450
|
+
normalized === 'pumuki-reset-master-plan.md' ||
|
|
451
|
+
normalized === 'package.json' ||
|
|
452
|
+
normalized === 'package-lock.json' ||
|
|
448
453
|
isSkillsContractCarrierPath(normalized)
|
|
449
454
|
);
|
|
450
455
|
};
|
|
@@ -456,13 +461,15 @@ const isSkillsEnforcementRemediationDiff = (
|
|
|
456
461
|
return false;
|
|
457
462
|
}
|
|
458
463
|
|
|
459
|
-
const normalizedPaths = paths.map((path) => toNormalizedPath(path));
|
|
464
|
+
const normalizedPaths = paths.map((path) => toNormalizedPath(path).toLowerCase());
|
|
460
465
|
const touchesDetectorSurface = normalizedPaths.some((path) =>
|
|
461
466
|
path.startsWith('core/facts/') ||
|
|
462
467
|
path.startsWith('core/rules/presets/heuristics/') ||
|
|
463
468
|
path.startsWith('integrations/config/') ||
|
|
464
469
|
path === 'integrations/git/runplatformgate.ts' ||
|
|
465
|
-
path === 'integrations/git/__tests__/runplatformgate.test.ts'
|
|
470
|
+
path === 'integrations/git/__tests__/runplatformgate.test.ts' ||
|
|
471
|
+
path === 'integrations/git/gitatomicity.ts' ||
|
|
472
|
+
path === 'integrations/git/__tests__/gitatomicity.test.ts'
|
|
466
473
|
);
|
|
467
474
|
const touchesLockOrScenario = normalizedPaths.some((path) =>
|
|
468
475
|
path === 'skills.lock.json' || path.endsWith('.feature')
|
|
@@ -485,6 +492,37 @@ const collectStagedPaths = (git: IGitService, repoRoot: string): ReadonlyArray<s
|
|
|
485
492
|
}
|
|
486
493
|
};
|
|
487
494
|
|
|
495
|
+
const BASELINE_BRANCH_REFS = [
|
|
496
|
+
'origin/develop',
|
|
497
|
+
'origin/main',
|
|
498
|
+
'upstream/develop',
|
|
499
|
+
'upstream/main',
|
|
500
|
+
'develop',
|
|
501
|
+
'main',
|
|
502
|
+
];
|
|
503
|
+
|
|
504
|
+
const collectPrePushChangedPaths = (
|
|
505
|
+
git: IGitService,
|
|
506
|
+
repoRoot: string
|
|
507
|
+
): ReadonlyArray<string> => {
|
|
508
|
+
for (const baselineRef of BASELINE_BRANCH_REFS) {
|
|
509
|
+
try {
|
|
510
|
+
git.runGit(['rev-parse', '--verify', baselineRef], repoRoot);
|
|
511
|
+
const mergeBase = git.runGit(['merge-base', baselineRef, 'HEAD'], repoRoot).trim();
|
|
512
|
+
if (mergeBase.length === 0) {
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
return git.runGit(['diff', '--name-only', `${mergeBase}..HEAD`], repoRoot)
|
|
516
|
+
.split('\n')
|
|
517
|
+
.map((line) => toNormalizedPath(line).toLowerCase())
|
|
518
|
+
.filter((line) => line.length > 0);
|
|
519
|
+
} catch {
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return [];
|
|
524
|
+
};
|
|
525
|
+
|
|
488
526
|
const toBlockingFindingsForPaths = (
|
|
489
527
|
findings: ReadonlyArray<Finding>,
|
|
490
528
|
paths: ReadonlySet<string>
|
|
@@ -1456,22 +1494,41 @@ export async function runPlatformGate(params: {
|
|
|
1456
1494
|
stagedCodePathSet
|
|
1457
1495
|
)
|
|
1458
1496
|
: [];
|
|
1497
|
+
const previousIosTestsQualityFinding =
|
|
1498
|
+
previousFactsForStagedPaths.length > 0 &&
|
|
1499
|
+
iosTestsQualityFinding === undefined &&
|
|
1500
|
+
isStrictEnforcementStage(params.policy.stage)
|
|
1501
|
+
? toIosTestsQualityBlockingFinding({
|
|
1502
|
+
stage: params.policy.stage,
|
|
1503
|
+
facts: previousFactsForStagedPaths,
|
|
1504
|
+
})
|
|
1505
|
+
: undefined;
|
|
1506
|
+
const previousRemediationBlockingFindings = [
|
|
1507
|
+
...previousBlockingFindingsForStagedPaths,
|
|
1508
|
+
...(previousIosTestsQualityFinding ? [previousIosTestsQualityFinding] : []),
|
|
1509
|
+
];
|
|
1459
1510
|
const remediationProgressFinding =
|
|
1460
|
-
|
|
1511
|
+
previousRemediationBlockingFindings.length > currentBlockingFindingsForStagedPaths.length &&
|
|
1461
1512
|
currentBlockingFindingsForStagedPaths.length === 0
|
|
1462
1513
|
? toRemediationProgressAllowedFinding({
|
|
1463
1514
|
stage: params.policy.stage as Exclude<GateStage, 'STAGED'>,
|
|
1464
1515
|
currentBlockingCount: currentBlockingFindingsForStagedPaths.length,
|
|
1465
|
-
previousBlockingCount:
|
|
1516
|
+
previousBlockingCount: previousRemediationBlockingFindings.length,
|
|
1466
1517
|
paths: stagedCodePaths,
|
|
1467
1518
|
ruleIds: [
|
|
1468
1519
|
...new Set(
|
|
1469
|
-
|
|
1520
|
+
previousRemediationBlockingFindings.map((finding) => finding.ruleId)
|
|
1470
1521
|
),
|
|
1471
1522
|
].sort(),
|
|
1472
1523
|
})
|
|
1473
1524
|
: undefined;
|
|
1474
|
-
const skillsEnforcementRemediationDiff = isSkillsEnforcementRemediationDiff(
|
|
1525
|
+
const skillsEnforcementRemediationDiff = isSkillsEnforcementRemediationDiff(
|
|
1526
|
+
stagedPaths.length > 0
|
|
1527
|
+
? stagedPaths
|
|
1528
|
+
: params.policy.stage === 'PRE_PUSH'
|
|
1529
|
+
? collectPrePushChangedPaths(git, repoRoot)
|
|
1530
|
+
: []
|
|
1531
|
+
);
|
|
1475
1532
|
const remediationProgressAllowsGlobalGap =
|
|
1476
1533
|
remediationProgressFinding !== undefined ||
|
|
1477
1534
|
(skillsEnforcementRemediationDiff &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.158",
|
|
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": {
|
|
@@ -5,3 +5,11 @@ export const isTruthyEnvValue = (value?: string): boolean => {
|
|
|
5
5
|
const normalized = value.trim().toLowerCase();
|
|
6
6
|
return normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on';
|
|
7
7
|
};
|
|
8
|
+
|
|
9
|
+
export const isFalsyEnvValue = (value?: string): boolean => {
|
|
10
|
+
if (!value) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
const normalized = value.trim().toLowerCase();
|
|
14
|
+
return normalized === '0' || normalized === 'false' || normalized === 'no' || normalized === 'off';
|
|
15
|
+
};
|
|
@@ -3,14 +3,21 @@ import type {
|
|
|
3
3
|
SystemNotificationEmitResult,
|
|
4
4
|
SystemNotificationsConfig,
|
|
5
5
|
} from './framework-menu-system-notifications-types';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
isFalsyEnvValue,
|
|
8
|
+
isTruthyEnvValue,
|
|
9
|
+
} from './framework-menu-system-notifications-env';
|
|
7
10
|
|
|
8
11
|
export const resolveSystemNotificationGate = (params: {
|
|
9
12
|
config: SystemNotificationsConfig;
|
|
10
13
|
nowMs: number;
|
|
11
14
|
env?: NodeJS.ProcessEnv;
|
|
12
15
|
}): SystemNotificationEmitResult | null => {
|
|
13
|
-
if (
|
|
16
|
+
if (
|
|
17
|
+
isTruthyEnvValue(params.env?.PUMUKI_DISABLE_SYSTEM_NOTIFICATIONS) ||
|
|
18
|
+
isFalsyEnvValue(params.env?.PUMUKI_SYSTEM_NOTIFICATIONS) ||
|
|
19
|
+
isFalsyEnvValue(params.env?.PUMUKI_NOTIFICATIONS)
|
|
20
|
+
) {
|
|
14
21
|
return { delivered: false, reason: 'disabled' };
|
|
15
22
|
}
|
|
16
23
|
if (!params.config.enabled) {
|