mirror of
https://github.com/jarrodwatts/claude-hud.git
synced 2026-04-20 01:32:38 +00:00
Refactor agent rendering and status icon logic
MAX_RECENT_COMPLETED and MAX_AGENTS_SHOWN constants at the top Dedup seen set in renderAgentsLine getStatusIcon() extracted with failed case handled Math.max(0, ...) guard in formatElapsed Hour-aware branch at the bottom of formatElapsed
This commit is contained in:
committed by
GitHub
parent
30e1dfe46a
commit
3790411344
@@ -1,6 +1,9 @@
|
||||
import type { RenderContext, AgentEntry } from '../types.js';
|
||||
import { yellow, green, magenta, label } from './colors.js';
|
||||
|
||||
const MAX_RECENT_COMPLETED = 2;
|
||||
const MAX_AGENTS_SHOWN = 3;
|
||||
|
||||
export function renderAgentsLine(ctx: RenderContext): string | null {
|
||||
const { agents } = ctx.transcript;
|
||||
const colors = ctx.config?.colors;
|
||||
@@ -8,28 +11,53 @@ export function renderAgentsLine(ctx: RenderContext): string | null {
|
||||
const runningAgents = agents.filter((a) => a.status === 'running');
|
||||
const recentCompleted = agents
|
||||
.filter((a) => a.status === 'completed')
|
||||
.slice(-2);
|
||||
.slice(-MAX_RECENT_COMPLETED);
|
||||
|
||||
const toShow = [...runningAgents, ...recentCompleted].slice(-3);
|
||||
const seen = new Set<string>();
|
||||
const toShow = [...runningAgents, ...recentCompleted]
|
||||
.filter((a) => {
|
||||
if (seen.has(a.id)) return false;
|
||||
seen.add(a.id);
|
||||
return true;
|
||||
})
|
||||
.slice(-MAX_AGENTS_SHOWN);
|
||||
|
||||
if (toShow.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const lines: string[] = [];
|
||||
|
||||
for (const agent of toShow) {
|
||||
lines.push(formatAgent(agent, colors));
|
||||
}
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
function formatAgent(agent: AgentEntry, colors?: RenderContext['config']['colors']): string {
|
||||
const statusIcon = agent.status === 'running' ? yellow('◐') : green('✓');
|
||||
function getStatusIcon(
|
||||
status: AgentEntry['status'],
|
||||
colors?: RenderContext['config']['colors']
|
||||
): string {
|
||||
switch (status) {
|
||||
case 'running':
|
||||
return yellow('◐');
|
||||
case 'failed':
|
||||
return label('✗', colors);
|
||||
case 'completed':
|
||||
default:
|
||||
return green('✓');
|
||||
}
|
||||
}
|
||||
|
||||
function formatAgent(
|
||||
agent: AgentEntry,
|
||||
colors?: RenderContext['config']['colors']
|
||||
): string {
|
||||
const statusIcon = getStatusIcon(agent.status, colors);
|
||||
const type = magenta(agent.type);
|
||||
const model = agent.model ? label(`[${agent.model}]`, colors) : '';
|
||||
const desc = agent.description ? label(`: ${truncateDesc(agent.description)}`, colors) : '';
|
||||
const desc = agent.description
|
||||
? label(`: ${truncateDesc(agent.description)}`, colors)
|
||||
: '';
|
||||
const elapsed = formatElapsed(agent);
|
||||
|
||||
return `${statusIcon} ${type}${model ? ` ${model}` : ''}${desc} ${label(`(${elapsed})`, colors)}`;
|
||||
@@ -44,12 +72,18 @@ function formatElapsed(agent: AgentEntry): string {
|
||||
const now = Date.now();
|
||||
const start = agent.startTime.getTime();
|
||||
const end = agent.endTime?.getTime() ?? now;
|
||||
const ms = end - start;
|
||||
const ms = Math.max(0, end - start);
|
||||
|
||||
if (ms < 1000) return '<1s';
|
||||
if (ms < 60000) return `${Math.round(ms / 1000)}s`;
|
||||
if (ms < 60_000) return `${Math.round(ms / 1000)}s`;
|
||||
|
||||
const mins = Math.floor(ms / 60000);
|
||||
const secs = Math.round((ms % 60000) / 1000);
|
||||
return `${mins}m ${secs}s`;
|
||||
const totalSecs = Math.floor(ms / 1000);
|
||||
const mins = Math.floor(totalSecs / 60);
|
||||
const secs = totalSecs % 60;
|
||||
|
||||
if (mins < 60) return `${mins}m ${secs}s`;
|
||||
|
||||
const hours = Math.floor(mins / 60);
|
||||
const remainingMins = mins % 60;
|
||||
return `${hours}h ${remainingMins}m`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user