Claude Code Hooks — Push AI Agent Activity to a Physical Display
Claude Code Hooks — Push AI Agent Activity to a Physical Display
Claude Code works autonomously. You give it a task, walk away, come back 20 minutes later — and then spend 5 minutes scrolling terminal output to figure out what happened.
For teams running multiple Claude Code sessions across different repos, the visibility problem compounds. Nobody knows what the AI agents are doing until someone checks manually.
What if every Claude Code session pushed its activity to a screen on your desk — task completions, errors, progress — the same way a CI dashboard shows pipeline status?
This tutorial shows you how to wire Claude Code's hook system into PushToDisplay so agent activity appears on any device in real time.
What you'll build
A 4-panel display where each panel shows a different aspect of Claude Code's activity:
| Panel | Hook trigger | Content |
|---|---|---|
| Panel 1 | Task completion | Summary of what was built/fixed + files changed |
| Panel 2 | Error/blocked | Red alert when the agent hits a failure or needs input |
| Panel 3 | Progress heartbeat | Current file, step count, what's happening now |
| Panel 4 | Session summary | End-of-session stats: files, lines, duration |
Your agent works. Your screen updates. You glance over and know exactly where things stand.
Prerequisites
- Claude Code installed and working (
claudeCLI available) - PushToDisplay CLI installed:
npm install -g pushtodisplay - Authenticate:
pushtodisplay auth login --api-key YOUR_KEY - Set board layout to 2×2 Grid in the app (Settings → Layout → 2×2 Grid)
How Claude Code hooks work
Claude Code supports hooks — shell commands that execute at specific lifecycle points during a session. You configure them in your project's .claude/settings.json or globally in ~/.claude/settings.json:
{
"hooks": {
"postToolExecution": "~/.claude/hooks/post-tool.sh",
"onError": "~/.claude/hooks/on-error.sh",
"postSession": "~/.claude/hooks/post-session.sh"
}
}Each hook receives context via environment variables — the tool name, result, error message, file paths, etc. We'll use these to push structured updates to the display.
Hook 1: Task completion → Panel 1
When Claude Code completes a tool execution (file write, command run, test pass), push a summary to Panel 1.
Create ~/.claude/hooks/post-tool.sh:
#!/bin/bash
# Only push on significant completions (file writes, not every read)
if [[ "$CLAUDE_TOOL" != "write_file" && "$CLAUDE_TOOL" != "run_command" ]]; then
exit 0
fi
# Determine status color
if [[ "$CLAUDE_EXIT_CODE" == "0" ]]; then
BG="#0d7a3e"
STATUS="✓ Done"
else
BG="#c0392b"
STATUS="✗ Failed"
fi
pushtodisplay send \
--panel 1 \
--background "$BG" \
--block "{\"text\": \"$STATUS: $CLAUDE_TOOL\", \"size\": \"large\", \"weight\": \"bold\", \"color\": \"#ffffff\"}" \
--block "{\"text\": \"$CLAUDE_FILE\", \"size\": \"medium\", \"color\": \"#ffffffcc\"}" \
--block "{\"text\": \"$(date '+%H:%M:%S') • $CLAUDE_SESSION_ID\", \"size\": \"small\", \"color\": \"#ffffff99\"}"Make it executable:
chmod +x ~/.claude/hooks/post-tool.shNow every time Claude Code writes a file or runs a command, your display shows what happened and whether it succeeded.
Hook 2: Error alert → Panel 2
When Claude Code hits an error — a test failure, a permission issue, or a blocked state — push a red alert to Panel 2.
Create ~/.claude/hooks/on-error.sh:
#!/bin/bash
pushtodisplay send \
--panel 2 \
--background "#c0392b" \
--full-panel \
--block "{\"text\": \"⚠️ Agent Blocked\", \"size\": \"large\", \"weight\": \"bold\", \"color\": \"#ffffff\"}" \
--block "{\"text\": \"$CLAUDE_ERROR_MESSAGE\", \"size\": \"medium\", \"color\": \"#ffffffcc\"}" \
--block "{\"text\": \"Needs attention • $(date '+%H:%M')\", \"size\": \"small\", \"color\": \"#ffffff99\"}"This uses --full-panel so the error takes over the panel space with larger text — impossible to miss from across the room.
Hook 3: Progress heartbeat → Panel 3
For long-running sessions, push periodic progress to Panel 3 so you can see what Claude Code is working on right now.
Create ~/.claude/hooks/progress.sh:
#!/bin/bash
# Called periodically or on each tool execution
STEP_COUNT="${CLAUDE_STEP_COUNT:-?}"
CURRENT_FILE="${CLAUDE_FILE:-unknown}"
ELAPSED="${CLAUDE_ELAPSED:-0s}"
pushtodisplay send \
--panel 3 \
--background "#2c3e50" \
--block "{\"text\": \"Working...\", \"size\": \"large\", \"weight\": \"bold\", \"color\": \"#ffffff\"}" \
--block "{\"text\": \"$CURRENT_FILE\", \"size\": \"medium\", \"color\": \"#ffffffcc\"}" \
--block "{\"text\": \"Step $STEP_COUNT • $ELAPSED elapsed\", \"size\": \"small\", \"color\": \"#ffffff99\"}"Glance at the screen — if it says "Working..." with a file name, the agent is still active. If the timestamp is stale, something might be stuck.
Hook 4: Session summary → Panel 4
When a Claude Code session ends, push a final summary to Panel 4 — what was accomplished overall.
Create ~/.claude/hooks/post-session.sh:
#!/bin/bash
# Collect session stats from environment
FILES_CHANGED="${CLAUDE_FILES_CHANGED:-0}"
LINES_ADDED="${CLAUDE_LINES_ADDED:-0}"
LINES_REMOVED="${CLAUDE_LINES_REMOVED:-0}"
DURATION="${CLAUDE_DURATION:-unknown}"
TASK="${CLAUDE_TASK_SUMMARY:-Session complete}"
pushtodisplay send \
--panel 4 \
--background "#1a5276" \
--block "{\"text\": \"Session Complete\", \"size\": \"large\", \"weight\": \"bold\", \"color\": \"#ffffff\"}" \
--block "{\"text\": \"$TASK\", \"size\": \"medium\", \"color\": \"#ffffffcc\"}" \
--block "{\"text\": \"$FILES_CHANGED files • +$LINES_ADDED/-$LINES_REMOVED lines • $DURATION\", \"size\": \"small\", \"color\": \"#ffffff99\"}"Come back from lunch and Panel 4 tells you: "Refactored auth module — 8 files, +142/-89 lines, 12 minutes."
Alternative: Use curl directly
If you prefer not to install the CLI in your hook scripts, call the REST API directly:
#!/bin/bash
curl -s -X POST https://api.pushtodisplay.com/v1/updates \
-H "Content-Type: application/json" \
-H "X-Api-Key: $PUSHTODISPLAY_API_KEY" \
-d "{
\"panelId\": 1,
\"background\": \"#0d7a3e\",
\"blocks\": [
{\"text\": \"$STATUS\", \"size\": \"large\", \"weight\": \"bold\", \"color\": \"#ffffff\"},
{\"text\": \"$CLAUDE_FILE\", \"size\": \"medium\", \"color\": \"#ffffffcc\"}
]
}"Same result, no dependency beyond curl.
Team setup: Multiple agents, one board
For teams with several developers running Claude Code simultaneously, assign each developer a panel — or use separate boards per developer with a shared overview board:
Option A — One board, one panel per dev:
# In each developer's hook config, set their panel
export PUSHTODISPLAY_PANEL=1 # Alice
export PUSHTODISPLAY_PANEL=2 # Bob
export PUSHTODISPLAY_PANEL=3 # Carol
export PUSHTODISPLAY_PANEL=4 # DaveA mounted TV shows the whole team's AI agent activity at a glance — who's building, who's blocked, who's idle.
Option B — Consolidate with CI:
Combine with the GitHub Actions dashboard setup. Panels 1–2 show CI/CD status, Panels 3–4 show Claude Code activity. One screen, full pipeline + AI agent visibility.
Consolidate AI agent output with everything else
The power isn't just Claude Code visibility in isolation — it's consolidating AI agent activity alongside your other development signals:
- Panel 1: GitHub Actions build/test results (from your CI workflow)
- Panel 2: Claude Code task completions
- Panel 3: Deploy status from Vercel/AWS
- Panel 4: Claude Code errors/alerts
One screen. CI, CD, and AI agent activity — all consolidated. No context-switching between GitHub, terminal, and Slack.
Get started
- Install the CLI:
npm install -g pushtodisplay - Authenticate:
pushtodisplay auth login --api-key YOUR_KEY - Create the hook scripts above in
~/.claude/hooks/ - Add the hook paths to
.claude/settings.json - Start a Claude Code session and watch the panels update
Your AI agent's work — visible at a glance, without scrolling a terminal.
Related: GitHub Actions Dashboard tutorial · CLI docs · HTTP API reference · MCP Server for Claude Code