Skip to content

Commit b0f350b

Browse files
committed
refactor(pipeline): optimize formatCompactPrompt with single-pass reduce
Use reduce instead of multiple filter calls for better performance when processing large finding sets. Addresses Gemini code review feedback on PR #117.
1 parent b1dc32a commit b0f350b

6 files changed

Lines changed: 84 additions & 54 deletions

File tree

lib/patterns/pipeline.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -544,19 +544,25 @@ function formatHandoffPrompt(findings, mode, options = {}) {
544544
* @returns {string} Compact formatted prompt
545545
*/
546546
function formatCompactPrompt(findings, mode, maxFindings) {
547-
// Group by certainty
548-
const byGroup = {
549-
HIGH: findings.filter(f => f.certainty === CERTAINTY.HIGH),
550-
MEDIUM: findings.filter(f => f.certainty === CERTAINTY.MEDIUM),
551-
LOW: findings.filter(f => f.certainty === CERTAINTY.LOW)
552-
};
547+
// Single pass to count certainty levels and auto-fixable findings
548+
const { highCount, mediumCount, lowCount, autoFixableCount } = findings.reduce((acc, f) => {
549+
switch (f.certainty) {
550+
case CERTAINTY.HIGH: acc.highCount++; break;
551+
case CERTAINTY.MEDIUM: acc.mediumCount++; break;
552+
case CERTAINTY.LOW: acc.lowCount++; break;
553+
}
554+
if (f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none') {
555+
acc.autoFixableCount++;
556+
}
557+
return acc;
558+
}, { highCount: 0, mediumCount: 0, lowCount: 0, autoFixableCount: 0 });
553559

554560
// Truncate if needed
555561
const limited = findings.slice(0, maxFindings);
556562
const truncated = findings.length > maxFindings;
557563

558564
// Summary header
559-
let output = `## Slop: ${mode}|H:${byGroup.HIGH.length}|M:${byGroup.MEDIUM.length}|L:${byGroup.LOW.length}\n\n`;
565+
let output = `## Slop: ${mode}|H:${highCount}|M:${mediumCount}|L:${lowCount}\n\n`;
560566

561567
// Table format
562568
output += '|File|L|Pattern|Cert|Fix|\n';
@@ -573,8 +579,7 @@ function formatCompactPrompt(findings, mode, maxFindings) {
573579
}
574580

575581
// Auto-fix summary
576-
const autoFixable = findings.filter(f => f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none');
577-
output += `\n**Auto-fixable: ${autoFixable.length}** | Manual: ${findings.length - autoFixable.length}`;
582+
output += `\n**Auto-fixable: ${autoFixableCount}** | Manual: ${findings.length - autoFixableCount}`;
578583

579584
return output;
580585
}

plugins/deslop-around/lib/patterns/pipeline.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -544,19 +544,25 @@ function formatHandoffPrompt(findings, mode, options = {}) {
544544
* @returns {string} Compact formatted prompt
545545
*/
546546
function formatCompactPrompt(findings, mode, maxFindings) {
547-
// Group by certainty
548-
const byGroup = {
549-
HIGH: findings.filter(f => f.certainty === CERTAINTY.HIGH),
550-
MEDIUM: findings.filter(f => f.certainty === CERTAINTY.MEDIUM),
551-
LOW: findings.filter(f => f.certainty === CERTAINTY.LOW)
552-
};
547+
// Single pass to count certainty levels and auto-fixable findings
548+
const { highCount, mediumCount, lowCount, autoFixableCount } = findings.reduce((acc, f) => {
549+
switch (f.certainty) {
550+
case CERTAINTY.HIGH: acc.highCount++; break;
551+
case CERTAINTY.MEDIUM: acc.mediumCount++; break;
552+
case CERTAINTY.LOW: acc.lowCount++; break;
553+
}
554+
if (f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none') {
555+
acc.autoFixableCount++;
556+
}
557+
return acc;
558+
}, { highCount: 0, mediumCount: 0, lowCount: 0, autoFixableCount: 0 });
553559

554560
// Truncate if needed
555561
const limited = findings.slice(0, maxFindings);
556562
const truncated = findings.length > maxFindings;
557563

558564
// Summary header
559-
let output = `## Slop: ${mode}|H:${byGroup.HIGH.length}|M:${byGroup.MEDIUM.length}|L:${byGroup.LOW.length}\n\n`;
565+
let output = `## Slop: ${mode}|H:${highCount}|M:${mediumCount}|L:${lowCount}\n\n`;
560566

561567
// Table format
562568
output += '|File|L|Pattern|Cert|Fix|\n';
@@ -573,8 +579,7 @@ function formatCompactPrompt(findings, mode, maxFindings) {
573579
}
574580

575581
// Auto-fix summary
576-
const autoFixable = findings.filter(f => f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none');
577-
output += `\n**Auto-fixable: ${autoFixable.length}** | Manual: ${findings.length - autoFixable.length}`;
582+
output += `\n**Auto-fixable: ${autoFixableCount}** | Manual: ${findings.length - autoFixableCount}`;
578583

579584
return output;
580585
}

plugins/next-task/lib/patterns/pipeline.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -544,19 +544,25 @@ function formatHandoffPrompt(findings, mode, options = {}) {
544544
* @returns {string} Compact formatted prompt
545545
*/
546546
function formatCompactPrompt(findings, mode, maxFindings) {
547-
// Group by certainty
548-
const byGroup = {
549-
HIGH: findings.filter(f => f.certainty === CERTAINTY.HIGH),
550-
MEDIUM: findings.filter(f => f.certainty === CERTAINTY.MEDIUM),
551-
LOW: findings.filter(f => f.certainty === CERTAINTY.LOW)
552-
};
547+
// Single pass to count certainty levels and auto-fixable findings
548+
const { highCount, mediumCount, lowCount, autoFixableCount } = findings.reduce((acc, f) => {
549+
switch (f.certainty) {
550+
case CERTAINTY.HIGH: acc.highCount++; break;
551+
case CERTAINTY.MEDIUM: acc.mediumCount++; break;
552+
case CERTAINTY.LOW: acc.lowCount++; break;
553+
}
554+
if (f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none') {
555+
acc.autoFixableCount++;
556+
}
557+
return acc;
558+
}, { highCount: 0, mediumCount: 0, lowCount: 0, autoFixableCount: 0 });
553559

554560
// Truncate if needed
555561
const limited = findings.slice(0, maxFindings);
556562
const truncated = findings.length > maxFindings;
557563

558564
// Summary header
559-
let output = `## Slop: ${mode}|H:${byGroup.HIGH.length}|M:${byGroup.MEDIUM.length}|L:${byGroup.LOW.length}\n\n`;
565+
let output = `## Slop: ${mode}|H:${highCount}|M:${mediumCount}|L:${lowCount}\n\n`;
560566

561567
// Table format
562568
output += '|File|L|Pattern|Cert|Fix|\n';
@@ -573,8 +579,7 @@ function formatCompactPrompt(findings, mode, maxFindings) {
573579
}
574580

575581
// Auto-fix summary
576-
const autoFixable = findings.filter(f => f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none');
577-
output += `\n**Auto-fixable: ${autoFixable.length}** | Manual: ${findings.length - autoFixable.length}`;
582+
output += `\n**Auto-fixable: ${autoFixableCount}** | Manual: ${findings.length - autoFixableCount}`;
578583

579584
return output;
580585
}

plugins/project-review/lib/patterns/pipeline.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -544,19 +544,25 @@ function formatHandoffPrompt(findings, mode, options = {}) {
544544
* @returns {string} Compact formatted prompt
545545
*/
546546
function formatCompactPrompt(findings, mode, maxFindings) {
547-
// Group by certainty
548-
const byGroup = {
549-
HIGH: findings.filter(f => f.certainty === CERTAINTY.HIGH),
550-
MEDIUM: findings.filter(f => f.certainty === CERTAINTY.MEDIUM),
551-
LOW: findings.filter(f => f.certainty === CERTAINTY.LOW)
552-
};
547+
// Single pass to count certainty levels and auto-fixable findings
548+
const { highCount, mediumCount, lowCount, autoFixableCount } = findings.reduce((acc, f) => {
549+
switch (f.certainty) {
550+
case CERTAINTY.HIGH: acc.highCount++; break;
551+
case CERTAINTY.MEDIUM: acc.mediumCount++; break;
552+
case CERTAINTY.LOW: acc.lowCount++; break;
553+
}
554+
if (f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none') {
555+
acc.autoFixableCount++;
556+
}
557+
return acc;
558+
}, { highCount: 0, mediumCount: 0, lowCount: 0, autoFixableCount: 0 });
553559

554560
// Truncate if needed
555561
const limited = findings.slice(0, maxFindings);
556562
const truncated = findings.length > maxFindings;
557563

558564
// Summary header
559-
let output = `## Slop: ${mode}|H:${byGroup.HIGH.length}|M:${byGroup.MEDIUM.length}|L:${byGroup.LOW.length}\n\n`;
565+
let output = `## Slop: ${mode}|H:${highCount}|M:${mediumCount}|L:${lowCount}\n\n`;
560566

561567
// Table format
562568
output += '|File|L|Pattern|Cert|Fix|\n';
@@ -573,8 +579,7 @@ function formatCompactPrompt(findings, mode, maxFindings) {
573579
}
574580

575581
// Auto-fix summary
576-
const autoFixable = findings.filter(f => f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none');
577-
output += `\n**Auto-fixable: ${autoFixable.length}** | Manual: ${findings.length - autoFixable.length}`;
582+
output += `\n**Auto-fixable: ${autoFixableCount}** | Manual: ${findings.length - autoFixableCount}`;
578583

579584
return output;
580585
}

plugins/reality-check/lib/patterns/pipeline.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -544,19 +544,25 @@ function formatHandoffPrompt(findings, mode, options = {}) {
544544
* @returns {string} Compact formatted prompt
545545
*/
546546
function formatCompactPrompt(findings, mode, maxFindings) {
547-
// Group by certainty
548-
const byGroup = {
549-
HIGH: findings.filter(f => f.certainty === CERTAINTY.HIGH),
550-
MEDIUM: findings.filter(f => f.certainty === CERTAINTY.MEDIUM),
551-
LOW: findings.filter(f => f.certainty === CERTAINTY.LOW)
552-
};
547+
// Single pass to count certainty levels and auto-fixable findings
548+
const { highCount, mediumCount, lowCount, autoFixableCount } = findings.reduce((acc, f) => {
549+
switch (f.certainty) {
550+
case CERTAINTY.HIGH: acc.highCount++; break;
551+
case CERTAINTY.MEDIUM: acc.mediumCount++; break;
552+
case CERTAINTY.LOW: acc.lowCount++; break;
553+
}
554+
if (f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none') {
555+
acc.autoFixableCount++;
556+
}
557+
return acc;
558+
}, { highCount: 0, mediumCount: 0, lowCount: 0, autoFixableCount: 0 });
553559

554560
// Truncate if needed
555561
const limited = findings.slice(0, maxFindings);
556562
const truncated = findings.length > maxFindings;
557563

558564
// Summary header
559-
let output = `## Slop: ${mode}|H:${byGroup.HIGH.length}|M:${byGroup.MEDIUM.length}|L:${byGroup.LOW.length}\n\n`;
565+
let output = `## Slop: ${mode}|H:${highCount}|M:${mediumCount}|L:${lowCount}\n\n`;
560566

561567
// Table format
562568
output += '|File|L|Pattern|Cert|Fix|\n';
@@ -573,8 +579,7 @@ function formatCompactPrompt(findings, mode, maxFindings) {
573579
}
574580

575581
// Auto-fix summary
576-
const autoFixable = findings.filter(f => f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none');
577-
output += `\n**Auto-fixable: ${autoFixable.length}** | Manual: ${findings.length - autoFixable.length}`;
582+
output += `\n**Auto-fixable: ${autoFixableCount}** | Manual: ${findings.length - autoFixableCount}`;
578583

579584
return output;
580585
}

plugins/ship/lib/patterns/pipeline.js

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -544,19 +544,25 @@ function formatHandoffPrompt(findings, mode, options = {}) {
544544
* @returns {string} Compact formatted prompt
545545
*/
546546
function formatCompactPrompt(findings, mode, maxFindings) {
547-
// Group by certainty
548-
const byGroup = {
549-
HIGH: findings.filter(f => f.certainty === CERTAINTY.HIGH),
550-
MEDIUM: findings.filter(f => f.certainty === CERTAINTY.MEDIUM),
551-
LOW: findings.filter(f => f.certainty === CERTAINTY.LOW)
552-
};
547+
// Single pass to count certainty levels and auto-fixable findings
548+
const { highCount, mediumCount, lowCount, autoFixableCount } = findings.reduce((acc, f) => {
549+
switch (f.certainty) {
550+
case CERTAINTY.HIGH: acc.highCount++; break;
551+
case CERTAINTY.MEDIUM: acc.mediumCount++; break;
552+
case CERTAINTY.LOW: acc.lowCount++; break;
553+
}
554+
if (f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none') {
555+
acc.autoFixableCount++;
556+
}
557+
return acc;
558+
}, { highCount: 0, mediumCount: 0, lowCount: 0, autoFixableCount: 0 });
553559

554560
// Truncate if needed
555561
const limited = findings.slice(0, maxFindings);
556562
const truncated = findings.length > maxFindings;
557563

558564
// Summary header
559-
let output = `## Slop: ${mode}|H:${byGroup.HIGH.length}|M:${byGroup.MEDIUM.length}|L:${byGroup.LOW.length}\n\n`;
565+
let output = `## Slop: ${mode}|H:${highCount}|M:${mediumCount}|L:${lowCount}\n\n`;
560566

561567
// Table format
562568
output += '|File|L|Pattern|Cert|Fix|\n';
@@ -573,8 +579,7 @@ function formatCompactPrompt(findings, mode, maxFindings) {
573579
}
574580

575581
// Auto-fix summary
576-
const autoFixable = findings.filter(f => f.autoFix && f.autoFix !== 'flag' && f.autoFix !== 'none');
577-
output += `\n**Auto-fixable: ${autoFixable.length}** | Manual: ${findings.length - autoFixable.length}`;
582+
output += `\n**Auto-fixable: ${autoFixableCount}** | Manual: ${findings.length - autoFixableCount}`;
578583

579584
return output;
580585
}

0 commit comments

Comments
 (0)