Data Flow
Hook to JSON Pipeline
Section titled “Hook to JSON Pipeline”When Claude Code fires an event, the hook system writes status to the filesystem:
Claude Code Event │ ▼Hook Script (notify.sh) │ ├── Reads stdin JSON for event metadata │ (teammate_name, team_name, session_id, hook_event_name) │ ├── Determines target file: ~/.claude-sessions/<tmux_session>.json │ ├── Routes based on teammate presence: │ ├── No teammate → Update main session status │ └── Has teammate → Update team.agents[] entry │ └── Writes JSON atomicallyStatus File Format
Section titled “Status File Format”{ "tmux_session": "my-session", "status": "working", "message": "Implementing login feature", "cwd": "/home/user/projects/app", "timestamp": 1738972800, "metrics": { "started": 1738970000, "tools": {"Read": 5, "Write": 3, "Bash": 2}, "recent_tools": ["Read", "Write", "Bash"] }, "team": { "name": "my-project", "agents": [ {"name": "researcher", "status": "working", "timestamp": 1738972800} ] }}TUI Polling Pipeline
Section titled “TUI Polling Pipeline”The TUI runs multiple concurrent polling loops:
Session Polling (500ms)
Section titled “Session Polling (500ms)”Timer tick │ ▼Read ~/.claude-sessions/*.json │ ▼Parse each JSON file → []session.Info │ ▼Cross-reference with `tmux list-sessions` │ ├── Remove entries with no matching tmux session │ ▼SortSessions() │ ├── Priority statuses first (waiting, permission) ├── Priority teammates next (agents needing attention) └── Then by timestamp (most recent first) │ ▼Send sessionsMsg to Update │ ▼Re-render viewGit Info Polling
Section titled “Git Info Polling”Session list updated / Timer tick │ ▼For each session with a CWD: │ ├── Check cache (5s TTL, 10s max age) │ ├── Cache hit → skip │ └── Cache miss ▼ │ ▼Run git commands in CWD │ ├── git branch --show-current ├── git status --porcelain ├── git rev-list --count @{upstream}..HEAD └── git log -1 --format="%h %s" │ ▼Send gitInfoMsg to UpdateToken Metrics
Section titled “Token Metrics”Session CWD │ ▼Convert to Claude project path /home/user/project → -home-user-project │ ▼Find most recent .jsonl in ~/.claude/projects/<path>/ │ ▼Parse JSONL for assistant messages with usage data │ ▼Aggregate: input_tokens + cache_read + cache_creation → total input output_tokens → total outputTask Polling (30s)
Section titled “Task Polling (30s)”Timer tick / Manual refresh │ ▼Discover .navi.yaml files │ ▼For each project config: │ ├── Check cache (configurable TTL) │ ├── Cache hit → skip │ └── Cache miss ▼ │ ▼Execute provider script with args │ ▼Parse JSON output → ProviderResult │ ▼Send to Update → render task panelMessage Flow in the TUI
Section titled “Message Flow in the TUI”The Bubble Tea Update function processes messages in priority order:
- Dialog mode — Route to dialog-specific handler
- Task panel focus — Route to task panel handler
- Preview focus — Route to preview handler
- Search mode — Route to search handler
- Main keybindings — Handle navigation, actions, toggles
- Async messages — Process polling results, command outputs