[FEATURE] Safe, Declarative Response Text Substitutions (Post-Render Transforms)
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
LLMs persistently use certain typographic patterns (em dashes, placeholder text like [Your Name], curly quotes) despite explicit instructions in CLAUDE.md and system prompts. These instructions are advisory and the model routinely ignores them. There is currently no deterministic way to clean up Claude Code's conversational/terminal output before it renders to the user.
Hooks solve this problem for file writes (PostToolUse on Write/Edit), but the chat response text has no equivalent interception point.
Why a generic response-transform hook is dangerous
An open-ended hook that lets users run arbitrary scripts on response text before rendering would effectively be a post-guardrail injection point. A malicious or careless script could strip safety refusals, rewrite disclaimers, or make Claude appear to say things it never generated. This would undermine Anthropic's safety architecture.
Proposed Solution
Instead of an arbitrary transform hook, provide a safe, declarative configuration for simple text replacements. Example in .claude/settings.json:
json{
"responseSubstitutions": [
{ "find": "\u2014", "replace": ", " },
{ "find": "\u2013", "replace": "- " },
{ "find": "[Your Name]", "replace": "Jay Chetty" },
{ "find": "\u201c", "replace": "\"" },
{ "find": "\u201d", "replace": "\"" }
]
}
Safety constraints Anthropic could enforce:
Plain string matching only (no regex, no scripts)
Maximum replacement length cap (e.g., 100 characters) to prevent injecting large blocks of text
Replacements cannot target or remove known safety-critical patterns (refusal phrases, warning prefixes)
A short allowlist of substitution categories could further limit scope: typographic normalization, placeholder fill-in, locale formatting
Substitutions are visible in settings and auditable
Alternative Solutions
CLAUDE.md instructions: Advisory only. The model ignores them unpredictably.
PostToolUse hooks on file writes: Works for files but not chat output.
A full response-transform hook: Too dangerous for the reasons described above.
Priority
Critical - Blocking my work
Feature Category
CLI commands and flags
Use Case Example
I'm a security architect using Claude Code to draft architecture documents, threat models, and technical proposals. My writing style strictly avoids em dashes. I have this rule in my CLAUDE.md, in my system prompt, and I've told the model directly in conversation. Despite all of this, roughly 1 in 3 responses still contain em dashes.
Step-by-step scenario:
I ask Claude Code to draft a threat model section for an AI inference pipeline.
Claude generates a solid technical response, but the chat output contains: The attestation service validates the TEE report — including the firmware measurement chain — before releasing decryption keys.
I notice the em dashes, sigh, and manually ask Claude to rewrite without them.
Claude rewrites. Two paragraphs later in the same response, there's another em dash.
I copy the text out of the terminal into my document and do a manual find-and-replace.
This cycle repeats across every session, every day.
With the proposed responseSubstitutions config, I would add { "find": "\u2014", "replace": ", " } once and never think about it again. The fix is deterministic, costs zero tokens, requires no re-prompting, and doesn't touch the model's actual generation or safety behavior. It's a cosmetic pass on the rendered output, the same thing I'm already doing by hand every single time.
The same pattern applies to users who always have to fix [Your Name] placeholders, or teams that prefer straight quotes over curly quotes. These are all surface-level text preferences that prompt instructions cannot reliably enforce.
Additional Context
This is a small feature that solves a real and persistent pain point. The constrained design preserves Anthropic's safety guarantees while giving users deterministic control over surface-level formatting in chat responses.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗