diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml deleted file mode 100644 index 348a302..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Bug report -description: Something isn't working as expected -title: "bug: " -labels: ["bug"] -body: - - type: markdown - attributes: - value: | - Thanks for the report! Please include as much detail as you can. - - type: textarea - id: summary - attributes: - label: Summary - description: What happened? - placeholder: The HUD doesn't appear when I start Claude Code... - validations: - required: true - - type: textarea - id: steps - attributes: - label: Steps to reproduce - description: Provide clear, numbered steps. - placeholder: | - 1. Run `claude` - 2. Start a session - 3. Observe... - validations: - required: true - - type: textarea - id: expected - attributes: - label: Expected behavior - validations: - required: true - - type: textarea - id: actual - attributes: - label: Actual behavior - validations: - required: true - - type: textarea - id: logs - attributes: - label: Logs - description: Paste relevant output (use `CLAUDE_HUD_DEBUG=1` and `claude --debug hooks`). - render: shell - - type: input - id: claude_version - attributes: - label: Claude Code version - placeholder: Output of `claude --version` - - type: input - id: terminal - attributes: - label: Terminal - placeholder: iTerm2 / tmux / Kitty / WezTerm / Zellij / Windows Terminal - - type: input - id: os - attributes: - label: OS - placeholder: macOS 14 / Ubuntu 22.04 / Windows 11 WSL diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 0e882f0..0000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,8 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Troubleshooting guide - url: https://github.com/jarrodwatts/claude-hud/blob/main/TROUBLESHOOTING.md - about: Start here for common setup issues and fixes. - - name: Documentation - url: https://github.com/jarrodwatts/claude-hud#docs - about: Read the docs and developer guide. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml deleted file mode 100644 index e4ca9ac..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Feature request -description: Suggest an improvement or new feature -title: "feat: " -labels: ["enhancement"] -body: - - type: markdown - attributes: - value: | - Share your idea. Concrete use cases help a lot. - - type: textarea - id: problem - attributes: - label: Problem - description: What problem are you trying to solve? - validations: - required: true - - type: textarea - id: solution - attributes: - label: Proposed solution - description: What would you like to see added or changed? - validations: - required: true - - type: textarea - id: alternatives - attributes: - label: Alternatives considered - - type: textarea - id: context - attributes: - label: Additional context diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 46bb072..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,19 +0,0 @@ -## Summary - -Describe the change and its intent. - -## Testing - -- [ ] `bun run lint` (tui) -- [ ] `bun run typecheck` (tui) -- [ ] `bun test` (tui) - -## Screenshots / TUI Capture - -If this changes the HUD UI, include a screenshot or recording. - -## Checklist - -- [ ] Updated docs or help text if needed -- [ ] Added/updated tests for new behavior -- [ ] No new lint or type errors diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 12eb883..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,87 +0,0 @@ -name: CI - -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest] - bun: [latest, 1.1.30] - - steps: - - uses: actions/checkout@v4 - - - uses: oven-sh/setup-bun@v2 - with: - bun-version: ${{ matrix.bun }} - - - name: Install dependencies - working-directory: tui - run: bun install --frozen-lockfile - - - name: Lint - working-directory: tui - run: bun run lint - - - name: Type check - working-directory: tui - run: bun run typecheck - - - name: Test - working-directory: tui - run: bun test - - - name: Snapshot guard - run: git diff --exit-code - - - name: Build - working-directory: tui - run: bun run build - - validate-plugin: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Check plugin.json exists - run: test -f .claude-plugin/plugin.json - - - name: Check hooks.json exists - run: test -f hooks/hooks.json - - - name: Check scripts are executable - run: | - test -x scripts/session-start.sh - test -x scripts/capture-event.sh - test -x scripts/cleanup.sh - - - name: Validate JSON files - run: | - jq . .claude-plugin/plugin.json > /dev/null - jq . hooks/hooks.json > /dev/null - - audit: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest - - - name: Install dependencies - working-directory: tui - run: bun install --frozen-lockfile - - - name: Dependency audit - working-directory: tui - run: bun run audit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 2ff9c8e..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Release - -on: - push: - tags: - - 'v*.*.*' - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest - - - name: Install dependencies - working-directory: tui - run: bun install --frozen-lockfile - - - name: Build TUI - working-directory: tui - run: bun run build - - - name: Package artifact - run: tar -czf claude-hud-tui.tar.gz tui/dist tui/package.json - - - name: Release artifact - uses: softprops/action-gh-release@v2 - with: - files: claude-hud-tui.tar.gz diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 51b9f44..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,41 +0,0 @@ -# Repository Guidelines - -## Project Structure & Module Organization -- `tui/` houses the TypeScript/React Ink HUD app. - - `tui/src/components/` for UI panels (e.g., `ContextMeter.tsx`). - - `tui/src/hooks/` for shared state hooks (e.g., `useHudState.ts`). - - `tui/src/lib/` for core logic (event reader, tracking, types). -- `scripts/` contains shell entrypoints used by Claude hooks. -- `hooks/` defines event subscriptions (`hooks.json`). -- `docs/` stores changelog, ADRs, and research notes. - -## Build, Test, and Development Commands -Run commands from `tui/` unless noted. -- `bun install` installs dependencies. -- `bun run build` compiles TypeScript to `tui/dist/`. -- `bun run dev` watches TypeScript for local development. -- `bun run start` runs the built HUD (`dist/index.js`). -- `bun test` runs the Vitest suite; `bun test ` targets a file. -- `bun run lint` runs ESLint; `bun run format` runs Prettier. -- Root `scripts/verify-install.sh` checks plugin installation. - -## Coding Style & Naming Conventions -- TypeScript strict mode; avoid `any` (use `unknown` or real types). -- React functional components with hooks; wrap panels in `React.memo`. -- Tests live alongside code and use `*.test.ts`/`*.test.tsx`. -- Formatting via Prettier, linting via ESLint flat config (`tui/eslint.config.js`). - -## Testing Guidelines -- Frameworks: Vitest + @testing-library/react + ink-testing-library. -- Prefer focused component/unit tests under `tui/src/`. -- Run all tests with `bun test`; use `bun test --coverage` for coverage. - -## Commit & Pull Request Guidelines -- Commit messages follow `type: summary` (examples: `docs: ...`, `refactor: ...`). -- PRs should include a clear description, tests for new behavior, and any UI - screenshots for visual changes in the TUI. -- Before opening a PR: run `bun run lint`, `bun run typecheck`, and `bun test`. - -## Security & Configuration Tips -- Runtime FIFOs and logs live under `~/.claude/hud/` (sessions, pids, logs). -- Hook scripts rely on `jq`; ensure it is available in local dev. diff --git a/CLAUDE.md b/CLAUDE.md index a0b2d1d..bfb44fb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,29 +1,19 @@ # CLAUDE.md -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +This file provides guidance to Claude Code when working with this repository. ## Project Overview -Claude HUD is a Claude Code plugin that displays a real-time terminal HUD (Heads-Up Display) in a split pane. It shows context usage, tool activity, agent status, todos, git status, and cost estimation. +Claude HUD is a Claude Code plugin that displays a real-time multi-line statusline. It shows context health, tool activity, agent status, and todo progress. ## Build Commands ```bash -# All commands run from tui/ directory -cd tui - bun install # Install dependencies -bun run build # Build TypeScript -bun run dev # Watch mode for development -bun test # Run all tests -bun test # Run specific test (e.g., bun test sparkline) - bun run replay:events -- --input ../tui/test-fixtures/hud-events.jsonl # Replay events - bun run profile:events -- ../tui/test-fixtures/hud-events-stress.jsonl # Profile throughput +bun run build # Build TypeScript to dist/ -# Manual testing with a FIFO -mkfifo /tmp/test.fifo -bun run start -- --session test --fifo /tmp/test.fifo -# Then in another terminal, send test events to the FIFO +# Test with sample stdin data +echo '{"model":{"display_name":"Opus"},"context_window":{"current_usage":{"input_tokens":45000},"context_window_size":200000}}' | node dist/index.js ``` ## Architecture @@ -31,82 +21,91 @@ bun run start -- --session test --fifo /tmp/test.fifo ### Data Flow ``` -Claude Code Hooks → capture-event.sh → FIFO → EventReader → React State → Ink Components +Claude Code → stdin JSON → parse → render lines → stdout → Claude Code displays + ↘ transcript_path → parse JSONL → tools/agents/todos ``` -1. **hooks/hooks.json** - Registers shell scripts for Claude Code lifecycle events -2. **scripts/capture-event.sh** - Transforms hook JSON into HudEvent format, writes to session FIFO -3. **scripts/session-start.sh** - Creates FIFO, builds TUI if needed, spawns HUD in terminal split -4. **tui/src/lib/event-reader.ts** - Reads FIFO line-by-line, parses JSON, emits events with auto-reconnect -5. **tui/src/index.tsx** - Main App component, processes events and manages all state +**Key insight**: The statusline is invoked every ~300ms by Claude Code. Each invocation: +1. Receives JSON via stdin (model, context, tokens - native accurate data) +2. Parses the transcript JSONL file for tools, agents, and todos +3. Renders multi-line output to stdout +4. Claude Code displays all lines -### Hook Events +### Data Sources -| Event | Script | Purpose | -|-------|--------|---------| -| SessionStart | session-start.sh | Spawns HUD in split pane | -| PreToolUse | capture-event.sh | Shows tool as "running" | -| PostToolUse | capture-event.sh | Updates tool completion, tracks context/cost | -| UserPromptSubmit | capture-event.sh | Tracks user prompts, clears idle state | -| Stop | capture-event.sh | Sets idle state | -| PreCompact | capture-event.sh | Increments compaction count | -| SubagentStop | capture-event.sh | Marks agent complete | -| SessionEnd | cleanup.sh | Kills process, removes FIFO | +**Native from stdin JSON** (accurate, no estimation): +- `model.display_name` - Current model +- `context_window.current_usage` - Token counts +- `context_window.context_window_size` - Max context +- `transcript_path` - Path to session transcript -All events sent to the FIFO include `schemaVersion: 1` (see `docs/API.md`). +**From transcript JSONL parsing**: +- `tool_use` blocks → tool name, input, start time +- `tool_result` blocks → completion, duration +- Running tools = `tool_use` without matching `tool_result` +- `TodoWrite` calls → todo list +- `Task` calls → agent info -### Library Structure (tui/src/lib/) +**From config files**: +- MCP count from `~/.claude/.mcp.json` +- Rules count from CLAUDE.md files -- **types.ts** - All TypeScript interfaces (HudEvent, ToolEntry, TodoItem, ContextHealth, etc.) -- **event-reader.ts** - FIFO reader with connection status and exponential backoff reconnect -- **context-tracker.ts** - Estimates token usage, burn rate, compaction warnings -- **cost-tracker.ts** - Calculates API costs based on model pricing +### File Structure -### Component Structure (tui/src/components/) +``` +src/ +├── index.ts # Entry point +├── stdin.ts # Parse Claude's JSON input +├── transcript.ts # Parse transcript JSONL +├── config-reader.ts # Read MCP/rules configs +├── types.ts # TypeScript interfaces +└── render/ + ├── index.ts # Main render coordinator + ├── session-line.ts # Line 1: model, context, rules, MCPs + ├── tools-line.ts # Line 2: tool activity + ├── agents-line.ts # Line 3: agent status + ├── todos-line.ts # Line 4: todo progress + └── colors.ts # ANSI color helpers +``` -- **ContextMeter** - Token usage bar, sparkline history, burn rate -- **ToolStream** - Live tool calls with status, duration, path truncation -- **AgentList** - Running/completed subagents with elapsed time -- **SessionStats** - Tool counts, lines changed, session duration -- **GitStatus** - Branch, staged/modified/untracked counts -- **TodoList** - Current task list from TodoWrite events -- **ModifiedFiles** - Files changed via Edit/Write -- **McpStatus** - Connected MCP servers -- **Sparkline** - Unicode sparkline chart (▁▂▃▄▅▆▇█) +### Output Format -### Session Files +``` +[Opus] ████████░░ 45% | 📋 3 rules | 🔌 5 MCPs | ⏱️ 12m +◐ Edit: auth.ts | ✓ Read ×3 | ✓ Grep ×2 +◐ explore [haiku]: Finding auth code (2m 15s) +▸ Fix authentication bug (2/5) +``` -Runtime files stored in `~/.claude/hud/`: -- `events/.fifo` - Named pipe for event streaming (session-scoped) -- `pids/.pid` - Process ID for cleanup (terminal-scoped) -- `refresh-.json` - Session state for HUD switching (terminal-scoped) -- `logs/.log` - Fallback output when split pane unavailable +Lines are conditionally shown: +- Line 1 (session): Always shown +- Line 2 (tools): Shown if any tools used +- Line 3 (agents): Shown only if agents active +- Line 4 (todos): Shown only if todos exist -**Terminal vs Session Scoping:** -- Each terminal window gets ONE HUD instance (tracked by terminal ID) -- Each Claude session has its own FIFO (for event isolation) -- `/new` within same terminal reuses existing HUD (signals it to switch sessions) -- Different terminal windows get separate HUDs +### Context Thresholds -Terminal IDs are derived from: tmux window ID, iTerm session ID, Kitty window ID, etc. +| Threshold | Color | Action | +|-----------|-------|--------| +| <70% | Green | Normal | +| 70-85% | Yellow | Warning | +| >85% | Red | Show token breakdown | +| >95% | Red | Show ⚠️ COMPACT | -## HUD Configuration +## Plugin Configuration -Optional HUD config lives at `~/.claude/hud/config.json`: +The plugin is configured in `.claude-plugin/plugin.json`: ```json { - "panelOrder": ["status", "context", "tools", "agents", "todos"], - "hiddenPanels": ["cost"], - "width": 56 + "statusLine": { + "type": "command", + "command": "node ${CLAUDE_PLUGIN_ROOT}/dist/index.js" + } } ``` -Panel IDs: `status`, `context`, `cost`, `contextInfo`, `tools`, `agents`, `todos`. - ## Dependencies -- **Runtime**: Node.js 18+ or Bun, jq (JSON parsing in hooks) -- **TUI Framework**: React 18 + Ink 5 (terminal UI via Yoga layout) +- **Runtime**: Node.js 18+ or Bun - **Build**: TypeScript 5, ES2022 target, NodeNext modules -- **Testing**: Vitest + @testing-library/react + ink-testing-library diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index ebf3ec2..0000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,75 +0,0 @@ -# Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. - -We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. - -## Our Standards - -Examples of behavior that contributes to a positive environment for our community include: - -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -- Focusing on what is best not just for us as individuals, but for the overall community - -Examples of unacceptable behavior include: - -- The use of sexualized language or imagery, and sexual attention or advances of any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or email address, without their explicit permission -- Other conduct which could reasonably be considered inappropriate in a professional setting - -## Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. - -Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. - -## Scope - -This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement via the GitHub profile listed below. All complaints will be reviewed and investigated promptly and fairly. - -Contact: https://github.com/jarrodwatts - -## Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. - -**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. - -### 2. Warning - -**Community Impact**: A violation through a single incident or series of actions. - -**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. - -**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. - -**Consequence**: A permanent ban from any sort of public interaction within the community. - -## Attribution - -This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. - -Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 5904829..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,332 +0,0 @@ -# Contributing to Claude HUD - -Thanks for your interest in contributing! This guide will help you get started. - -## Community Standards - -Please read `CODE_OF_CONDUCT.md`. For security issues, see `SECURITY.md`. - -## Development Setup - -```bash -# 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 - -# Run with coverage -bun test --coverage - -# Lint and typecheck -bun run lint -bun run typecheck - -# Format code -bun run format - -# Replay a fixture event stream -bun run replay:events -- --input ../tui/test-fixtures/hud-events.jsonl - -# Profile event throughput -bun run profile:events -- ../tui/test-fixtures/hud-events-stress.jsonl -``` - -### One-shot checks - -From the repo root: - -```bash -./scripts/check.sh -``` - -### Local Testing - -To test the plugin locally without publishing: - -```bash -# 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 -├── docs/ -│ ├── CHANGELOG.md # Version history -│ ├── research/ # Research notes -│ └── adr/ # Architecture Decision Records -├── tui/ -│ ├── src/ -│ │ ├── index.tsx # Entry point, session handling -│ │ ├── app.tsx # Main App component (slim) -│ │ ├── components/ # React/Ink UI components -│ │ │ ├── ContextMeter.tsx # Token usage + sparkline -│ │ │ ├── CostDisplay.tsx # API cost tracking -│ │ │ ├── ToolStream.tsx # Tool activity list -│ │ │ ├── AgentList.tsx # Subagent tracking -│ │ │ ├── StatusBar.tsx # Model + idle status -│ │ │ ├── SessionStats.tsx # Session statistics -│ │ │ ├── TodoList.tsx # Task tracking -│ │ │ ├── ContextInfo.tsx # CLAUDE.md detection -│ │ │ ├── Sparkline.tsx # Sparkline visualization -│ │ │ └── ErrorBoundary.tsx # Error handling -│ │ ├── hooks/ -│ │ │ ├── useHudState.ts # Centralized state management -│ │ │ └── useElapsedTime.ts # Timer hook -│ │ └── lib/ -│ │ ├── types.ts # TypeScript interfaces -│ │ ├── event-reader.ts # FIFO reader -│ │ ├── unified-context-tracker.ts # Token tracking (real + estimated) -│ │ ├── cost-tracker.ts # Cost estimation -│ │ ├── settings-reader.ts # Claude settings -│ │ ├── context-detector.ts # CLAUDE.md detection -│ │ └── logger.ts # Debug logging -│ ├── package.json -│ ├── tsconfig.json -│ ├── eslint.config.js # ESLint flat config -│ └── 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 - -**useHudState** (`hooks/useHudState.ts`) -- Centralized state management hook -- Processes all events from EventReader -- Manages tools, agents, context, cost, todos -- Single source of truth for HUD state - -**EventReader** (`lib/event-reader.ts`) -- Reads from named pipe (FIFO) -- Handles reconnection with exponential backoff -- Emits 'event' and 'status' events - -**UnifiedContextTracker** (`lib/unified-context-tracker.ts`) -- Reads real tokens from transcript files when available -- Falls back to estimation when transcript unavailable -- Tracks burn rate and token history for sparkline -- Eliminates flickering from dual data sources - -**CostTracker** (`lib/cost-tracker.ts`) -- Calculates cost based on token usage -- Supports different model pricing (Opus, Sonnet, Haiku) -- Tracks input/output tokens separately - -## Adding a New Panel - -1. Create a component in `tui/src/components/`: - -```tsx -import React, { memo } from 'react'; -import { Box, Text } from 'ink'; - -interface Props { - data: YourDataType; -} - -export const YourPanel = memo(function YourPanel({ data }: Props) { - return ( - - - Your Panel - - {/* Panel content */} - - ); -}); -``` - -2. Add state in `hooks/useHudState.ts`: - -```tsx -const [yourData, setYourData] = useState(initialValue); -``` - -3. Process relevant events in the `processEvent` callback: - -```tsx -if (event.event === 'RelevantEvent') { - setYourData(/* updated data */); -} -``` - -4. Return the new state from `useHudState`: - -```tsx -return { - // ... existing state - yourData, -}; -``` - -5. Add the component to `app.tsx` (wrapped in ErrorBoundary): - -```tsx - - - -``` - -6. Add tests in `components/YourPanel.test.tsx`. - -## Adding a New Hook - -1. Add the hook to `hooks/hooks.json`: - -```json -"NewHookEvent": [ - { - "hooks": [ - { - "type": "command", - "command": "${CLAUDE_PLUGIN_ROOT}/scripts/capture-event.sh", - "timeout": 5 - } - ] - } -] -``` - -2. Update `HudEvent` type in `types.ts` if new fields are needed. - -3. Handle the event in `processEvent` in `index.tsx`. - -## Running Tests - -```bash -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 -- **React.memo** - Use for all components to prevent unnecessary re-renders -- **ESLint + Prettier** - Run `bun run lint` and `bun run format` -- **Pre-commit hooks** - Husky runs lint-staged on commit - -### Quality Tools - -```bash -# Lint (ESLint) -bun run lint -bun run lint:fix - -# Format (Prettier) -bun run format -bun run format:check - -# Type check -bun run typecheck - -# All tests with coverage -bun test --coverage -``` - -## 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. diff --git a/README.md b/README.md index 4125ceb..8c37e21 100644 --- a/README.md +++ b/README.md @@ -1,243 +1,121 @@ # Claude HUD -[![CI](https://github.com/jarrodwatts/claude-hud/actions/workflows/ci.yml/badge.svg)](https://github.com/jarrodwatts/claude-hud/actions/workflows/ci.yml) [![License](https://img.shields.io/github/license/jarrodwatts/claude-hud)](LICENSE) -[![Latest Release](https://img.shields.io/github/v/release/jarrodwatts/claude-hud)](https://github.com/jarrodwatts/claude-hud/releases) -Real-time terminal dashboard for Claude Code. See context usage, tool activity, agent status, and more in a split pane next to your terminal. +Real-time statusline HUD for Claude Code. See context usage, tool activity, agent status, and todo progress directly in your terminal. -## Quickstart (2 minutes) +``` +[Opus] ████████░░ 45% | 📋 3 rules | 🔌 5 MCPs | ⏱️ 12m +◐ Edit: auth.ts | ✓ Read ×3 | ✓ Grep ×2 +◐ explore [haiku]: Finding auth code (2m 15s) +▸ Fix authentication bug (2/5) +``` + +## Why? + +When Claude shows "Thinking..." for minutes, you have no visibility into what's happening. Claude HUD gives you **X-ray vision**: + +- **Context health** — See exactly how full your context window is (native, accurate data) +- **Tool activity** — Watch Claude read, edit, and search files in real-time +- **Agent tracking** — See which subagents are running and what they're doing +- **Todo progress** — Track task completion as Claude works + +## Installation ```bash claude /plugin install github.com/jarrodwatts/claude-hud ``` -Start Claude Code as usual. The HUD appears automatically. +That's it. Start Claude Code as usual — the statusline appears automatically. -Verify installation (optional): +## What You See -```bash -claude plugin validate claude-hud +### Line 1: Session Info ``` - -Toggle visibility with `Ctrl+H`. Exit with `Ctrl+C`. - -## LLM-Paste Overview (copy into your LLM) - -```markdown -Project: Claude HUD - -What it is: -- A Claude Code plugin that opens a real-time terminal HUD (Heads-Up Display) in a split pane. -- Shows context usage, tool activity, agent status, todos, git status, and cost estimation while Claude runs. - -Why use it: -- Monitor token burn, compaction risk, and costs as you work. -- See tool calls and agent activity in real time without leaving your editor/terminal. -- Spot issues early (errors, stalls, runaway context growth). - -How it works (Claude Code plugin model): -- Claude Code plugins are directories with a `.claude-plugin/plugin.json` manifest plus root-level feature folders. -- This plugin uses `hooks/hooks.json` to subscribe to Claude Code lifecycle events. -- Hook scripts in `scripts/` transform event payloads and stream them through a FIFO. -- The TUI (React + Ink) reads the FIFO and renders panels in a split pane. - -Key components: -- `.claude-plugin/plugin.json`: plugin manifest and metadata. -- `hooks/hooks.json`: event subscriptions (SessionStart, PreToolUse, PostToolUse, etc). -- `scripts/session-start.sh`: creates FIFO and launches HUD. -- `scripts/capture-event.sh`: normalizes hook events and writes them to the FIFO. -- `tui/src/lib/event-reader.ts`: reads FIFO, emits events with reconnect. -- `tui/src/index.tsx`: top-level UI state and rendering. - -Install (recommended): -- `claude /plugin install github.com/jarrodwatts/claude-hud` -- Start Claude Code as normal; HUD spawns automatically. - -Verify: -- `claude plugin validate claude-hud` -- or `./scripts/verify-install.sh` (when installed from source) - -Requirements: -- Claude Code (v1.0.33+) -- Node.js 18+ or Bun -- `jq` for hook JSON parsing - -Supported terminals: -- tmux, iTerm2, Kitty, WezTerm, Zellij, Windows Terminal (WSL) for split panes. -- Others fall back to a separate window or background process. - -Common troubleshooting: -- Set `CLAUDE_HUD_DEBUG=1` and run `claude` to see debug logs. -- Use `claude --debug hooks` to inspect hook activity. -- See `TROUBLESHOOTING.md` for more. - -Summary: -- Claude HUD is a production-ready Claude Code plugin that streams hook events into a split-pane TUI so you can see context health, tool activity, and agent status live. +[Opus] ████████░░ 45% | 📋 3 rules | 🔌 5 MCPs | ⏱️ 12m ``` +- **Model** — Current model (Opus, Sonnet, Haiku) +- **Context bar** — Visual progress with color coding: + - 🟢 Green: <70% (healthy) + - 🟡 Yellow: 70-85% (getting full) + - 🔴 Red: >85% (warning) — shows token breakdown + - ⚠️ COMPACT: >95% (critical) +- **Rules count** — How many CLAUDE.md files loaded +- **MCP count** — Connected MCP servers +- **Duration** — Session time -Prefer a standalone file? See `docs/LLM.md`. +### Line 2: Tool Activity +``` +◐ Edit: auth.ts | ✓ Read ×3 | ✓ Grep ×2 +``` +- **Running tools** with ◐ spinner and target file +- **Completed tools** aggregated by type with counts -## Docs +### Line 3: Agent Status (when active) +``` +◐ explore [haiku]: Finding auth code (2m 15s) +``` +- **Agent type** and model +- **Description** of what it's doing +- **Elapsed time** -- `TROUBLESHOOTING.md` -- `CONTRIBUTING.md` -- `docs/CHANGELOG.md` -- `docs/FAQ.md` -- `docs/LLM.md` -- `docs/ARCHITECTURE.md` -- `docs/README.md` -- `CLAUDE.md` -- `CODE_OF_CONDUCT.md` -- `SECURITY.md` -- `LICENSE` - -## Features - -### Context Health -The most important metric when working with AI. See at a glance: -- **Token count** with visual progress bar -- **Sparkline** showing token usage history -- **Burn rate** — tokens consumed per minute -- **Compaction warning** when context is getting full -- **Breakdown** of input vs output token usage - -### Cost Estimation -Track your API costs in real-time: -- **Total cost** with input/output breakdown -- Automatically detects model pricing (Sonnet/Opus/Haiku) - -### Tool Activity Stream -Watch Claude work in real-time: -- Every tool call with status icons (✓ complete, ◐ running, ✗ error) -- **Duration** for each operation -- **Smart path truncation** showing filename + parent -- Color-coded: green for success, yellow for running, red for errors - -### Session Status -- **Idle indicator** (💤 idle / ⚡ working) -- **Permission mode** when not default -- **Compaction count** warnings -- **Last user prompt** preview - -### Agent Tracking -When Claude spawns subagents: -- **Type and description** of each agent -- **Live elapsed time** counter -- **Nested tool calls** — see what the agent is doing -- Completion status - -### Session Statistics -- Total tool call counts by type -- Lines changed (+additions/-deletions) -- Session duration -- Number of completed agents - -### Additional Panels -- **Todo List** — Claude's current task tracking -- **Modified Files** — files changed this session -- **MCP Status** — connected MCP servers +### Line 4: Todo Progress (when todos exist) +``` +▸ Fix authentication bug (2/5) +``` +- **Current task** being worked on +- **Progress** (completed/total) ## How It Works -Claude HUD uses Claude Code's plugin hooks to capture events: +Claude HUD uses Claude Code's **statusline API** — a multi-line display that updates every ~300ms. -1. **SessionStart** — Spawns the HUD in a split pane -2. **PreToolUse** — Shows tools before execution (running state) -3. **PostToolUse** — Captures tool completion -4. **UserPromptSubmit** — Tracks user prompts -5. **Stop** — Detects idle state -6. **PreCompact** — Tracks context compaction -7. **SubagentStop** — Tracks agent completion -8. **SessionEnd** — Cleans up +Unlike other approaches, Claude HUD: +- **No separate window** — Displays inline in your terminal +- **No hooks needed** — Parses the transcript directly +- **Native data** — Gets accurate token/context info from Claude Code +- **Works everywhere** — Any terminal, not just tmux/iTerm -Data flows through a named pipe (FIFO) to a React/Ink terminal UI. +### Architecture -## Plugin Anatomy (Claude Code) - -Claude Code plugins are directories with a `.claude-plugin/plugin.json` manifest plus feature directories at the plugin root. In Claude HUD: -- `.claude-plugin/plugin.json` declares the plugin name/version and provides the namespace. -- `hooks/hooks.json` registers lifecycle event subscriptions. -- `scripts/` contains the hook entrypoints that receive event payloads. -- `tui/` contains the React/Ink HUD that renders streamed events. - -## Configuration - -- `CLAUDE_HUD_DEBUG=1` enables debug logging to stderr. +``` +Claude Code → stdin JSON (model, tokens, context) + → transcript JSONL (tools, agents, todos) + → claude-hud renders 4 lines + → Claude Code displays them +``` ## Requirements -- Claude Code +- Claude Code v1.0.80+ - Node.js 18+ or Bun -- `jq` (for JSON parsing in hooks) -## Supported Terminals +## Configuration -| Terminal | Split Support | -|----------|---------------| -| **tmux** | ✓ Native split pane | -| **iTerm2** | ✓ Native split | -| **Kitty** | ✓ Remote control split | -| **WezTerm** | ✓ CLI split pane | -| **Zellij** | ✓ Native split | -| **Windows Terminal** | ✓ WSL split | -| **macOS Terminal** | Separate window | -| **xterm (Linux)** | Separate window | -| **Others** | Background process | +Claude HUD works with zero configuration. Optionally customize via `~/.claude/hud/config.json`: -## Keyboard Shortcuts - -| Key | Action | -|-----|--------| -| `Ctrl+H` | Toggle HUD visibility | -| `Ctrl+C` | Exit HUD | - -## Troubleshooting (Quick Checks) - -```bash -# Check plugin is valid -claude plugin validate claude-hud - -# Enable debug logging for the HUD -CLAUDE_HUD_DEBUG=1 claude - -# View debug output -claude --debug hooks - -# If installed from source, run verification script -./scripts/verify-install.sh +```json +{ + "showRules": true, + "showMcps": true, + "showDuration": true, + "contextWarningThreshold": 85, + "contextCriticalThreshold": 95 +} ``` ## Development ```bash -# Clone the repo git clone https://github.com/jarrodwatts/claude-hud -cd claude-hud/tui +cd claude-hud -# Install dependencies +# Install & build bun install - -# Build bun run build -# Run tests -bun test - -# Lint & typecheck -bun run lint -bun run typecheck - -# Start manually (for development) -bun run start -- --session test --fifo /tmp/test.fifo -``` - -### Debug Mode - -Set `CLAUDE_HUD_DEBUG=1` to enable detailed logging to stderr: - -```bash -CLAUDE_HUD_DEBUG=1 bun run start -- --session test --fifo /tmp/test.fifo +# Test with sample data +echo '{"model":{"display_name":"Opus"},"context_window":{"current_usage":{"input_tokens":45000},"context_window_size":200000}}' | node dist/index.js ``` ## License @@ -246,4 +124,8 @@ MIT ## Credits -Built with [Claude Code](https://claude.ai/code) and [Ink](https://github.com/vadimdemedes/ink). +Built with [Claude Code](https://claude.ai/code). + +--- + +**v2.0** — Complete rewrite from split-pane TUI to inline statusline. [See v1 for the original split-pane version](https://github.com/jarrodwatts/claude-hud/tree/v1.0.0-split-pane). diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index d67719d..0000000 --- a/SECURITY.md +++ /dev/null @@ -1,28 +0,0 @@ -# Security Policy - -## Supported Versions - -Security updates are provided for the latest release. - -## Dependency Policy - -- Run `bun run audit` from `tui/` before releases and during CI. -- Update `bun.lock` when dependency versions change; commits should include both - `tui/package.json` and `tui/bun.lock`. - -## Reporting a Vulnerability - -Please report security issues privately. Use GitHub Security Advisories for this repository: - -https://github.com/jarrodwatts/claude-hud/security/advisories - -If you cannot use GitHub advisories, contact the maintainer via the GitHub profile: - -https://github.com/jarrodwatts - -## Threat Model (Summary) - -The HUD reads local files (settings, CLAUDE.md, config) and parses hook event -payloads. Threats primarily involve untrusted local file contents or malformed -events. The HUD treats parsing errors as safe-mode conditions and falls back to -last known good state while logging errors. See `docs/THREAT_MODEL.md`. diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md deleted file mode 100644 index a43fcfa..0000000 --- a/TROUBLESHOOTING.md +++ /dev/null @@ -1,161 +0,0 @@ -# Troubleshooting Claude HUD - -## HUD Not Appearing - -### 1. Check Plugin Installation -```bash -# Verify the plugin is installed -ls ~/.claude/plugins/ | grep claude-hud -``` - -If not listed, install with: -```bash -claude /plugin install github.com/jarrodwatts/claude-hud -``` - -### 2. Check Plugin Validation -```bash -# Validate the plugin structure -claude plugin validate ~/.claude/plugins/claude-hud -``` - -You should see: `✔ Validation passed` - -### 3. Check Terminal Support -The HUD works best with terminals that support split panes: -- **tmux** - Best support, native split -- **iTerm2** - Native split on macOS -- **Kitty** - Remote control split -- **WezTerm** - CLI split pane -- **Zellij** - Native split - -For other terminals, the HUD runs in a separate window or background. - -### 4. Check Dependencies -```bash -# Ensure jq is installed (required for hook scripts) -which jq || echo "jq not found - install with: brew install jq" - -# Check Node.js or Bun is available -which node || which bun || echo "Node.js or Bun required" -``` - -### 4b. Check Bootstrap Log -If the HUD fails to launch, a bootstrap log is written with actionable fixes: -```bash -cat ~/.claude/hud/logs/hud-bootstrap.log -``` - -### 5. Manual Testing -Test the HUD manually: -```bash -# Create a test FIFO -mkfifo /tmp/test-hud.fifo - -# Start the HUD (in one terminal) -cd ~/.claude/plugins/claude-hud/tui -node dist/index.js --session test --fifo /tmp/test-hud.fifo - -# Send a test event (in another terminal) -echo '{"event":"PostToolUse","tool":"Read","input":{"file_path":"/test.ts"},"response":{"content":"test"},"session":"test","ts":1234567890}' > /tmp/test-hud.fifo -``` - -You should see the event appear in the HUD. - -## HUD Appears But No Data - -### Check FIFO Connection -The HUD connects via a named pipe. Check if it exists: -```bash -ls -la ~/.claude/hud/events/ -``` - -You should see `.fifo` files for active sessions. - -### Check Hook Execution -Run Claude with debug mode to see hook execution: -```bash -claude --debug hooks -``` - -Look for messages about `capture-event.sh` being called. - -### Check Logs -View HUD logs if running in background: -```bash -cat ~/.claude/hud/logs/*.log -``` - -## Common Issues - -### "jq: command not found" -Install jq: -```bash -# macOS -brew install jq - -# Ubuntu/Debian -sudo apt-get install jq - -# Other Linux -# Use your package manager -``` - -### "Permission denied" on Scripts -Make scripts executable: -```bash -chmod +x ~/.claude/plugins/claude-hud/scripts/*.sh -``` - -### HUD Freezes or Crashes -1. Check for error in logs: `cat ~/.claude/hud/logs/*.log` -2. Kill any stuck processes: `pkill -f claude-hud` -3. Remove stale FIFOs: `rm ~/.claude/hud/events/*.fifo` -4. Start a new Claude session - -### tmux Split Not Working -Ensure you're running Claude inside tmux: -```bash -# Check if in tmux -echo $TMUX - -# Start tmux if not -tmux new-session -``` - -### iTerm2 Split Not Working -Ensure iTerm2 is the active terminal: -```bash -echo $TERM_PROGRAM -# Should output: iTerm.app -``` - -## Getting Help - -If you're still having issues: -1. Check the [GitHub Issues](https://github.com/jarrodwatts/claude-hud/issues) -2. Open a new issue with: - - Your terminal type - - Output of `claude plugin validate` - - Any error messages from logs - - Steps to reproduce - -## Debug Mode - -Enable debug logging for more verbose output: -```bash -# Method 1: Environment variable (recommended) -CLAUDE_HUD_DEBUG=1 claude - -# Method 2: Claude's built-in debug mode -claude --debug hooks - -# Method 3: Manual testing with debug output -cd ~/.claude/plugins/claude-hud/tui -CLAUDE_HUD_DEBUG=1 node dist/index.js --session test --fifo /tmp/test.fifo -``` - -Debug output is written to stderr and includes: -- Event parsing errors -- FIFO connection status -- Transcript file reading attempts diff --git a/docs/API.md b/docs/API.md deleted file mode 100644 index bb5d8ea..0000000 --- a/docs/API.md +++ /dev/null @@ -1,36 +0,0 @@ -# API Contracts - -## HUD Event Schema (v1) - -All events written to the HUD FIFO must include `schemaVersion: 1`. The HUD -will ignore events with an unknown schema version. - -### Required fields -- `schemaVersion`: number (current: `1`) -- `event`: string (e.g., `PreToolUse`, `PostToolUse`, `Stop`) -- `session`: string -- `ts`: number (epoch seconds) - -### Optional fields -- `tool`: string or null -- `toolUseId`: string -- `input`: object or null -- `response`: object or null -- `permissionMode`: string -- `transcriptPath`: string -- `cwd`: string -- `prompt`: string - -### Example -```json -{ - "schemaVersion": 1, - "event": "PostToolUse", - "tool": "Read", - "toolUseId": "tool-1", - "input": { "file_path": "README.md" }, - "response": { "duration_ms": 120 }, - "session": "abc123", - "ts": 1700000000 -} -``` diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md deleted file mode 100644 index caffdcc..0000000 --- a/docs/ARCHITECTURE.md +++ /dev/null @@ -1,73 +0,0 @@ -# Architecture - -Claude HUD is a Claude Code plugin that renders a real-time TUI from hook events. - -## High-Level Flow - -``` -Claude Code hooks - -> scripts/capture-event.sh - -> session FIFO (~/.claude/hud/events/.fifo) - -> tui/src/lib/event-reader.ts - -> tui/src/hooks/useHudState.ts - -> tui/src/app.tsx - -> Ink UI panels -``` - -## Plugin Structure - -``` -claude-hud/ - .claude-plugin/plugin.json - hooks/hooks.json - scripts/ - tui/ -``` - -- `.claude-plugin/plugin.json` declares the plugin and hook entrypoints. -- `hooks/hooks.json` subscribes to Claude Code lifecycle events. -- `scripts/` normalizes event payloads and launches the HUD. -- `tui/` contains the Ink-based terminal UI. - -## Runtime Files - -The HUD writes runtime artifacts under `~/.claude/hud/`: - -- `events/.fifo` - Event stream (session-scoped) -- `pids/.pid` - HUD process ID (terminal-scoped) -- `refresh-.json` - Current session state (terminal-scoped) -- `logs/.log` - Fallback output - -### Terminal vs Session Scoping - -Each terminal window gets ONE HUD instance, tracked by a terminal ID derived from: -- tmux: `#{window_id}` (e.g., `tmux-@0`) -- iTerm2: `ITERM_SESSION_ID` -- Kitty: `KITTY_WINDOW_ID` -- WezTerm: `WEZTERM_PANE` -- Fallback: TTY device or parent PID - -This ensures: -- Multiple Claude instances in different windows → separate HUDs -- `/new` within same window → HUD switches sessions (not duplicated) - -## Key Components - -- `tui/src/lib/event-reader.ts` reads the FIFO and reconnects if it drops. -- `tui/src/hooks/useHudState.ts` is the single source of truth for HUD state. -- `tui/src/components/` renders panels such as ContextMeter, ToolStream, AgentList. -- `tui/src/lib/unified-context-tracker.ts` handles context usage and burn rate. -- `tui/src/lib/cost-tracker.ts` calculates input/output cost. - -## Hook Events - -Common events used by the HUD: - -- `SessionStart`: spawn HUD in a split pane -- `PreToolUse`: show tool in running state -- `PostToolUse`: record completion and metrics -- `UserPromptSubmit`: track prompts and idle state -- `Stop`: mark idle -- `PreCompact`: compaction counter -- `SubagentStop`: agent completion -- `SessionEnd`: cleanup diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md deleted file mode 100644 index a20e2fe..0000000 --- a/docs/CHANGELOG.md +++ /dev/null @@ -1,199 +0,0 @@ -# Changelog - -All notable changes to claude-hud will be documented in this file. - -## [2.0.11] - 2026-01-03 - -### Removed -- **Dead code cleanup**: Removed 1,145+ lines of unused code - - `context-tracker.ts` - superseded by UnifiedContextTracker - - `transcript-reader.ts` - functionality moved to UnifiedContextTracker - - `stats-reader.ts` - unused - - `usage-reader.ts` - unused - - `ContextState` interface - redundant subset of ContextHealth - -### Improved -- **Test coverage**: Now at 95.14% (194 tests) -- **Code reduction**: From ~3,000+ lines to 1,928 lines (36% reduction) - ---- - -## [2.0.10] - 2026-01-03 - -### Added -- **CI**: GitHub Actions workflow for automated testing - - Lint, typecheck, test, and build on push/PR - - Plugin structure validation (Note: requires `workflow` scope to push) - -### Fixed -- **Build**: Removed accidental .gitignore entry blocking CI workflow -- **Version**: Synced plugin.json version with package.json (was 0.1.0, now 2.0.10) - ---- - -## [2.0.9] - 2026-01-03 - -### Improved -- **Performance**: Added React.memo to SessionStats component - - All components now consistently wrapped with React.memo - -### Fixed -- **Documentation**: Removed broken screenshot reference from README - ---- - -## [2.0.8] - 2026-01-03 - -### Improved -- **Test coverage**: Increased to 94.25% (231 total tests) - - ToolStream now at 100% line coverage - - Added edge case tests for path truncation -- **Code quality**: Removed dead code from truncatePath function - ---- - -## [2.0.7] - 2026-01-03 - -### Improved -- **Performance**: Added React.memo to McpStatus and ModifiedFiles components -- **Debugging**: ErrorBoundary now logs errors via logger utility - ---- - -## [2.0.6] - 2026-01-03 - -### Improved -- **Documentation**: Updated CONTRIBUTING.md with v2.0 architecture - - Added coverage, lint, typecheck, format commands - - Documented useHudState as central state management - - Updated project structure with new files - - Added Code Style section with quality tools - ---- - -## [2.0.5] - 2026-01-03 - -### Improved -- **Test coverage**: Increased to 94.00% (229 total tests) - - Added ContextMeter tests (header, percentage, compact warning, number formatting) - - Added settings-reader edge case tests (invalid JSON, missing fields) - ---- - -## [2.0.4] - 2026-01-03 - -### Improved -- **Test coverage**: Increased to 93.92% (218 total tests) - - Added SessionStats hours format test - - Added transcript-reader invalidate test - - Added AgentList edge case tests (filename-only targets, truncation, empty targets) - - Added context-detector edge case tests (missing permissions, undefined cwd) - ---- - -## [2.0.3] - 2026-01-03 - -### Improved -- **Test coverage**: Increased to 93.64% (210 total tests) - - Added StatusBar.test.tsx with truncatePath tests - - Added ToolStream edge case tests for path truncation - - Added context-tracker tests for addMessageTokens and getContextState - ---- - -## [2.0.2] - 2026-01-03 - -### Improved -- **Test coverage**: Increased to 92%+ (192 total tests) - - Added ErrorBoundary tests for error rendering - - Added event-reader tests for getLastEventTime() and switchFifo() - - Added usage-reader tests for invalidate() and edge cases -- **Performance**: Added React.memo to all remaining components - - TodoList, Sparkline, AgentList, StatusBar, ContextInfo now memoized - - Moved all helper functions outside component bodies - -### Removed -- Unused GitStatus component - ---- - -## [2.0.1] - 2026-01-03 - -### Added -- **Debug logging**: Proper error logging via `CLAUDE_HUD_DEBUG=1` - - Logger utility with debug/warn/error levels - - Replaces all silent catch blocks with logged errors -- **GitHub Actions CI**: Automated lint, typecheck, test, and build on push/PR - - Plugin structure validation (plugin.json, hooks.json, scripts) - - Note: Requires `workflow` scope on GitHub token to push - -### Fixed -- **Agent tools tracking**: Agent tools array now populates correctly - - Tools tracked per-agent and limited to last 5 calls - - Excludes Task tool itself from tracking - -### Improved -- **Test coverage**: Increased from 82% to 90%+ (31 new tests) - - Added tests for logger, ContextInfo, useElapsedTime, StatsReader -- **Performance**: Added React.memo to prevent unnecessary re-renders - - Wrapped ContextMeter, ToolStream, CostDisplay - - Moved helper functions outside component bodies - -### Removed -- Unused components: Edits.tsx, RateLimitMeter.tsx -- Unused types: AppState interface -- Unused exports: readStats() now internal-only - ---- - -## [2.0.0] - 2026-01-02 - -### Architecture Overhaul - -A complete rewrite focusing on stability, accuracy, and developer experience. - -### Added -- **UnifiedContextTracker**: Single source of truth for context tracking - - Reads real token counts from Claude transcript files - - Falls back to estimation when transcript unavailable - - Eliminates flickering from dual data sources -- **CostDisplay**: Real-time API cost estimation - - Tracks input/output tokens separately - - Automatic model detection for accurate pricing - - Supports Opus, Sonnet, and Haiku pricing -- **Custom hooks architecture**: - - `useHudState` - Centralized state management - - `useElapsedTime` - Session timer hook -- **Code quality tooling**: - - ESLint with TypeScript, React, and React Hooks rules - - Prettier with consistent formatting - - Husky pre-commit hooks with lint-staged -- **Comprehensive test suite**: 152 tests covering all components - -### Changed -- **app.tsx**: Reduced from 329 lines to 136 lines (59% reduction) -- **Context tracking**: Reads transcript on Stop events only, not polling -- **State management**: Follows ADR 001 pattern with custom hooks - -### Fixed -- **Context flickering**: Eliminated dual-source updates -- **Session handling**: Proper transcript path detection on /resume -- **Test reliability**: Fixed race condition in smoke tests - -### Technical -- Added Architecture Decision Records (ADRs): - - ADR 001: State management via custom hooks - - ADR 002: Event-driven data flow with minimal polling - - ADR 003: Minimal shell scripts, logic in TypeScript - - ADR 004: Session ID tracking for graceful transitions -- Research documented in `docs/research/RESEARCH.md` - -## [1.0.0] - Initial Release - -- Context meter with sparkline -- Tool stream with live status -- Agent tracking -- Todo list display -- Session statistics -- Git status panel -- MCP server status diff --git a/docs/FAQ.md b/docs/FAQ.md deleted file mode 100644 index 5c82a6d..0000000 --- a/docs/FAQ.md +++ /dev/null @@ -1,45 +0,0 @@ -# FAQ - -## Does Claude HUD change Claude's outputs or prompts? - -No. Claude HUD is read-only. It listens to Claude Code hook events and renders a UI, but it does not modify prompts, tools, or outputs. - -## Does it work if my terminal doesn't support splits? - -Yes. Claude HUD tries to open a split pane when supported (tmux, iTerm2, Kitty, WezTerm, Zellij, Windows Terminal WSL). If splits are not available, it falls back to a separate window or background process. - -## How do I uninstall? - -```bash -claude /plugin uninstall claude-hud -``` - -## Does it require network access? - -No. The HUD runs locally and only reads Claude Code hook events. - -## What does it depend on? - -- Claude Code (v1.0.33+) -- Node.js 18+ or Bun -- `jq` for JSON parsing in hook scripts - -## What data does it read? - -It consumes Claude Code hook payloads and session events. It does not read your code unless a hook event includes metadata (like file paths) that Claude Code already exposes. - -## Where are runtime files stored? - -Under `~/.claude/hud/`: -- `events/.fifo` for the event stream -- `pids/.pid` for process tracking -- `logs/.log` for fallback logs - -## How do I debug it? - -```bash -CLAUDE_HUD_DEBUG=1 claude -claude --debug hooks -``` - -For more, see `TROUBLESHOOTING.md`. diff --git a/docs/LLM.md b/docs/LLM.md deleted file mode 100644 index 7a39b3b..0000000 --- a/docs/LLM.md +++ /dev/null @@ -1,55 +0,0 @@ -# Claude HUD: LLM-Paste Overview - -Copy the block below into your LLM of choice. - -```markdown -Project: Claude HUD - -What it is: -- A Claude Code plugin that opens a real-time terminal HUD (Heads-Up Display) in a split pane. -- Shows context usage, tool activity, agent status, todos, git status, and cost estimation while Claude runs. - -Why use it: -- Monitor token burn, compaction risk, and costs as you work. -- See tool calls and agent activity in real time without leaving your editor/terminal. -- Spot issues early (errors, stalls, runaway context growth). - -How it works (Claude Code plugin model): -- Claude Code plugins are directories with a `.claude-plugin/plugin.json` manifest plus root-level feature folders. -- This plugin uses `hooks/hooks.json` to subscribe to Claude Code lifecycle events. -- Hook scripts in `scripts/` transform event payloads and stream them through a FIFO. -- The TUI (React + Ink) reads the FIFO and renders panels in a split pane. - -Key components: -- `.claude-plugin/plugin.json`: plugin manifest and metadata. -- `hooks/hooks.json`: event subscriptions (SessionStart, PreToolUse, PostToolUse, etc). -- `scripts/session-start.sh`: creates FIFO and launches HUD. -- `scripts/capture-event.sh`: normalizes hook events and writes them to the FIFO. -- `tui/src/lib/event-reader.ts`: reads FIFO, emits events with reconnect. -- `tui/src/index.tsx`: top-level UI state and rendering. - -Install (recommended): -- `claude /plugin install github.com/jarrodwatts/claude-hud` -- Start Claude Code as normal; HUD spawns automatically. - -Verify: -- `claude plugin validate claude-hud` -- or `./scripts/verify-install.sh` (when installed from source) - -Requirements: -- Claude Code (v1.0.33+) -- Node.js 18+ or Bun -- `jq` for hook JSON parsing - -Supported terminals: -- tmux, iTerm2, Kitty, WezTerm, Zellij, Windows Terminal (WSL) for split panes. -- Others fall back to a separate window or background process. - -Common troubleshooting: -- Set `CLAUDE_HUD_DEBUG=1` and run `claude` to see debug logs. -- Use `claude --debug hooks` to inspect hook activity. -- See `TROUBLESHOOTING.md` for more. - -Summary: -- Claude HUD is a production-ready Claude Code plugin that streams hook events into a split-pane TUI so you can see context health, tool activity, and agent status live. -``` diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index e70600c..0000000 --- a/docs/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Documentation - -Start here for a map of the project docs. - -## Getting Started - -- `../README.md` for install + quickstart -- `../TROUBLESHOOTING.md` for common setup issues -- `FAQ.md` for common questions - -## Architecture - -- `ARCHITECTURE.md` for the data flow and component map -- `../CLAUDE.md` for contributor-focused technical details -- `adr/` for architecture decisions -- `API.md` for the HUD event contract -- `THREAT_MODEL.md` for local file and event stream risks - -## Development - -- `../CONTRIBUTING.md` for setup, tests, and contribution guidelines -- `CHANGELOG.md` for release notes -- `RELEASING.md` for the release workflow - -## LLM Helpers - -- `LLM.md` for the copy-paste summary block diff --git a/docs/RELEASING.md b/docs/RELEASING.md deleted file mode 100644 index 9801fbf..0000000 --- a/docs/RELEASING.md +++ /dev/null @@ -1,27 +0,0 @@ -# Releasing Claude HUD - -## Versioning Strategy - -Claude HUD follows semantic versioning. Release tags are `vX.Y.Z`. Both -`tui/package.json` and `.claude-plugin/plugin.json` are kept in sync. - -## Release Steps - -1. Bump versions: - ```bash - node scripts/release.ts --bump patch - ``` -2. Generate changelog entry: - ```bash - node scripts/changelog.ts X.Y.Z - ``` -3. Review `docs/CHANGELOG.md`, commit, and tag: - ```bash - git commit -am "chore: release X.Y.Z" - git tag vX.Y.Z - git push --follow-tags - ``` - -## Artifacts - -GitHub Actions builds the TUI and uploads `claude-hud-tui.tar.gz` on release tags. diff --git a/docs/THREAT_MODEL.md b/docs/THREAT_MODEL.md deleted file mode 100644 index 02ff7db..0000000 --- a/docs/THREAT_MODEL.md +++ /dev/null @@ -1,30 +0,0 @@ -# Threat Model - -## Scope - -Claude HUD reads local files and hook event streams to render a terminal UI. -It does not handle network input directly. - -## Assets - -- Hook event payloads (tool usage, prompts, timings). -- Local configuration and settings files. -- Rendered UI state (context usage, costs, agents). - -## Trust Boundaries - -- `scripts/capture-event.sh` writes events into a FIFO. -- HUD reads from the FIFO and local filesystem paths under `$HOME/.claude`. - -## Threats - -- Malformed events causing crashes or incorrect state. -- Untrusted file contents in settings or config leading to parsing failures. -- Excessive event volume causing UI thrashing or degraded UX. - -## Mitigations - -- Schema versioning and validation for HUD events. -- Safe mode fallback when settings/config parsing fails. -- Render-rate cap to coalesce event bursts. -- Logging for parse failures and read errors. diff --git a/docs/research/RESEARCH.md b/docs/research/RESEARCH.md deleted file mode 100644 index 8feaf3b..0000000 --- a/docs/research/RESEARCH.md +++ /dev/null @@ -1,226 +0,0 @@ -# Claude HUD Research Findings - -This document captures research conducted to inform the architecture and implementation of claude-hud v2. - -## 1. Claude Code Plugin Best Practices - -### Sources -- [Anthropic: Claude Code Best Practices](https://www.anthropic.com/engineering/claude-code-best-practices) -- [Claude Code Plugins Announcement](https://www.anthropic.com/news/claude-code-plugins) -- [GitHub: claude-code/plugins](https://github.com/anthropics/claude-code/blob/main/plugins/README.md) - -### Key Principles - -1. **Low-level and Unopinionated**: Claude Code provides close to raw model access without forcing specific workflows. This design philosophy creates a flexible, customizable, scriptable, and safe power tool. - -2. **Plugin Components**: - - **Hooks**: Customize behavior at key points (PreToolUse, PostToolUse, Stop, SessionStart, SessionEnd, etc.) - - **Commands**: Slash commands defined in markdown files - - **Skills**: Knowledge and workflows bundled together - - **Subagents**: Purpose-built agents for specialized tasks - - **MCP Servers**: Connect to tools and data sources - -3. **Hook Architecture**: - - Hooks execute shell scripts in response to lifecycle events - - Input is provided via environment variables and stdin (JSON) - - Output is captured from stdout - - Non-blocking writes to FIFOs are critical for performance - -4. **Best Practices**: - - Use CLAUDE.md for project-specific guidance - - Commands can use `$ARGUMENTS` for parameterization - - MCP servers can be project-scoped, global, or checked in - - Debug with `--mcp-debug` flag - -### Implications for claude-hud - -- **Event-driven over polling**: Hooks provide real-time events; polling should be minimized -- **Non-blocking I/O**: Critical for not slowing down Claude Code -- **Session lifecycle awareness**: Need to handle SessionStart, SessionEnd, and session switching gracefully - ---- - -## 2. TUI Design Principles (lazygit, btop, etc.) - -### Sources -- [lazygit GitHub](https://github.com/jesseduffield/lazygit) -- [awesome-tuis](https://github.com/rothgar/awesome-tuis) -- [The (lazy) Git UI You Didn't Know You Need](https://www.bwplotka.dev/2025/lazygit/) - -### What Makes Great TUIs - -1. **Visual Organization & Consistency** - - Set of boxes ("views") with consistent behavior - - Most views visible at all times (unless zoomed) - - Strong visual hierarchy - -2. **Core UX Principles** - - Simplicity - - Consistency - - Discoverability - - Sane defaults - - Shortcuts for common flows - - Interactivity - -3. **Enhanced Visualization** - - Present complex information in structured, readable ways - - Use graphs and charts for time-series data - - Make patterns visible at a glance - -4. **Keyboard-Driven Navigation** - - Vim-style keybindings (h/j/k/l, q to quit) - - Consistent across the application - - / for filtering, y for copy - -5. **Reduced Context Switching** - - All relevant information in one view - - No need to switch to other terminals/tools - -6. **Learning Curve & Discoverability** - - Stick to familiar terms and abstractions - - Guide users through complex operations - - Make advanced features discoverable - -### Implications for claude-hud - -- **Single canonical layout**: Don't overcomplicate with modes -- **Information density**: Show what matters most prominently -- **Consistency**: Same patterns throughout the UI -- **Glanceable**: Key metrics visible at a glance -- **No interactivity needed**: View-only is fine for a metrics dashboard - ---- - -## 3. Ink/React Terminal UI Patterns - -### Sources -- [Ink GitHub](https://github.com/vadimdemedes/ink) -- [Ink 3 Release Notes](https://vadimdemedes.com/posts/ink-3) -- [Building CLI tools with React using Ink](https://medium.com/trabe/building-cli-tools-with-react-using-ink-and-pastel-2e5b0d3e2793) - -### Key Features & Patterns - -1. **Core Components** - - ``: Fundamental text rendering with colors, styling - - ``: Flexbox-based layout container - - ``: Renders content once, never updates (CRITICAL for performance) - - ``: Output transformation utility - -2. **Performance Optimization** - - **Frame Rate Control**: - ```tsx - // Configure max FPS to reduce CPU usage - ``` - - **`` Component** (CRITICAL): - - Renders items permanently above the UI - - Cannot update after display - - Perfect for logs, completed items - - Almost 2x more performant in Ink 3 - - Used by Jest, Tap, Gatsby for large outputs - - **Incremental Rendering**: - - Only updates changed lines - - Reduces flickering - - Better for frequently updating UIs - -3. **Focus Management** - - `useFocus` hook for component focus - - `useFocusManager` for complex navigation - - Tab to cycle through focusable components - -4. **Console Logging** - - Ink intercepts console.log/error - - Displays correctly above the UI - - Prevents interference with rendering - -### Critical Performance Insight - -The `` component is key for preventing flickering: -- Use for persistent headers, completed items -- Only dynamic content should re-render -- Separating static from dynamic prevents full redraws - -### Implications for claude-hud - -- **Use `` strategically**: Headers, section dividers should not re-render -- **Minimize re-renders**: Only update components that actually changed -- **Memoization**: Use React.memo, useMemo, useCallback -- **Debounce rapid updates**: Context updates shouldn't cause rapid re-renders -- **Single source of truth**: Avoid multiple polling sources causing conflicting updates - ---- - -## 4. Current Architecture Problems - -Based on analysis of the existing codebase: - -### Data Flow Issues -1. **Multiple polling sources** (30s each): settings, context, transcript -2. **Race conditions**: FIFO cleanup timing issues -3. **Silent error handling**: Errors swallowed, hard to debug -4. **State inconsistency**: Multiple sources can cause flickering - -### Code Quality Issues -1. **app.tsx is 300+ lines**: Too much in one file -2. **Type assertions**: Using `as` instead of proper discriminated unions -3. **No linting/formatting**: Inconsistent code style -4. **Missing tests**: Several components untested - -### Session Handling Issues -1. **Session attachment fails**: /new /exit /resume don't work smoothly -2. **No cleanup on session switch**: Stale data persists - ---- - -## 5. Architecture Recommendations - -Based on research, here are the recommended approaches: - -### State Management -**Recommendation: Custom hooks + useReducer** -- Not XState (overkill for this use case) -- Not Context API alone (prop drilling isn't an issue) -- Custom hooks encapsulate related state logic -- useReducer for complex state transitions - -### Data Flow -**Recommendation: Event-driven with minimal polling** -- Primary: Hook events via FIFO (real-time) -- Secondary: Single consolidated poll for data not in events -- Eliminate redundant polling sources - -### Shell Scripts -**Recommendation: Keep bash for hooks, move logic to TypeScript** -- Hooks MUST be shell scripts (Claude Code requirement) -- But keep them minimal - just pass data to FIFO -- Complex logic in TypeScript (testable) - -### Session Handling -**Recommendation: Session ID in events + graceful reconnection** -- Track session ID in all events -- Detect session changes and reset state -- Reconnect FIFO with exponential backoff - ---- - -## 6. Action Items from Research - -1. **Refactor to event-driven architecture**: Single FIFO, minimal polling -2. **Use `` for stable UI sections**: Prevent unnecessary re-renders -3. **Extract state to custom hooks**: useContextState, useToolStream, etc. -4. **Add proper error handling**: No silent catches, structured logging -5. **Implement session tracking**: Detect /new /exit /resume -6. **Add ESLint + Prettier**: Consistent code quality -7. **Comprehensive tests**: Especially for state transitions - ---- - -## References - -- [Anthropic: Claude Code Best Practices](https://www.anthropic.com/engineering/claude-code-best-practices) -- [Claude Code Plugins](https://www.anthropic.com/news/claude-code-plugins) -- [Ink GitHub](https://github.com/vadimdemedes/ink) -- [lazygit](https://github.com/jesseduffield/lazygit) -- [awesome-tuis](https://github.com/rothgar/awesome-tuis)