Skip to content

feat(tui): add fs.watch bridge for hud-state.json to enable TUI updates in stdio mode #1104

Description

@JeremyDev87

Problem

The TUI sidebar (codingbuddy tui) does not react to mode changes (PLAN/ACT/EVAL/AUTO) or agent activations when the MCP server runs in stdio mode (the default).

Root Cause

The TUI receives state updates exclusively through TuiEventBus events emitted by TuiInterceptor, which intercepts MCP tool responses inside the MCP server process. In stdio mode, Claude Code spawns the MCP server as a child process communicating via stdin/stdout — the TUI runs as a separate process with no connection to this EventBus.

Claude Code ──stdio──▶ MCP Server (TuiInterceptor emits events internally)
                              ↑ events never leave this process

codingbuddy tui (separate process, EventBus is empty)

Meanwhile, the plugin hooks already write mode/agent state to ~/.codingbuddy/hud-state.json (used by the statusLine HUD script), but the TUI never reads this file.

Current Architecture

Component Writes to Reads from
Plugin hooks (Python) hud-state.json
StatusLine HUD script hud-state.json
TUI sidebar (React/Ink) EventBus only ❌ (no file source)
MCP Server (stdio) EventBus (internal)

Proposed Solution: fs.watch + EventBus Bridge

Add a file watcher in the TUI process that monitors hud-state.json and translates file changes into EventBus events.

Implementation

  1. New module: tui/events/hud-file-bridge.ts

    Watch ~/.codingbuddy/hud-state.json for changes. On change: read JSON, diff against previous state, emit EventBus events (MODE_CHANGED, AGENT_ACTIVATED, etc.)

  2. Integration point: Initialize the bridge in dashboard-app.tsx or multi-session-app.tsx alongside existing EventBus setup

  3. No changes needed to:

    • Existing TUI components (already subscribe to EventBus)
    • Plugin hooks (already write to hud-state.json)
    • MCP server interceptor (still works for SSE mode)

Why fs.watch over alternatives

Approach Latency CPU Complexity Existing code impact
fs.watch + EventBus ~100ms (FSEvents) Near zero Low None
setInterval polling 500ms-1s Slight Low None
SSE mode migration Instant None High Config changes for all users
IPC socket bridge Instant Low Medium New connection management

fs.watch uses macOS FSEvents / Linux inotify — kernel-level notification with no polling overhead.

Acceptance Criteria

  • TUI sidebar updates mode indicator when PLAN/ACT/EVAL/AUTO is typed
  • TUI sidebar shows active agent name on mode change
  • Works in stdio mode (default MCP transport)
  • Does not break SSE mode (EventBus events from both sources coexist)
  • Handles missing/malformed hud-state.json gracefully
  • Debounces rapid file changes (e.g. 100ms debounce)
  • Cleans up watcher on TUI shutdown

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions