pumuki 6.3.352 → 6.3.354
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.
|
@@ -30,6 +30,8 @@ type NotificationBlockingCause = {
|
|
|
30
30
|
message: string;
|
|
31
31
|
ruleId?: string;
|
|
32
32
|
file?: string;
|
|
33
|
+
line?: number;
|
|
34
|
+
lines?: ReadonlyArray<number>;
|
|
33
35
|
remediation?: string;
|
|
34
36
|
};
|
|
35
37
|
|
|
@@ -83,6 +85,48 @@ const extractMessageField = (message: string, field: string): string | undefined
|
|
|
83
85
|
return value && value.length > 0 ? value : undefined;
|
|
84
86
|
};
|
|
85
87
|
|
|
88
|
+
const normalizeEvidenceLinesForNotification = (
|
|
89
|
+
lines: unknown
|
|
90
|
+
): Pick<NotificationBlockingCause, 'line' | 'lines'> => {
|
|
91
|
+
if (typeof lines === 'number' && Number.isFinite(lines) && lines > 0) {
|
|
92
|
+
return {
|
|
93
|
+
line: Math.floor(lines),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (Array.isArray(lines)) {
|
|
97
|
+
const normalized = Array.from(
|
|
98
|
+
new Set(
|
|
99
|
+
lines
|
|
100
|
+
.filter((line): line is number => typeof line === 'number' && Number.isFinite(line) && line > 0)
|
|
101
|
+
.map((line) => Math.floor(line))
|
|
102
|
+
)
|
|
103
|
+
).sort((left, right) => left - right);
|
|
104
|
+
return normalized.length > 0 ? { lines: normalized } : {};
|
|
105
|
+
}
|
|
106
|
+
if (typeof lines === 'string') {
|
|
107
|
+
const normalized = Array.from(
|
|
108
|
+
new Set(
|
|
109
|
+
lines
|
|
110
|
+
.split(',')
|
|
111
|
+
.map((line) => Number.parseInt(line.trim(), 10))
|
|
112
|
+
.filter((line) => Number.isFinite(line) && line > 0)
|
|
113
|
+
)
|
|
114
|
+
).sort((left, right) => left - right);
|
|
115
|
+
return normalized.length > 0 ? { lines: normalized } : {};
|
|
116
|
+
}
|
|
117
|
+
return {};
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const extractStructuredLinesFromMessage = (
|
|
121
|
+
message: string
|
|
122
|
+
): Pick<NotificationBlockingCause, 'line' | 'lines'> => {
|
|
123
|
+
const raw = message.match(/\blines?=([0-9][0-9,\-\s]*)\b/i)?.[1];
|
|
124
|
+
if (!raw) {
|
|
125
|
+
return {};
|
|
126
|
+
}
|
|
127
|
+
return normalizeEvidenceLinesForNotification(raw);
|
|
128
|
+
};
|
|
129
|
+
|
|
86
130
|
const extractFirstNestedSkillSegment = (message: string): string =>
|
|
87
131
|
message
|
|
88
132
|
.replace(/^.*?\bBlocking causes:\s*1\)\s*/isu, '')
|
|
@@ -121,6 +165,11 @@ const extractNestedSkillCauseFromWrapper = (cause: NotificationBlockingCause): N
|
|
|
121
165
|
code: normalizeRuleCode(ruleId),
|
|
122
166
|
ruleId,
|
|
123
167
|
file: nestedFile ?? cause.file,
|
|
168
|
+
...(
|
|
169
|
+
cause.line || cause.lines
|
|
170
|
+
? {}
|
|
171
|
+
: extractStructuredLinesFromMessage(normalizedNestedMessage)
|
|
172
|
+
),
|
|
124
173
|
message: `rule=${ruleId} ${normalizedNestedMessage}`,
|
|
125
174
|
remediation:
|
|
126
175
|
cause.remediation && !/corrige la violaci[oó]n indicada|corrige la causa bloqueante/i.test(cause.remediation)
|
|
@@ -163,6 +212,7 @@ export const toAuditSummaryEventFromEvidence = (
|
|
|
163
212
|
code: cause.code,
|
|
164
213
|
ruleId: cause.ruleId,
|
|
165
214
|
file: cause.file,
|
|
215
|
+
...normalizeEvidenceLinesForNotification(cause.lines),
|
|
166
216
|
message: formatEvidenceBlockingCause(cause),
|
|
167
217
|
remediation: cause.remediation,
|
|
168
218
|
})
|
|
@@ -204,6 +254,7 @@ export const toAuditSummaryEventFromAiGate = (params: {
|
|
|
204
254
|
ruleId: violation.code.startsWith('skills.') ? violation.code : undefined,
|
|
205
255
|
message: violation.message,
|
|
206
256
|
remediation: 'Corrige la violación indicada y vuelve a intentar el commit.',
|
|
257
|
+
...extractStructuredLinesFromMessage(violation.message),
|
|
207
258
|
})
|
|
208
259
|
),
|
|
209
260
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.354",
|
|
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": {
|
|
@@ -137,6 +137,17 @@ const formatLocation = (cause: NonNullable<Extract<PumukiCriticalNotificationEve
|
|
|
137
137
|
if (!cause.file) {
|
|
138
138
|
return 'sin fichero';
|
|
139
139
|
}
|
|
140
|
+
if (typeof cause.line === 'number' && Number.isFinite(cause.line) && cause.line > 0) {
|
|
141
|
+
return `${cause.file}:${Math.floor(cause.line)}`;
|
|
142
|
+
}
|
|
143
|
+
if (Array.isArray(cause.lines)) {
|
|
144
|
+
const lines = cause.lines
|
|
145
|
+
.filter((line) => Number.isFinite(line) && line > 0)
|
|
146
|
+
.map((line) => Math.floor(line));
|
|
147
|
+
if (lines.length > 0) {
|
|
148
|
+
return `${cause.file}:${lines.join(',')}`;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
140
151
|
const line = extractLineFromCauseMessage(cause.message);
|
|
141
152
|
return line ? `${cause.file}:${line}` : cause.file;
|
|
142
153
|
};
|
|
@@ -118,6 +118,17 @@ const formatCauseLocation = (cause: BlockedCause): string => {
|
|
|
118
118
|
return 'sin fichero';
|
|
119
119
|
}
|
|
120
120
|
const baseFile = cause.file.split('/').filter(Boolean).pop() ?? cause.file;
|
|
121
|
+
if (typeof cause.line === 'number' && Number.isFinite(cause.line) && cause.line > 0) {
|
|
122
|
+
return `${baseFile}:${Math.floor(cause.line)}`;
|
|
123
|
+
}
|
|
124
|
+
if (Array.isArray(cause.lines)) {
|
|
125
|
+
const lines = cause.lines
|
|
126
|
+
.filter((line) => Number.isFinite(line) && line > 0)
|
|
127
|
+
.map((line) => Math.floor(line));
|
|
128
|
+
if (lines.length > 0) {
|
|
129
|
+
return `${baseFile}:${lines.join(',')}`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
121
132
|
const lineMatch = cause.message.match(/\blines?=([0-9][0-9,\-\s]*)\b/i);
|
|
122
133
|
if (!lineMatch?.[1]) {
|
|
123
134
|
return baseFile;
|