feat: support dynamic statusMessage interpolation for hooks

Resolved 💬 3 comments Opened Apr 8, 2026 by arazvan-ec Closed Apr 12, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

feat: support dynamic statusMessage interpolation for hooks

---

Problem

Hook statusMessage in .claude/settings.json is a static string. When hooks fire on tool calls, the activity log shows repeated generic labels like "After tool use: Edit" with no indication of which file is being processed or what the hook is doing.

In a typical session with 30+ tool calls, this produces 60-100 identical entries that provide no useful feedback to the user.

Current behavior

{
  "matcher": "Read|Write|Edit|Agent",
  "hooks": [{
    "type": "command",
    "command": "/path/to/hook.sh",
    "statusMessage": "Processing..."
  }]
}

Activity log shows:

- After tool use: Edit    → "Processing..."
- After tool use: Edit    → "Processing..."
- After tool use: Edit    → "Processing..."

No way to tell which file or what action each entry corresponds to.

Desired behavior

Allow statusMessage to interpolate variables from the hook context:

{
  "statusMessage": "Processing: {{tool_input.file_path}}"
}

Activity log would then show:

- After tool use: Edit    → "Processing: src/Controller/VehicleController.php"
- After tool use: Edit    → "Processing: .claude/settings.json"
- After tool use: Edit    → "Processing: backend/config/routes.yaml"

Proposed API

Support {{variable}} interpolation in statusMessage with access to the same context available to the hook script via stdin:

| Variable | Example value |
|----------|--------------|
| {{tool_name}} | Edit |
| {{tool_input.file_path}} | src/Entity/Vehicle.php |
| {{tool_input.command}} | git push origin main |
| {{tool_input.pattern}} | *.tsx |
| {{tool_input.description}} | Search for patterns |

Fallback: if the variable is not present in the context, replace with empty string (so "{{tool_input.file_path}}" on a Bash call just shows blank, not a literal {{...}}).

Workaround attempted

We consolidated 3 PostToolUse hooks into 1 dispatcher to reduce the number of entries (3→1 per tool call). This helps but doesn't solve the readability problem — each entry still shows a generic static message.

Environment

  • Claude Code web (claude.ai/code)
  • Hooks: PreToolUse + PostToolUse with matchers for Edit|Write|Read|Bash
  • Typical session: 30-50 tool calls → 60-100 hook activity entries

Proposed Solution

Allow statusMessage to support {{variable}} interpolation using the same context object that hooks receive via stdin.

Configuration:

{
"statusMessage": "Processing: {{tool_input.file_path}}"
}

Available variables:

Variable Example
{{tool_name}} Edit
{{tool_input.file_path}} src/Entity/Vehicle.php
{{tool_input.command}} git push origin main
Fallback: If a variable is not present in the context, replace with empty string.

Alternative Solutions

Consolidated 3 PostToolUse hooks into 1 dispatcher script to reduce the number of UI entries from 3 to 1 per tool call. This reduces noise by 50% but each entry still shows a static generic message — the user still can't tell which file triggered which hook.

Priority

Medium - Would be very helpful

Feature Category

Configuration and settings

Use Case Example

I'm building a Symfony app with 20+ workflow hooks (pre-edit gates, auto-evidence tracking, status line generation)
I use Claude Code web (claude.ai/code) and the activity log shows 60-100 entries per session
Every entry says "After tool use: Edit" with statusMessage "Processing..." — all identical
With dynamic interpolation, I'd see "Processing: src/Controller/VehicleController.php" and instantly know what each hook invocation corresponds to
This would save me from expanding each entry individually to understand what happened

Additional Context

_No response_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗