Learn as Claude builds.
A learning companion for the vibe coding era. vibe-learn watches what Claude Code does during a session and helps you understand what was built, why, and how — at your own pace.
Vibe coding is fast. Claude writes 15 files, refactors a module, installs three dependencies — and you hit "accept" on all of it. A week later you can't debug your own app because you never really understood what was built.
The faster AI gets at coding, the wider the gap between what was built and what you understand. vibe-learn closes that gap.
vibe-learn hooks into Claude Code's event system. As Claude works, lightweight scripts silently observe and log every action — files created, commands run, patterns used. After each response, a summary of what just happened is injected into Claude's context so it can surface it naturally.
┌─────────────────────────────────────────────────────────┐
│ CLAUDE CODE SESSION │
│ │
│ SessionStart → UserPrompt → [Tool Use]* → Stop │
│ ↓ ↓ ↓ ↓ │
│ [Bootstrap] [Capture] [Observe] [Summarise] │
└───────┬──────────────┬───────────┬────────────┬──────────┘
↓ ↓ ↓ ↓
┌─────────────────────────────────────────────────────────┐
│ .vibe-learn/ │
│ │
│ session-log.jsonl ← raw event stream (append-only) │
│ session-meta.json ← counters, timestamps │
│ pause-summary.txt ← "here's what just happened" │
└─────────────────────────────────────────────────────────┘
Hook lifecycle:
| Hook | When it fires | What it does |
|---|---|---|
SessionStart |
When you open a project | Creates .vibe-learn/, rotates old logs |
UserPromptSubmit |
When you send a message | Logs your intent |
PostToolUse |
After each Write/Edit/Bash | Appends a JSONL entry (<50ms, sync) |
Stop |
After each Claude response | Writes and injects a pause summary |
No AI, no API calls, no external services. Just a fast, reliable data pipeline.
curl -fsSL https://raw.githubusercontent.com/gkaria/vibe-learn/main/scripts/setup.sh | bashThis installs vibe-learn to ~/.vibe-learn/ and creates a vibe-learn CLI command at ~/.local/bin/vibe-learn.
Then, inside any project you want to instrument:
vibe-learn install
# or, if ~/.local/bin isn't in your PATH yet:
~/.vibe-learn/scripts/install.shThe install script:
- Creates
.claude/commands/with the/learnand/digestslash commands - Writes
.claude/settings.local.jsonwith the hook config - Adds
.vibe-learn/to.gitignore
Requires: jq — install with brew install jq (macOS) or apt-get install jq (Linux).
Updating: re-run the same curl command to update to the latest version.
git clone https://github.com/gkaria/vibe-learn.git
# Install into a project from the local clone
bash /path/to/vibe-learn/scripts/install.sh /path/to/your/project
# Or test setup.sh locally without a network round-trip
bash /path/to/vibe-learn/scripts/setup.sh --localAdd to your project's .claude/settings.local.json:
{
"hooks": {
"SessionStart": [
{"hooks": [{"type": "command", "command": "/path/to/vibe-learn/scripts/bootstrap.sh"}]}
],
"UserPromptSubmit": [
{"hooks": [{"type": "command", "command": "/path/to/vibe-learn/scripts/capture-prompt.sh"}]}
],
"PostToolUse": [
{"matcher": "Write|Edit|MultiEdit|Bash", "hooks": [{"type": "command", "command": "/path/to/vibe-learn/scripts/observe.sh"}]}
],
"Stop": [
{"hooks": [{"type": "command", "command": "/path/to/vibe-learn/scripts/pause-summary.sh"}]}
]
}
}Copy .claude/commands/learn.md and .claude/commands/digest.md into your project's .claude/commands/.
After installing, try this in any project to see vibe-learn in action:
# 1. Install vibe-learn into a test project
mkdir /tmp/demo-app && cd /tmp/demo-app
~/.vibe-learn/scripts/install.sh
# 2. Simulate a session — bootstrap, then a few tool events
echo '{"session_id":"demo","cwd":"/tmp/demo-app"}' | bash ~/.vibe-learn/scripts/bootstrap.sh
echo '{"cwd":"/tmp/demo-app","prompt":"Build me a REST API with auth"}' \
| bash ~/.vibe-learn/scripts/capture-prompt.sh
echo '{"cwd":"/tmp/demo-app","tool_name":"Write","tool_input":{"file_path":"src/app.ts"},"tool_response":{}}' \
| bash ~/.vibe-learn/scripts/observe.sh
echo '{"cwd":"/tmp/demo-app","tool_name":"Bash","tool_input":{"command":"npm install express"},"tool_response":{"exit_code":0}}' \
| bash ~/.vibe-learn/scripts/observe.sh
# 3. Generate a pause summary
echo '{"cwd":"/tmp/demo-app"}' | bash ~/.vibe-learn/scripts/pause-summary.sh
# 4. See what vibe-learn captured
cat /tmp/demo-app/.vibe-learn/session-log.jsonl | jq .
cat /tmp/demo-app/.vibe-learn/pause-summary.txtIn real use, you don't run any of this manually — Claude Code triggers the hooks automatically. This just shows what's happening behind the scenes.
Without vibe-learn — Claude writes 12 files, installs 4 packages, refactors a module. You hit "accept" on everything. A week later:
You: "Wait, why is there a middleware folder?"
You: "What does this bcrypt thing do?"
You: "Did I even need all these dependencies?"
With vibe-learn — the same session, but now you have a trail:
⏸ vibe-learn — what just happened:
Goal: Build a REST API with JWT authentication
✦ Created src/index.ts
✦ Created src/middleware/auth.ts
✦ Created src/routes/auth.ts
✦ Ran: npm install express jsonwebtoken bcryptjs
✦ Edited src/index.ts
✦ Ran: npx tsc --noEmit ✓
Use /learn to understand any of these decisions, or /digest for a full session report.
Then ask /learn why did Claude use middleware? or run /digest for a full breakdown of what was built, key decisions, patterns used, and topics to study next.
Once installed, vibe-learn runs silently. You don't need to do anything differently — just use Claude Code as normal.
After each response, if Claude made changes, a summary appears showing what just happened:
⏸ vibe-learn — what just happened:
Goal: add JWT auth middleware
✦ Created src/middleware/auth.ts
✦ Edited src/routes/user.ts
✦ Ran: npm install jsonwebtoken
Use /learn to understand any of these decisions, or /digest for a full session report.
Slash commands (available mid-session or at end):
No arguments — explains the most recent actions: what was built, decisions made, patterns used.
With a question — answers it grounded in your actual session and code:
/learn why did Claude use middleware here?
/learn what does the auth flow do?
/learn explain the database connection setup
Generates a full structured learning report for the session:
- What Was Built — plain-language summary
- Key Decisions — why Claude made specific choices
- Patterns Used — techniques and concepts from the code
- Things to Study — a checklist of topics to explore further
Optionally saves to .vibe-learn/digests/ as a markdown file.
your-project/
└── .vibe-learn/
├── session-log.jsonl ← raw event log (one JSON entry per line)
├── session-log.prev.jsonl ← previous session's log (kept as backup)
├── session-meta.json ← session stats and config
├── pause-summary.txt ← last pause summary
└── digests/ ← saved /digest reports (if you choose to save)
Useful log queries:
# Watch events in real-time
tail -f .vibe-learn/session-log.jsonl
# See all files Claude created
jq 'select(.tool=="Write")' .vibe-learn/session-log.jsonl
# See all bash commands run
jq 'select(.tool=="Bash") | .command' .vibe-learn/session-log.jsonlEdit config/defaults.json:
{
"log_dir": ".vibe-learn",
"max_log_size_mb": 10,
"rotate_on_session_start": true,
"pause_summary_max_lines": 20,
"capture_prompts": true,
"digest_min_events": 3
}| Option | Default | Description |
|---|---|---|
log_dir |
.vibe-learn |
Where to store logs (relative to project root) |
max_log_size_mb |
10 |
Max log file size before rotation |
rotate_on_session_start |
true |
Keep previous log as .prev.jsonl on new session |
pause_summary_max_lines |
20 |
Max lines in the pause summary |
capture_prompts |
true |
Log your messages (disable for privacy) |
digest_min_events |
3 |
Minimum events before /digest generates a report |
chmod +x scripts/*.sh
# Test bootstrap
echo '{"session_id":"test123","cwd":"/tmp/test-vl"}' | bash scripts/bootstrap.sh
ls /tmp/test-vl/.vibe-learn/
# Test observe (Write event)
echo '{"cwd":"/tmp/test-vl","tool_name":"Write","tool_input":{"file_path":"src/app.ts"},"tool_response":{}}' | bash scripts/observe.sh
cat /tmp/test-vl/.vibe-learn/session-log.jsonl
# Test observe (Bash event)
echo '{"cwd":"/tmp/test-vl","tool_name":"Bash","tool_input":{"command":"npm install express"},"tool_response":{"exit_code":0}}' | bash scripts/observe.sh
# Test capture-prompt
echo '{"cwd":"/tmp/test-vl","prompt":"Build me an Express API with auth"}' | bash scripts/capture-prompt.sh
# Test pause-summary
echo '{"cwd":"/tmp/test-vl"}' | bash scripts/pause-summary.sh
cat /tmp/test-vl/.vibe-learn/pause-summary.txt
rm -rf /tmp/test-vl- Bash — POSIX-compatible
- jq — JSON processing (
brew install jq/apt-get install jq) - Claude Code — with hooks support
- Phase 3: Cross-session learning history, difficulty level adaptation, plugin registry publishing
Contributions welcome. Best contributions right now:
- Bug reports and edge cases in the hook scripts
- Testing on different OS/shell environments
- Ideas for improving the pause summary or slash command prompts
Please open an issue before submitting a pull request for anything significant.
MIT — see LICENSE.
Copyright © 2026 Gaurang Karia.