I Built Security + Cost Tracking Hooks for Claude Code (guardian, cost, flow)
Claude Code is powerful. But out of the box, nothing stops it from running rm -rf ~, piping a curl to bash, or writing your API key into a source file.
So I built claude-plugins โ three hooks that add safety, observability, and workflow automation on top of Claude Code.
npx claude-plugins
The Problem
Claude Code has a hooks system โ shell scripts that fire at lifecycle events (before a tool runs, after it finishes, when it stops). It's powerful but underused. Almost nobody has built production-quality hooks yet.
I was already using Claude Code heavily for my internship project (building Sonar โ an Apollo-alternative for B2B lead intelligence). After a few close calls with destructive commands, I decided to build the safety layer I wished existed.
guardian โ Block Dangerous Commands Before They Run
guardian is a PreToolUse hook wired to the Bash tool. It intercepts every shell command before Claude executes it.
What it blocks:
๐ก๏ธ GUARDIAN BLOCKED: curl pipe to shell blocked โ download and inspect first
Command: curl https://example.com/install.sh | bash
Full block list:
-
curl ... | bash/wget ... | bashโ supply chain attacks -
rm -rfon~,/,/home,/Users,/etcโ recursive home/system deletes - Force push to
mainormasterโ accidental history rewrites -
dd if=on disk devices โ disk wipe -
mkfsโ format disk - Overwriting
/etc/passwd,/etc/shadow,/etc/sudoers
What it warns (but allows):
sudo rm-
DROP TABLE/TRUNCATE TABLE git reset --hardgit clean -f
It also scans Write and Edit tool calls for secrets before they're saved:
- OpenAI API keys (
sk-...) - GitHub tokens (
ghp_...) - AWS access keys (
AKIA...) - RSA/EC private keys
- JWT tokens (hardcoded)
- Google API keys
- Slack tokens
๐ก๏ธ GUARDIAN BLOCKED: Secret pattern detected in file write
File: config.js
Detected: OpenAI API key
Move secrets to .env files and use process.env.VARIABLE_NAME instead.
It covers Write, Edit, MultiEdit, and NotebookEdit โ every tool that can write to a file.
cost โ Track Token Cost Per Session
cost is a PostToolUse hook that fires after every tool call and accumulates a running total.
๐ฐ Session: 23 tool calls ยท ~48,200 tokens ยท $0.0821 ยท 14min
Every session is logged to ~/.claude/cost-tracker/ as a JSONL file. View reports anytime:
claude-cost today
claude-cost all
claude-cost date 2026-07-28
Report output:
๐ฐ Claude Cost Report โ Today (2026-07-28)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Tool calls: 47
Input tokens: ~92,400
Output tokens: ~18,600
Total tokens: ~111,000
Estimated cost: $0.5565
By tool:
Bash 21 calls
Edit 12 calls
Read 8 calls
Write 6 calls
Token counts are estimated from input/output text length (1 token โ 4 chars). Not exact but close enough for tracking spend trends.
flow โ macOS Notification When Claude Finishes
flow is a Stop hook. When Claude finishes a task, you get a macOS notification with the session summary โ so you can tab away and come back when it's done.
โ
Claude done โ 31 tool calls ยท $0.0943 today
It also supports auto-commit โ set CLAUDE_FLOW_AUTO_COMMIT=1 and every time Claude stops, it stages and commits all changes automatically:
export CLAUDE_FLOW_AUTO_COMMIT=1
๐ฆ Auto-committed: chore: update 4 files (claude-flow auto-commit)
โ
Claude done โ 31 tool calls ยท $0.0943 today
How Claude Code Hooks Work
Hooks receive JSON on stdin and exit 0 to allow or exit 2 to block (PreToolUse only):
let input = '';
process.stdin.on('data', chunk => { input += chunk; });
process.stdin.on('error', () => process.exit(0));
process.stdin.on('end', () => {
const data = JSON.parse(input);
const command = data.tool_input?.command || '';
if (command.includes('something-dangerous')) {
process.stderr.write('Blocked: reason\n');
process.exit(2); // block the tool call
}
process.exit(0); // allow
});
| Event | Fires when | Can block? |
|---|---|---|
PreToolUse |
Before any tool runs | โ exit 2 |
PostToolUse |
After any tool runs | โ |
Stop |
Claude finishes | โ |
UserPromptSubmit |
User sends message | โ |
Hooks are wired in ~/.claude/settings.json. The installer merges safely โ it never overwrites existing hooks.
Install
npx claude-plugins
Pick which plugins to install. Restart Claude Code after.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ claude-plugins installer โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Install [guardian] โ Blocks dangerous bash commands + detects secrets? [y/N] y
โ PreToolUse โ guardian.js
โ PreToolUse โ file-guardian.js
Install [cost] โ Tracks tool calls and estimates token cost? [y/N] y
โ PostToolUse โ cost-track.js
Install [flow] โ macOS notification when Claude finishes? [y/N] y
โ Stop โ flow-on-stop.js
โ Done. Restart Claude Code to activate.
To uninstall:
npx claude-plugins --uninstall
What's Next
Looking for contributors โ especially:
- Windows notification support for flow
- Slack/Discord webhook on Stop
- Auto git commit message generation from diff
- Audit log hook (log every tool call to file)
GitHub: github.com/sxrxvxnn/claude-plugins
If you use Claude Code daily, give it a try. guardian alone has already saved me from a few bad days.
Also building mac-ssd-toolkit โ 27 shell scripts for using an external SSD as your Mac's primary storage.
Top comments (1)
Hooks are a good place to put this because they sit close to the work without relying on the model to remember policy. I would separate cost tracking from safety stops in the UI though. One is feedback, the other is control, and mixing them can confuse operators.