I Rebuilt My Entire Claude Code Setup. It Learns From Every Session Now.
I was shipping features, fixing bugs, deploying trading bots with Claude Code — and still wasting the first 10 minutes of every session explaining the same things.
"Don't touch the magic numbers." "Always check for console.log before pushing." "This repo uses Australian English." "The VPS runs UTC, not AEST."
Every. Single. Session.
It cost me $234 once. I was working on a forex bot, rushed a change to a magic number, and Claude updated the entry function but missed the check_max_hold function. The old magic number still matched stuck positions. They got closed at a loss.
That $234 loss was entirely preventable. One grep across the codebase would have caught it. I didn't run the grep. Claude didn't know it should. Nobody checked.
That's when I stopped treating Claude Code as a stateless tool and started treating it as something that needs to remember.
The problem isn't Claude. It's the defaults.
Out of the box, Claude Code starts fresh every time. No memory of yesterday's debugging session. No awareness that you just spent 3 hours tracking down a race condition. No knowledge that git push to the trading bot repo should trigger a 5-point checklist, not just fire and forget.
The defaults work for quick one-off tasks. They fall apart for anyone running multiple projects — especially when some of those projects involve real money.
What I actually built
6 hooks, 4 context modes, and a continuous learning loop. The whole thing runs on bash scripts. No external dependencies, no MCP servers burning context window. Just shell scripts that fire at the right moments.
Hooks — the automation layer
Hooks are shell commands that run at specific points in Claude's lifecycle. Think of them like git hooks, but for your AI coding session.
SessionStart → Load yesterday's session context
PreToolUse(Bash) → Warn before git push with checklist
PostToolUse(Edit)→ Flag console.log in edited JS/TS files
PreCompact → Save git state before context compaction
Stop → Scan all modified files for console.log
Stop → Log session activity to daily learning fileThe one that's saved me the most grief is PreToolUse on Bash commands. Before any git push, it intercepts and shows me this:
⚠️ GIT PUSH DETECTED — Pre-push checklist:
□ Tests passing?
□ No console.log left?
□ Correct branch?
□ Changes reviewed?
Branch: main
Unpushed commits:
a1b2c3d Fix magic number in check_max_hold
e4f5g6h Update entry logic for EURUSDThat checklist would have prevented the $234 loss.
The continuous learning loop
This changed everything. When Claude finishes a response (the Stop event), a hook logs what happened:
#!/bin/bash
SESSION_FILE="$HOME/.claude/sessions/learnings/$(date +%Y-%m-%d).md"
echo "### $(date '+%H:%M %Z')" >> "$SESSION_FILE"
echo "**Files changed:**" >> "$SESSION_FILE"
git diff --name-only HEAD~1 2>/dev/null >> "$SESSION_FILE"
echo "**Diff summary:**" >> "$SESSION_FILE"
git diff --stat HEAD~1 2>/dev/null >> "$SESSION_FILE"Next session, the SessionStart hook picks this up and injects it as context. Claude starts the day knowing what changed yesterday. No more "can you remind me what we were working on?"
Context modes — different brains for different jobs
I got tired of Claude being a generalist when I needed a specialist. So I created four context modes, each injected via --system-prompt:
alias cdev='claude --system-prompt "$(cat ~/.claude/contexts/dev.md)"'
alias crev='claude --system-prompt "$(cat ~/.claude/contexts/review.md)"'
alias cres='claude --system-prompt "$(cat ~/.claude/contexts/research.md)"'
alias ctrd='claude --system-prompt "$(cat ~/.claude/contexts/trading.md)"'ctrd (trading mode) is the strictest. Born directly from the $234 mistake:
- Never rush deployments. Ever.
- Grep the entire codebase for all references before changing anything
- Verify changes line by line
- Ask for confirmation before executing anything that touches real money
The review mode (crev) turns Claude into a hostile code reviewer — severity-based checklist, security scanning, edge case hunting. I tell it to assume the code has bugs and find them.
Before and after
Before: Start session. Explain the project. Explain the conventions. Explain the gotchas. Start working. Forget to check for console.log. Push. Realise. Pull. Fix. Push again.
After: Type cdev. Claude already knows what changed yesterday, what branch I'm on, what the conventions are. I code. When I edit a JS file and leave a console.log, it warns me immediately. When I try to push, it shows the checklist. When I'm done, it logs everything for tomorrow.
What I can quantify: zero accidental console.log deployments since setting this up. Zero magic number mistakes. Zero "wait, what were we doing yesterday?" conversations.
The compaction problem
Claude Code compacts your context when it gets too long — it summarises older messages to make room. The default threshold is 95%, which means compaction hits you mid-thought and you lose whatever you were working on.
I set mine to 70% with a PreCompact hook that saves the current git state, recent diffs, and modified files before anything gets dropped:
export CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=7070% is the sweet spot I landed on. 50% was too aggressive — compacting every few messages. 95% was too late — losing context mid-task. 70% gives you enough room to finish a thought before cleanup happens.
Starting from scratch
You don't need 6 hooks and 4 context modes on day one. Start with two:
- A
SessionStarthook that loads previous context - A
Stophook that saves what happened
That's your learning loop. Everything else is refinement.
Also: watch your plugin count. Every MCP server and plugin eats into your context window. I have 19 enabled right now, which is probably too many. The everything-claude-code repo recommends keeping it under 10. I should take my own advice on that one.
The full hook config
For anyone who wants the complete setup, here's what goes in ~/.claude/settings.json:
{
"hooks": {
"SessionStart": [{
"matcher": "*",
"hooks": [{ "type": "command", "command": "bash ~/.claude/scripts/session-start.sh" }]
}],
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "bash ~/.claude/scripts/git-push-reminder.sh" }]
}],
"PostToolUse": [{
"matcher": "Edit",
"hooks": [{ "type": "command", "command": "bash ~/.claude/scripts/post-edit-console-warn.sh" }]
}],
"PreCompact": [{
"matcher": "*",
"hooks": [{ "type": "command", "command": "bash ~/.claude/scripts/pre-compact-save.sh" }]
}],
"Stop": [{
"matcher": "*",
"hooks": [{ "type": "command", "command": "bash ~/.claude/scripts/stop-check-console.sh" }]
}, {
"matcher": "*",
"hooks": [{ "type": "command", "command": "bash ~/.claude/scripts/continuous-learn.sh" }]
}]
}
}Each script is under 30 lines of bash. Nothing clever. They just run every time, without me having to remember to run them. That's the whole point.
This setup isn't magic. I still make mistakes. Claude still hallucinates sometimes. But the preventable mistakes — the ones where I knew better but forgot to check — those are gone.
The $234 loss taught me something I should have already known: the best automation isn't flashy. It's the kind that runs quietly and stops you from doing the dumb thing you were about to do.