In this blog post, we will see how a small Python script called Pleasantries can stop your AI coding CLI from burning a full model call every time you type "hi", "ok", or "thank you". I built this after noticing how often my own prompts to Claude Code and Qwen Code started with a greeting out of pure habit, and how each one quietly cost tokens and time for zero task value.
Pleasantries is a lightweight Python pre-hook script that intercepts greeting-only prompts before they reach an AI coding CLI model. It uses regex fullmatch logic to block inputs like "hi," "thank you," or "ok" while allowing prompts that contain pleasantry words but carry a real task.
The tool supports 15 AI coding CLIs, including Claude Code, Gemini CLI, and Cursor, and installs via a single Python script with no external dependencies. Users can customize the blocklist and add new CLI adapters with minimal effort.
1. Why I built Pleasantries
Pleasantries is a pre-hook script for AI coding CLIs. It blocks pleasantry-only prompts like "hi", "hello", "ok", and "thank you" before they ever reach the model.
Here is the observation that started this. AI coding assistants are task tools, not chat buddies. Every "hello" still triggers a full round trip: the CLI reads it, sends it to the model, and the model replies. That is a wasted call, wasted tokens, and a small break in your flow, all for a prompt that carries no actual task.
I spend a lot of my time thinking about efficiency, whether that is a load test or a model call, so this felt like an easy win to automate away.
2. How it works
The idea is simple. A hook intercepts your prompt before it reaches the model:
You type "hi" --> Hook reads prompt --> Regex fullmatch --> Blocked
You type "fix auth bug" --> Hook reads prompt --> No match --> Prompt proceeds
Under the hood, the matcher normalizes your input (lowercase, strip punctuation, collapse whitespace) and checks if the entire prompt is a pleasantry using a fullmatch, not a partial match. That distinction matters a lot. Prompts that contain a pleasantry word but also carry a real task pass through untouched.
Each CLI has its own way of blocking a prompt once the hook decides to reject it, as shown below:
| Block method | CLIs |
|---|---|
| stderr + exit code 2 | Claude, Kiro, Copilot Chat, Copilot CLI, Cursor, Factory Droid, Kimi Code, Devin |
JSON {"decision": "block"} + exit 0 |
Codex |
JSON {"decision": "deny"} + exit 0 |
Gemini |
3. Which AI coding CLIs are supported
Pleasantries currently hooks into 15 CLIs, including Claude Code, Codex CLI, Gemini CLI, Cursor, Copilot Chat, Copilot CLI, Qwen Code, Junie CLI, Factory Droid, Kimi Code, grok-cli, Kun, Open Interpreter, Kiro, and Devin CLI.
A few tools do not have a hook system to plug into yet, so they are not supported: CodeBuddy, OpenCode, Aider, Kilo Code, Trae, Hermes, Pi, OpenClaw, Amp, Google Antigravity, Cline, oh-my-pi, Freebuff, and Command Code.
4. A quick example
Say you fire up Claude Code and type "hi" out of habit before getting to your real ask. With the hook installed, that prompt never reaches the model:
| Prompt | Result |
|---|---|
hi |
Blocked |
thank you so much |
Blocked |
fix the login bug |
Allowed |
hello world program in python |
Allowed |
Notice the last two rows. "hello world program in python" contains the word hello, but it is clearly a real task, so it sails through. That fullmatch logic is what keeps this from being an annoying false-positive machine.
5. Installing it in under a minute
Head to github.com/QAInsights/pleasantries and clone the repo. Then run the installer:
python install.py
The installer will:
- Copy
block_pleasantries.pyto~/.pleasantries/ - Detect which AI coding CLIs are installed on your machine
- Let you pick which ones to hook
- Merge the hook into each CLI's config, skipping anything already installed
If you would rather wire it up by hand, here is the Claude Code config as an example. Add this to ~/.claude/settings.json:
{
"hooks": {
"UserPromptSubmit": [
{ "hooks": [{ "type": "command",
"command": "python3 /path/to/block_pleasantries.py claude",
"timeout": 5 }] }
]
}
}
Swap in the real path to block_pleasantries.py, and you are set. Every other supported CLI follows the same pattern with its own config file, all documented in the README.
To remove every hook later:
python install.py --uninstall
Requirements are light: Python 3.10+, no external dependencies beyond the standard library (json, re, sys), and it runs on macOS, Linux, and Windows.
6. Customizing the blocklist
The blocklist lives in the PLEASANTRY_PATTERNS regex inside block_pleasantries.py, grouped by category:
- Greetings: hi, hello, hey, howdy, good morning, and similar
- Acknowledgments: ok, sure, yeah, got it
- Thanks: thank you, thanks, thx, ty
- Please: please, pls, plz
- Farewells: bye, goodbye, see ya, later
If your team has its own shorthand, like a Slack-style "yo" or "np", just add it to the matching category and the hook picks it up on the next run.
Adding support for a brand new CLI is just as simple, since the core matcher is CLI-agnostic and each CLI only needs a small adapter function to plug into the shared ADAPTERS dict.
7. Wrap up
Pleasantries is a small tool solving a small but real problem. If you run multiple AI coding CLIs day to day and catch yourself typing "hi" before your actual ask, this hook quietly saves you a wasted model call every single time.
Happy Testing!
Do you type greetings to your AI coding assistant out of habit too, or am I the only one guilty of that?



Top comments (0)