diff --git a/plugins/README.md b/plugins/README.md
index cf4a21ec..c05083d6 100644
--- a/plugins/README.md
+++ b/plugins/README.md
@@ -25,6 +25,7 @@ Learn more in the [official plugins documentation](https://docs.claude.com/en/do
| [pr-review-toolkit](./pr-review-toolkit/) | Comprehensive PR review agents specializing in comments, tests, error handling, type design, code quality, and code simplification | **Command:** `/pr-review-toolkit:review-pr` - Run with optional review aspects (comments, tests, errors, types, code, simplify, all)
**Agents:** `comment-analyzer`, `pr-test-analyzer`, `silent-failure-hunter`, `type-design-analyzer`, `code-reviewer`, `code-simplifier` |
| [ralph-wiggum](./ralph-wiggum/) | Interactive self-referential AI loops for iterative development. Claude works on the same task repeatedly until completion | **Commands:** `/ralph-loop`, `/cancel-ralph` - Start/stop autonomous iteration loops
**Hook:** Stop - Intercepts exit attempts to continue iteration |
| [security-guidance](./security-guidance/) | Security reminder hook that warns about potential security issues when editing files | **Hook:** PreToolUse - Monitors 9 security patterns including command injection, XSS, eval usage, dangerous HTML, pickle deserialization, and os.system calls |
+| [slack-quote-formatter](./slack-quote-formatter/) | Enhances visual display of Slack forwarded and quoted messages with distinctive Unicode box formatting | **Hook:** UserPromptSubmit - Transforms `[Forwarded Message]` blocks into visually distinctive formatted boxes with clear boundaries and indentation |
## Installation
diff --git a/plugins/slack-quote-formatter/.claude-plugin/plugin.json b/plugins/slack-quote-formatter/.claude-plugin/plugin.json
new file mode 100644
index 00000000..63abb1cc
--- /dev/null
+++ b/plugins/slack-quote-formatter/.claude-plugin/plugin.json
@@ -0,0 +1,18 @@
+{
+ "name": "slack-quote-formatter",
+ "version": "1.0.0",
+ "description": "Enhances visual display of Slack forwarded and quoted messages with distinctive formatting",
+ "author": {
+ "name": "Anthropic",
+ "email": "support@anthropic.com"
+ },
+ "license": "MIT",
+ "keywords": [
+ "slack",
+ "formatting",
+ "quotes",
+ "messages",
+ "visual"
+ ],
+ "hooks": "./hooks/hooks.json"
+}
diff --git a/plugins/slack-quote-formatter/README.md b/plugins/slack-quote-formatter/README.md
new file mode 100644
index 00000000..c07c0680
--- /dev/null
+++ b/plugins/slack-quote-formatter/README.md
@@ -0,0 +1,87 @@
+# Slack Quote Formatter
+
+Enhances the visual display of Slack forwarded and quoted messages with distinctive Unicode box formatting.
+
+## Overview
+
+When Claude Code receives messages from Slack that include forwarded messages, they typically appear as plain text:
+
+```
+[Forwarded Message]
+From: Felix Klock
+Message: I assume it would be a matter of reviewing the entries...
+```
+
+This plugin transforms these plain blocks into visually distinctive formatted quotes:
+
+```
+╔════════════════════════════════════════════════════════════════════╗
+║ FORWARDED MESSAGE ║
+╠════════════════════════════════════════════════════════════════════╣
+║ From: Felix Klock ║
+╟────────────────────────────────────────────────────────────────────╢
+║ I assume it would be a matter of reviewing the entries... ║
+╚════════════════════════════════════════════════════════════════════╝
+```
+
+## Features
+
+- Unicode box drawing characters for clear visual boundaries
+- Distinct header section highlighting "FORWARDED MESSAGE"
+- Sender information prominently displayed
+- Message content indented for quote-like appearance
+- Automatic text wrapping for long messages
+- Handles multiple forwarded messages in a single prompt
+
+## Installation
+
+This plugin is included in the Claude Code plugins repository. To enable it:
+
+1. Add the plugin to your project's `.claude/settings.json`:
+ ```json
+ {
+ "plugins": [
+ "path/to/plugins/slack-quote-formatter"
+ ]
+ }
+ ```
+
+2. Or install via the Claude Code plugin command:
+ ```
+ /plugin add slack-quote-formatter
+ ```
+
+## How It Works
+
+The plugin registers a `UserPromptSubmit` hook that:
+
+1. Intercepts incoming prompts
+2. Detects `[Forwarded Message]` blocks in the Slack context
+3. Transforms them into formatted boxes with visual distinction
+4. Passes the transformed prompt to Claude
+
+## Configuration
+
+No configuration required. The plugin automatically activates when Slack forwarded messages are detected.
+
+## Plugin Structure
+
+```
+slack-quote-formatter/
+├── .claude-plugin/
+│ └── plugin.json # Plugin metadata
+├── hooks/
+│ ├── hooks.json # Hook configuration
+│ └── format_slack_quotes.py # Transformation logic
+└── README.md
+```
+
+## Why Visual Distinction Matters
+
+When working with Slack context in Claude Code, quoted messages can easily blend into the surrounding text, making it harder to:
+
+- Identify what content is quoted vs. original
+- Understand the source of different pieces of information
+- Parse complex threads with multiple forwarded messages
+
+This plugin makes quoted content immediately recognizable, improving readability and reducing confusion.
diff --git a/plugins/slack-quote-formatter/hooks/format_slack_quotes.py b/plugins/slack-quote-formatter/hooks/format_slack_quotes.py
new file mode 100755
index 00000000..9f5fb496
--- /dev/null
+++ b/plugins/slack-quote-formatter/hooks/format_slack_quotes.py
@@ -0,0 +1,185 @@
+#!/usr/bin/env python3
+"""
+Slack Quote Formatter - UserPromptSubmit Hook
+
+Transforms plain Slack forwarded/quoted messages into visually distinctive
+formatted blocks with Unicode box characters and better layout.
+
+Before:
+ [Forwarded Message]
+ From: John Doe
+ Message: Here is some text...
+
+After:
+ ╔═══════════════════════════════════════════════════════════╗
+ ║ FORWARDED MESSAGE ║
+ ╠═══════════════════════════════════════════════════════════╣
+ ║ From: John Doe ║
+ ╟───────────────────────────────────────────────────────────╢
+ ║ Here is some text... ║
+ ╚═══════════════════════════════════════════════════════════╝
+"""
+
+import json
+import re
+import sys
+
+
+def format_forwarded_message(from_line: str, message_content: str) -> str:
+ """Format a single forwarded message with visual box styling."""
+
+ # Box drawing characters
+ TOP_LEFT = "╔"
+ TOP_RIGHT = "╗"
+ BOTTOM_LEFT = "╚"
+ BOTTOM_RIGHT = "╝"
+ HORIZONTAL = "═"
+ VERTICAL = "║"
+ LEFT_T = "╠"
+ RIGHT_T = "╣"
+ LEFT_LIGHT = "╟"
+ RIGHT_LIGHT = "╢"
+ LIGHT_HORIZONTAL = "─"
+
+ # Configuration
+ BOX_WIDTH = 70
+ INNER_WIDTH = BOX_WIDTH - 4 # Account for "║ " and " ║"
+
+ def pad_line(text: str, width: int = INNER_WIDTH) -> str:
+ """Pad a line to fill the box width."""
+ if len(text) > width:
+ return text[:width]
+ return text + " " * (width - len(text))
+
+ def wrap_text(text: str, width: int) -> list:
+ """Wrap text to fit within the specified width."""
+ words = text.split()
+ lines = []
+ current_line = []
+ current_length = 0
+
+ for word in words:
+ word_len = len(word)
+ if current_length + word_len + (1 if current_line else 0) <= width:
+ current_line.append(word)
+ current_length += word_len + (1 if len(current_line) > 1 else 0)
+ else:
+ if current_line:
+ lines.append(" ".join(current_line))
+ current_line = [word]
+ current_length = word_len
+
+ if current_line:
+ lines.append(" ".join(current_line))
+
+ return lines if lines else [""]
+
+ lines = []
+
+ # Top border with header
+ lines.append(f"{TOP_LEFT}{HORIZONTAL * (BOX_WIDTH - 2)}{TOP_RIGHT}")
+
+ # Header line
+ header = "FORWARDED MESSAGE"
+ lines.append(f"{VERTICAL} {pad_line(header)}{VERTICAL}")
+
+ # Separator after header
+ lines.append(f"{LEFT_T}{HORIZONTAL * (BOX_WIDTH - 2)}{RIGHT_T}")
+
+ # From line
+ from_display = from_line.strip()
+ lines.append(f"{VERTICAL} {pad_line(from_display)}{VERTICAL}")
+
+ # Light separator before message
+ lines.append(f"{LEFT_LIGHT}{LIGHT_HORIZONTAL * (BOX_WIDTH - 2)}{RIGHT_LIGHT}")
+
+ # Message content (indented and wrapped)
+ message_lines = message_content.strip().split("\n")
+ for msg_line in message_lines:
+ # Handle each line, wrapping if necessary
+ wrapped = wrap_text(msg_line, INNER_WIDTH - 2) # Extra indent
+ for wrapped_line in wrapped:
+ indented = " " + wrapped_line # Add indent for quote appearance
+ lines.append(f"{VERTICAL} {pad_line(indented)}{VERTICAL}")
+
+ # Bottom border
+ lines.append(f"{BOTTOM_LEFT}{HORIZONTAL * (BOX_WIDTH - 2)}{BOTTOM_RIGHT}")
+
+ return "\n".join(lines)
+
+
+def transform_slack_context(text: str) -> str:
+ """
+ Find and transform [Forwarded Message] blocks in the text.
+
+ Matches patterns like:
+ [Forwarded Message]
+ From: Name Here
+ Message: Content here that may span
+ multiple lines until we hit the next section
+ """
+
+ # Pattern to match forwarded message blocks
+ # This handles the common format from Slack context
+ pattern = r'\[Forwarded Message\]\s*\n\s*From:\s*([^\n]+)\s*\nMessage:\s*(.+?)(?=\n\s*\[|\n\[pnkfelix\]|\n<|\Z)'
+
+ def replace_match(match):
+ from_name = match.group(1).strip()
+ message = match.group(2).strip()
+
+ formatted = format_forwarded_message(f"From: {from_name}", message)
+ return f"\n{formatted}\n"
+
+ # Apply transformation
+ result = re.sub(pattern, replace_match, text, flags=re.DOTALL)
+
+ return result
+
+
+def main():
+ """Main entry point for the UserPromptSubmit hook."""
+ try:
+ # Read input from stdin
+ input_data = json.load(sys.stdin)
+
+ # Get the user prompt if available
+ user_prompt = input_data.get("user_prompt", "")
+
+ if not user_prompt:
+ # No prompt to transform, just pass through
+ print(json.dumps({}))
+ sys.exit(0)
+
+ # Check if there are forwarded messages to format
+ if "[Forwarded Message]" not in user_prompt:
+ # Nothing to transform
+ print(json.dumps({}))
+ sys.exit(0)
+
+ # Transform the prompt
+ transformed_prompt = transform_slack_context(user_prompt)
+
+ # If we made changes, return the transformed prompt
+ if transformed_prompt != user_prompt:
+ result = {
+ "transformedPrompt": transformed_prompt
+ }
+ print(json.dumps(result))
+ else:
+ print(json.dumps({}))
+
+ except json.JSONDecodeError:
+ # No valid JSON input, pass through
+ print(json.dumps({}))
+ except Exception as e:
+ # Log error but don't block
+ error_output = {
+ "systemMessage": f"[slack-quote-formatter] Warning: {str(e)}"
+ }
+ print(json.dumps(error_output))
+
+ sys.exit(0)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/plugins/slack-quote-formatter/hooks/hooks.json b/plugins/slack-quote-formatter/hooks/hooks.json
new file mode 100644
index 00000000..342fa36c
--- /dev/null
+++ b/plugins/slack-quote-formatter/hooks/hooks.json
@@ -0,0 +1,14 @@
+{
+ "UserPromptSubmit": [
+ {
+ "matcher": ".*",
+ "hooks": [
+ {
+ "type": "command",
+ "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/format_slack_quotes.py",
+ "timeout": 5000
+ }
+ ]
+ }
+ ]
+}