takt: issue (#220)

This commit is contained in:
nrs 2026-02-11 06:37:06 +09:00 committed by GitHub
parent 6bf495f417
commit 36e77ae0fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 74 additions and 3 deletions

View File

@ -393,6 +393,63 @@ describe('ParallelLogger', () => {
expect(doneIndex0).toBe(doneIndex1);
});
it('should prepend task prefix to all summary lines in rich mode', () => {
const logger = new ParallelLogger({
subMovementNames: ['arch-review', 'security-review'],
writeFn,
progressInfo: { iteration: 5, maxMovements: 30 },
taskLabel: 'override-persona-provider',
taskColorIndex: 0,
parentMovementName: 'reviewers',
movementIteration: 1,
});
logger.printSummary('reviewers', [
{ name: 'arch-review', condition: 'approved' },
{ name: 'security-review', condition: 'needs_fix' },
]);
// Every output line should have the task prefix
for (const line of output) {
expect(line).toContain('[over]');
expect(line).toContain('[reviewers]');
expect(line).toContain('(5/30)(1)');
}
// Verify task color (cyan for index 0)
expect(output[0]).toContain('\x1b[36m');
// Verify summary content is still present
const fullOutput = output.join('');
expect(fullOutput).toContain('reviewers results');
expect(fullOutput).toContain('arch-review:');
expect(fullOutput).toContain('approved');
expect(fullOutput).toContain('security-review:');
expect(fullOutput).toContain('needs_fix');
});
it('should not prepend task prefix to summary lines in non-rich mode', () => {
const logger = new ParallelLogger({
subMovementNames: ['arch-review'],
writeFn,
});
logger.printSummary('reviewers', [
{ name: 'arch-review', condition: 'approved' },
]);
// No task prefix should appear
for (const line of output) {
expect(line).not.toContain('[over]');
}
// Summary content is present
const fullOutput = output.join('');
expect(fullOutput).toContain('reviewers results');
expect(fullOutput).toContain('arch-review:');
expect(fullOutput).toContain('approved');
});
it('should flush remaining buffers before printing summary', () => {
const logger = new ParallelLogger({
subMovementNames: ['step-a'],

View File

@ -189,6 +189,19 @@ export class ParallelLogger {
}
}
/**
* Build the prefix string for summary lines (no sub-movement name).
* Returns empty string in non-rich mode (no task-level prefix needed).
*/
private buildSummaryPrefix(): string {
if (this.taskLabel && this.parentMovementName && this.progressInfo && this.movementIteration != null && this.taskColorIndex != null) {
const taskColor = COLORS[this.taskColorIndex % COLORS.length];
const { iteration, maxMovements } = this.progressInfo;
return `${taskColor}[${this.taskLabel}]${RESET}[${this.parentMovementName}](${iteration}/${maxMovements})(${this.movementIteration}) `;
}
return '';
}
/**
* Flush remaining line buffers for all sub-movements.
* Call after all sub-movements complete to output any trailing partial lines.
@ -243,10 +256,11 @@ export class ParallelLogger {
const headerLine = `${'─'.repeat(sideWidth)}${headerText}${'─'.repeat(sideWidth)}`;
const footerLine = '─'.repeat(headerLine.length);
this.writeFn(`${headerLine}\n`);
const summaryPrefix = this.buildSummaryPrefix();
this.writeFn(`${summaryPrefix}${headerLine}\n`);
for (const line of resultLines) {
this.writeFn(`${line}\n`);
this.writeFn(`${summaryPrefix}${line}\n`);
}
this.writeFn(`${footerLine}\n`);
this.writeFn(`${summaryPrefix}${footerLine}\n`);
}
}