Skip to content

feat(tui): enhance FocusedAgent panel with visual agent avatars, braille progress, sparkline graph, and status icons #505

@JeremyDev87

Description

@JeremyDev87

Problem

The FocusedAgent panel uses plain text/log-style rendering for agent activity. Status is shown with minimal single-character icons (●○⏸!✓), progress bar uses simple block characters (█░), and there are no graphical elements to visualize activity patterns.

Proposed Enhancements

Enhancement 1: Role-based emoji avatars

Replace single-character status icons in the agent header with role-based emoji avatars.

In apps/mcp-server/src/tui/utils/theme.ts:

/** Maps agent role/name keywords to emoji avatars for visual identification */
export const AGENT_AVATARS: Record<string, string> = {
  'solution-architect': '🏛️',
  'architect': '🏗️',
  'frontend': '🎨',
  'backend': '⚙️',
  'security': '🔒',
  'test': '🧪',
  'performance': '⚡',
  'code-quality': '📏',
  'devops': '🚀',
  'documentation': '📝',
  'accessibility': '♿',
  'seo': '🔍',
  'observability': '📊',
  'migration': '🔄',
  'integration': '🔗',
  'event-architecture': '📨',
  'mobile': '📱',
  'data': '🗄️',
  'ui-ux': '🎯',
  'i18n': '🌐',
  'plan-mode': '📋',
  'act-mode': '🔨',
  'eval-mode': '🔬',
  'auto-mode': '🤖',
};

/** Resolve avatar for an agent by matching name keywords */
export function getAgentAvatar(agentName: string): string {
  const lower = agentName.toLowerCase();
  for (const [keyword, avatar] of Object.entries(AGENT_AVATARS)) {
    if (lower.includes(keyword)) return avatar;
  }
  return '🤖'; // default
}

Before: ● solution-architect RUNNING PLAN [45%]
After: 🏛️ solution-architect ● RUNNING PLAN [45%]

Enhancement 2: Braille progress bar with inline percentage

Replace the simple █░ progress bar with higher-resolution braille characters.

In apps/mcp-server/src/tui/components/focused-agent.pure.ts:

/**
 * Enhanced progress bar using braille characters for finer granularity.
 * Each braille char represents a smaller increment than block chars.
 */
export function formatEnhancedProgressBar(
  progress: number,
  width: number = 30,
): { bar: string; label: string } {
  const clamped = Math.max(0, Math.min(100, progress));
  const filledCount = Math.round((clamped / 100) * width);
  const emptyCount = width - filledCount;
  return {
    bar: '⣿'.repeat(filledCount) + '░'.repeat(emptyCount),
    label: `${clamped}%`,
  };
}

Before: ████████████████░░░░░░░░░░░░░░░░░░░░░░░░
After: ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿░░░░░░░░░░░░░░░░░░ 45%

Enhancement 3: Activity sparkline graph

Add a sparkline visualization showing tool call frequency over time.

In apps/mcp-server/src/tui/components/focused-agent.pure.ts:

const SPARK_CHARS = '▁▂▃▄▅▆▇█';

/**
 * Generate a sparkline showing tool call frequency over the last N seconds.
 * Each character represents one time bucket; height = relative call count.
 */
export function formatActivitySparkline(
  toolCalls: Array<{ timestamp: number }>,
  bucketCount: number = 20,
  windowMs: number = 60_000,
  now?: number,
): string {
  const currentTime = now ?? Date.now();
  const bucketSize = windowMs / bucketCount;
  const buckets = new Array(bucketCount).fill(0);

  for (const call of toolCalls) {
    const age = currentTime - call.timestamp;
    if (age < 0 || age > windowMs) continue;
    const idx = Math.min(bucketCount - 1, Math.floor(age / bucketSize));
    buckets[bucketCount - 1 - idx]++;
  }

  const max = Math.max(1, ...buckets);
  return buckets
    .map(b => SPARK_CHARS[Math.round((b / max) * (SPARK_CHARS.length - 1))])
    .join('');
}

Display in FocusedAgentPanel:

─── Activity ─────────────────────────
▁▁▂▃▅▇█▇▅▃▂▁▁▁▂▃▅▇█▇

Enhancement 4: Enhanced checklist icons

Replace plain [x]/[ ] with visual status icons.

In apps/mcp-server/src/tui/components/focused-agent.pure.ts:

export function formatEnhancedChecklist(tasks: TaskItem[], maxItems = 6): string {
  const visible = tasks.slice(0, maxItems);
  const lines = visible.map(t => {
    if (t.completed) return `  ✔ ${t.subject}`;   // green checkmark
    return `  ◻ ${t.subject}`;                     // empty box
  });
  if (tasks.length > maxItems) {
    lines.push(`  ⋯ (+${tasks.length - maxItems} more)`);
  }
  return lines.join('\n');
}

Before:

[x] Apply systematic-debugging
[ ] Apply test-driven-development

After:

  ✔ Apply systematic-debugging          (green)
  ◻ Apply test-driven-development       (dim)

Enhancement 5: Animated status spinner (optional, if Ink supports re-render)

export const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'] as const;

This requires a timer-based re-render which may or may not be feasible with current Ink setup. If the dashboard already re-renders on state changes frequently enough, a frame counter based on render count could work instead of a timer.

Files to Modify

File Change
apps/mcp-server/src/tui/utils/theme.ts Add AGENT_AVATARS, getAgentAvatar()
apps/mcp-server/src/tui/utils/theme.spec.ts Tests for avatar resolution
apps/mcp-server/src/tui/components/focused-agent.pure.ts Add formatEnhancedProgressBar, formatActivitySparkline, formatEnhancedChecklist
apps/mcp-server/src/tui/components/focused-agent.pure.spec.ts Tests for new formatters
apps/mcp-server/src/tui/components/FocusedAgentPanel.tsx Wire up new formatters + avatar
apps/mcp-server/src/tui/dashboard-app.tsx Pass toolCalls to FocusedAgentPanel for sparkline

Test Plan

yarn workspace codingbuddy test -- --testPathPattern="focused-agent|theme"

Avatar tests:

  1. getAgentAvatar('solution-architect')'🏛️'
  2. getAgentAvatar('frontend-developer')'🎨'
  3. getAgentAvatar('unknown-agent')'🤖' (default)
  4. Case-insensitive matching

Progress bar tests:

  1. formatEnhancedProgressBar(0, 20){ bar: '░'.repeat(20), label: '0%' }
  2. formatEnhancedProgressBar(50, 20) → 10 + 10 , label '50%'
  3. formatEnhancedProgressBar(100, 20) → 20 , label '100%'

Sparkline tests:

  1. Empty calls → all (minimum height)
  2. Even distribution → all same height
  3. Single spike → one , rest
  4. Respects windowMs boundary (ignores older calls)

Checklist tests:

  1. Completed task → prefix
  2. Incomplete task → prefix
  3. Overflow → ⋯ (+N more) suffix

Acceptance Criteria

  • Agent header shows role-based emoji avatar
  • Progress bar uses braille characters with inline % label
  • Activity sparkline shows tool call frequency pattern
  • Checklist uses / icons with color coding
  • Default avatar 🤖 for unrecognized agents
  • All pure formatting functions are tested
  • No visual regression in narrow/medium layout modes

Metadata

Metadata

Assignees

Labels

featpriority:couldCould Have - 있으면 좋은 기능tuiTUI Agent Monitor

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions