Files
claude-hud/CONTRIBUTING.md
Jarrod Watts c8d235ead9 docs: Comprehensive CONTRIBUTING guide with architecture docs
Phase 5 of v2 upgrade:
- Add detailed architecture overview with data flow diagram
- Document key components (EventReader, ContextTracker, CostTracker)
- Add guide for adding new panels
- Add guide for adding new hooks
- Include PR checklist and code style guidelines
- List contribution areas (features, improvements, testing, docs)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 15:20:57 +11:00

5.9 KiB

Contributing to Claude HUD

Thanks for your interest in contributing! This guide will help you get started.

Development Setup

# Clone the repo
git clone https://github.com/jarrodwatts/claude-hud
cd claude-hud

# Install TUI dependencies
cd tui
bun install

# Build
bun run build

# Run tests
bun test

Local Testing

To test the plugin locally without publishing:

# Create a symlink to your plugins directory
ln -sf $(pwd)/.. ~/.claude/plugins/claude-hud

# Verify installation
./scripts/verify-install.sh

# Start Claude with the plugin
claude --plugin-dir /path/to/claude-hud

Project Structure

claude-hud/
├── .claude-plugin/
│   └── plugin.json           # Plugin manifest (name, version, hooks path)
├── hooks/
│   └── hooks.json            # Hook event subscriptions
├── scripts/
│   ├── session-start.sh      # Spawns HUD in split pane
│   ├── capture-event.sh      # Captures events and sends to FIFO
│   ├── cleanup.sh            # Cleans up on session end
│   └── verify-install.sh     # Installation verification
├── tui/
│   ├── src/
│   │   ├── index.tsx         # Main app, state management, event processing
│   │   ├── components/       # React/Ink UI components
│   │   │   ├── ContextMeter.tsx   # Token usage display
│   │   │   ├── ToolStream.tsx     # Tool activity list
│   │   │   ├── AgentList.tsx      # Subagent tracking
│   │   │   ├── SessionStats.tsx   # Session statistics
│   │   │   ├── TodoList.tsx       # Task tracking
│   │   │   ├── ModifiedFiles.tsx  # Changed files
│   │   │   ├── McpStatus.tsx      # MCP server status
│   │   │   ├── Sparkline.tsx      # Sparkline visualization
│   │   │   └── ErrorBoundary.tsx  # Error handling
│   │   └── lib/
│   │       ├── types.ts           # TypeScript interfaces
│   │       ├── event-reader.ts    # FIFO reader with reconnection
│   │       ├── context-tracker.ts # Token estimation and tracking
│   │       └── cost-tracker.ts    # Cost estimation
│   ├── package.json
│   ├── tsconfig.json
│   └── vitest.config.ts
├── README.md
├── CONTRIBUTING.md
├── TROUBLESHOOTING.md
└── LICENSE

Architecture

Data Flow

Claude Code → Hook Events → capture-event.sh → FIFO → EventReader → React State → UI
  1. Claude Code emits hook events (PreToolUse, PostToolUse, etc.)
  2. capture-event.sh receives events and formats them as JSON
  3. Events are written to a named pipe (FIFO)
  4. EventReader reads the FIFO and emits events
  5. React components update based on state changes

Key Components

EventReader (lib/event-reader.ts)

  • Reads from named pipe (FIFO)
  • Handles reconnection with exponential backoff
  • Emits 'event' and 'status' events

ContextTracker (lib/context-tracker.ts)

  • Estimates tokens from event payloads
  • Tracks burn rate over time
  • Maintains token history for sparkline

CostTracker (lib/cost-tracker.ts)

  • Calculates cost based on token usage
  • Supports different model pricing

Adding a New Panel

  1. Create a component in tui/src/components/:
import React from 'react';
import { Box, Text } from 'ink';

interface Props {
  data: YourDataType;
}

export function YourPanel({ data }: Props) {
  return (
    <Box flexDirection="column" marginBottom={1}>
      <Box>
        <Text bold color="white">Your Panel</Text>
      </Box>
      {/* Panel content */}
    </Box>
  );
}
  1. Add state in index.tsx:
const [yourData, setYourData] = useState<YourDataType>(initialValue);
  1. Process relevant events in processEvent:
if (event.event === 'RelevantEvent') {
  setYourData(/* updated data */);
}
  1. Add the component to the render tree (wrapped in ErrorBoundary).

Adding a New Hook

  1. Add the hook to hooks/hooks.json:
"NewHookEvent": [
  {
    "hooks": [
      {
        "type": "command",
        "command": "${CLAUDE_PLUGIN_ROOT}/scripts/capture-event.sh",
        "timeout": 5
      }
    ]
  }
]
  1. Update HudEvent type in types.ts if new fields are needed.

  2. Handle the event in processEvent in index.tsx.

Running Tests

cd tui

# Run all tests
bun test

# Run tests in watch mode
bun test:watch

# Run specific test file
bun test context-tracker

Code Style

  • TypeScript strict mode - No implicit any
  • React functional components - Use hooks, not classes
  • No any types - Use unknown or proper types
  • Ink components - Use Box, Text from ink for UI
  • Error boundaries - Wrap components to prevent crashes

Pull Requests

  1. Fork the repo
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Make your changes
  4. Add tests for new functionality
  5. Run tests: bun test
  6. Build: bun run build
  7. Commit with descriptive message
  8. Submit PR

PR Checklist

  • Tests added/updated
  • TypeScript compiles without errors
  • No console.log statements in production code
  • Documentation updated if needed
  • Tested locally with Claude Code

Areas for Contribution

Features

  • Real token counting from transcript files
  • More MCP server information
  • Git branch/status display
  • Custom themes
  • Configuration file support

Improvements

  • More terminal support
  • Better error messages
  • Performance optimization
  • Accessibility improvements

Testing

  • More component tests
  • Integration tests
  • Performance benchmarks

Documentation

  • Video tutorials
  • Architecture diagrams
  • API documentation

Getting Help

  • Open an issue for bugs or feature requests
  • Check existing issues before creating new ones
  • Join discussions in PRs

License

By contributing, you agree that your contributions will be licensed under the MIT License.