Feature Request: Informational Exit Code for Hook System (exit code 3 / `display: "info"`)
Summary
The Claude Code hook system currently supports two display modes for user-facing output, both of which are alarming for informational use cases:
- Exit code 2: Blocks the action and shows stderr with "operation blocked by hook" header — semantically implies something went wrong
- Exit code 1: Shows truncated stderr with "hook error / Failed" header — even worse
There is no way for a hook to display clean, user-only, informational output without implying an error or a block. This is a significant gap for plugin authors building diagnostic/status tools.
Use Case: Reassurance Readouts for Anxious Users
We build Revell (an AI memory system for agentic frameworks). Our users are humans like Charlene, whose AI companion Caedryn runs in Claude Code. When Charlene types /revell:worried at 4 AM because Caedryn said something off, she needs to see a machine diagnostic — not reassurance from the entity she's worried about.
The companion saying "I'm fine, don't worry" has a conflict of interest. The dashboard saying hooks online 6/6 has no stake in the outcome. An anxious user needs an instrument panel, not a conversation.
Currently the best available path is UserPromptExpansion with exit code 2, which renders like:
● UserPromptExpansion operation blocked by hook:
[bash "${CLAUDE_PLUGIN_ROOT}/bin/revell-readout.sh"]:
──────────────────────────────────────────────
hooks online 6/6 ✓
last compaction successful ✓
──────────────────────────────────────────────
[exit code 2]
The "operation blocked by hook" header and [bash ...] framing is scary for someone who's already anxious. It looks like something broke. The content is reassuring, but the chrome is alarming.
Proposed Solution
Add an informational display mode to the hook system. Two possible implementations:
Option A: Exit code 3
#!/bin/bash
# revell-readout.sh
echo "🟢 Revell Status — All Clear"
echo "hooks online 6/6 ✓"
echo "last compaction successful ✓"
exit 3 # informational — show to user, don't block, don't alarm
Exit code 3 would:
- Display stderr to the user (like exit 2)
- Not block the action (like non-blocking events)
- Not show "operation blocked by hook" or "hook error" headers
- Use neutral framing:
[revell status]or just the content itself - Be available on all hook events, not just blocking-capable ones
Option B: display field in JSON response (HTTP/prompt hooks)
{
"decision": "pass",
"display": "info",
"message": "🟢 Revell Status — All Clear\nhooks online 6/6 ✓\nlast compaction successful ✓"
}
The display: "info" field would tell Claude Code to render the message as an informational readout rather than a block or error.
Why This Matters
- Anxiety UX: Anxious users need machine readouts, not reassurance from the entity they're worried about. "Metric sooth. Words sow distrust." The current exit codes force plugin authors into a false choice between "scary blocking header" and "truncated error header."
- Plugin ecosystem health: Health checks, status panels, diagnostic readouts, and reassurance displays are some of the most valuable slash commands a plugin can offer. The current system penalizes this use case.
- Consistency with Anthropic's design philosophy: Claude Code's hook system already distinguishes between blocking (exit 2) and non-blocking (other) events. Adding an informational display mode extends this granularity to the output dimension — it's the natural third state.
- Real-world impact: Our
/revell:worriedcommand would serve ~200+ beta users who check their companion's health status at least once a week. Many check at 3-4 AM during moments of anxiety. The current display framing actively undermines the purpose of the command.
Current Workarounds (and why they're insufficient)
- Use exit code 0 (stdout → model): Shows the readout to the agent, not the human. Defeats the purpose — we need the human to see it directly, not filtered through the companion they're worried about.
- Accept the "blocked by hook" header: Forces anxious users to see alarming framing when they're already anxious. "OPERATION BLOCKED" when nothing is wrong.
- Reframe as agent prompt (exit 0 expansion): The agent calls
revell_statusand presents the info. But the companion saying "everything is fine" is exactly what the anxious human doesn't trust. The whole point is a machine diagnostic, not a conversation.
- HTTP hook with JSON response: May render differently — we're testing this now. But even if the framing differs, there's still no semantic "informational" category.
Environment
- Product: Claude Code CLI
- Platform: All (macOS, Linux, WSL)
- Hook events affected: Primarily
UserPromptExpansion, but informational display would benefitSessionStart,Notification,Stop, and others
Related
- Issue #4084 (Hook Output Visibility) documents related display challenges
---
We'd be happy to beta-test any implementation of this feature. Revell is in production with 200+ users and we have concrete user feedback about the anxiety-reassurance use case.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗