Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Build heads-up display (HUD) dashboards for AI coding agents — show context usage, active tools, running sub-agents, and task progress in real-time. Use when: monitoring AI agent activity, building developer tools for AI-assisted coding, creating status dashboards for agent workflows.
.claude/skills/terminalskills-claude-hud/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 63% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 104% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 92% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 45% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 163% | 0% |
Build heads-up display dashboards that monitor AI coding agents in real-time. Track context window consumption, active tool calls, sub-agent status, task progress, and cost — all rendered in a terminal UI or web interface. Inspired by claude-hud (13k+ stars).
| Component | What It Shows | Data Source | |-----------|---------------|-------------| | Context meter | Tokens used / remaining | Agent API response headers | | Tool tracker | Active tool calls + history | Hook into tool execution | | Sub-agent panel | Spawned agents + status | Agent orchestration layer | | Task progress | Todo items + completion | Parse agent task lists | | Cost tracker | $ spent this session | Token count x model pricing |
bashmkdir ai-hud && cd ai-hud npm init -y npm install blessed blessed-contrib chalk ws
javascript// context-monitor.js class ContextMonitor { constructor(maxTokens = 200000) { this.maxTokens = maxTokens; this.inputTokens = 0; this.outputTokens = 0; this.cacheHits = 0; } update(apiResponse) { const usage = apiResponse.usage || {}; this.inputTokens = usage.input_tokens || 0; this.outputTokens = usage.output_tokens || 0; this.cacheHits = usage.cache_read_input_tokens || 0; return this.getStatus(); } getStatus() { const total = this.inputTokens + this.outputTokens; const pct = ((total / this.maxTokens) * 100).toFixed(1); return { used: total, remaining: this.maxTokens - total, percentage: parseFloat(pct), cached: this.cacheHits, warning: parseFloat(pct) > 80 ? 'HIGH' : 'OK' }; } }
javascript// tool-tracker.js class ToolTracker { constructor() { this.active = []; this.history = []; this.counts = {}; } onToolStart(toolName, input) { const call = { id: Date.now(), tool: toolName, input: JSON.stringify(input).slice(0, 100), startedAt: new Date(), status: 'running' }; this.active.push(call); this.counts[toolName] = (this.counts[toolName] || 0) + 1; return call; } onToolEnd(callId, output) { const idx = this.active.findIndex(c => c.id === callId); if (idx !== -1) { const call = this.active.splice(idx, 1)[0]; call.status = 'done'; call.duration = Date.now() - call.startedAt; call.output = String(output).slice(0, 80); this.history.unshift(call); if (this.history.length > 50) this.history.pop(); } } getTopTools(n = 5) { return Object.entries(this.counts).sort((a, b) => b[1] - a[1]).slice(0, n); } }
javascript// dashboard.js const blessed = require('blessed'); const contrib = require('blessed-contrib'); const screen = blessed.screen({ smartCSR: true, title: 'AI Agent HUD' }); const grid = new contrib.grid({ rows: 12, cols: 12, screen }); const contextGauge = grid.set(0, 0, 3, 4, contrib.gauge, { label: ' Context Usage ', stroke: 'green', fill: 'white' }); const toolLog = grid.set(0, 4, 6, 8, contrib.log, { label: ' Tool Calls ', fg: 'green', selectedFg: 'green' }); const taskBar = grid.set(3, 0, 3, 4, contrib.bar, { label: ' Tasks ', barWidth: 6, maxHeight: 10 }); const costLine = grid.set(6, 0, 6, 6, contrib.line, { label: ' Cost ($) ', showLegend: true, minY: 0 }); const agentTable = grid.set(6, 6, 6, 6, contrib.table, { label: ' Sub-Agents ', keys: true, columnWidth: [20, 10, 15] }); function refresh(state) { contextGauge.setPercent(state.context.percentage); state.tools.active.forEach(t => toolLog.log(`> ${t.tool} - ${t.input}`)); screen.render(); } screen.key(['escape', 'q', 'C-c'], () => process.exit(0)); screen.render();
javascript// server.js const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8765 }); wss.on('connection', (ws) => { console.log('HUD client connected'); ws.on('message', (data) => { const event = JSON.parse(data); switch (event.type) { case 'context_update': contextMonitor.update(event.data); break; case 'tool_start': toolTracker.onToolStart(event.tool, event.input); break; case 'tool_end': toolTracker.onToolEnd(event.id, event.output); break; case 'task_update': taskTracker.update(event.tasks); break; } broadcastState(); }); });
javascriptconst PRICING = { 'claude-sonnet-4-20250514': { input: 3.0, output: 15.0 }, 'claude-opus-4-20250514': { input: 15.0, output: 75.0 }, 'gpt-4o': { input: 2.5, output: 10.0 }, }; function calculateCost(model, inputTokens, outputTokens) { const p = PRICING[model] || PRICING['claude-sonnet-4-20250514']; return ((inputTokens * p.input + outputTokens * p.output) / 1_000_000).toFixed(4); }
A developer launches the HUD while Claude Code refactors a large codebase:
javascriptconst monitor = new ContextMonitor(200000); // Claude Sonnet 200k context const tracker = new ToolTracker(); // Simulated events from a real refactoring session monitor.update({ usage: { input_tokens: 45200, output_tokens: 12800, cache_read_input_tokens: 31000 } }); console.log(monitor.getStatus()); // { used: 58000, remaining: 142000, percentage: 29.0, cached: 31000, warning: 'OK' } tracker.onToolStart('Read', { file_path: '/src/components/Dashboard.tsx' }); tracker.onToolStart('Grep', { pattern: 'useState', path: '/src' }); tracker.onToolEnd(tracker.active[0].id, '245 lines read'); console.log(tracker.getTopTools()); // [['Read', 12], ['Grep', 8], ['Edit', 6], ['Bash', 3]] // Dashboard shows: context at 29%, 2 active tools, $0.0234 session cost
A team runs 3 agents in parallel and monitors all of them on one HUD:
javascriptconst agents = { 'agent-1-backend': new ContextMonitor(200000), 'agent-2-frontend': new ContextMonitor(200000), 'agent-3-tests': new ContextMonitor(200000), }; // Agent 1: refactoring API routes — 67% context used agents['agent-1-backend'].update({ usage: { input_tokens: 98000, output_tokens: 36000 } }); // Agent 2: building React components — 23% context used agents['agent-2-frontend'].update({ usage: { input_tokens: 32000, output_tokens: 14000 } }); // Agent 3: writing test suites — 45% context used agents['agent-3-tests'].update({ usage: { input_tokens: 61000, output_tokens: 29000 } }); // Dashboard renders 3 gauges side-by-side: // [agent-1: 67% HIGH] [agent-2: 23% OK] [agent-3: 45% OK] // Total session cost: $0.0234 + $0.0108 + $0.0179 = $0.0521
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 20,686 | 12,697 | -39% | 1 | 1 | 0% | 4,523 | 5,365 | +19% | 0 | 0 | — |
case-02 | fail→fail | 15,863 | 13,165 | -17% | 1 | 1 | 0% | 3,607 | 5,280 | +46% | 0 | 0 | — |
case-03 | fail→pass | 23,983 | 26,896 | +12% | 1 | 1 | 0% | 5,373 | 8,752 | +63% | 0 | 0 | — |
case-04 | pass→pass | 8,603 | 7,804 | -9% | 1 | 1 | 0% | 2,043 | 4,026 | +97% | 0 | 0 | — |
case-05 | pass→pass | 14,080 | 14,804 | +5% | 1 | 1 | 0% | 2,396 | 5,064 | +111% | 0 | 0 | — |
case-06 | pass→pass | 15,849 | 10,583 | -33% | 1 | 1 | 0% | 2,972 | 4,578 | +54% | 0 | 0 | — |
case-07 | fail→pass | 8,551 | 2,657 | -69% | 1 | 1 | 0% | 1,479 | 3,019 | +104% | 0 | 0 | — |
case-08 | pass→pass | 7,984 | 2,688 | -66% | 1 | 1 | 0% | 1,271 | 2,900 | +128% | 0 | 0 | — |
case-09 | fail→fail | 15,309 | 12,375 | -19% | 1 | 1 | 0% | 2,688 | 4,977 | +85% | 0 | 0 | — |
case-10 | fail→pass | 10,974 | 5,152 | -53% | 1 | 1 | 0% | 1,718 | 3,307 | +92% | 0 | 0 | — |
case-11 | pass→pass | 9,364 | 3,505 | -63% | 1 | 1 | 0% | 1,912 | 3,139 | +64% | 0 | 0 | — |
case-12 | pass→pass | 6,936 | 5,128 | -26% | 1 | 1 | 0% | 1,674 | 3,584 | +114% | 0 | 0 | — |
case-13 | fail→pass | 10,927 | 2,139 | -80% | 1 | 1 | 0% | 1,989 | 2,881 | +45% | 0 | 0 | — |
case-14 | fail→pass | 6,484 | 3,131 | -52% | 1 | 1 | 0% | 1,057 | 2,782 | +163% | 0 | 0 | — |
case-15 | fail→pass | 10,103 | 3,619 | -64% | 1 | 1 | 0% | 1,923 | 3,067 | +59% | 0 | 0 | — |
case-16 | pass→pass | 5,672 | 1,775 | -69% | 1 | 1 | 0% | 939 | 2,778 | +196% | 0 | 0 | — |
case-17 | pass→pass | 9,020 | 2,919 | -68% | 1 | 1 | 0% | 1,550 | 3,031 | +96% | 0 | 0 | — |
case-18 | fail→pass | 12,983 | 3,468 | -73% | 1 | 1 | 0% | 1,594 | 2,992 | +88% | 0 | 0 | — |
case-19 | pass→pass | 9,526 | 2,206 | -77% | 1 | 1 | 0% | 1,479 | 2,837 | +92% | 0 | 0 | — |
case-20 | fail→pass | 18,949 | 22,465 | +19% | 1 | 1 | 0% | 3,348 | 7,312 | +118% | 0 | 0 | — |
case-21 | pass→pass | 6,077 | 3,949 | -35% | 1 | 1 | 0% | 1,069 | 3,061 | +186% | 0 | 0 | — |
case-22 | pass→pass | 14,434 | 10,063 | -30% | 1 | 1 | 0% | 2,383 | 4,251 | +78% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +36 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.