Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion data/concept-tree.json
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,36 @@
"triggers": ["cache", "redis", "CDN", "load balancer"]
}
}
},
"debugging": {
"name": "Debugging",
"icon": "🐛",
"belt_requirement": "white",
"concepts": {
"error-reading": {
"name": "Error Reading",
"xp_to_master": 15,
"prerequisites": [],
"description": "Understanding error messages and stack traces",
"triggers": ["error", "Error:", "Traceback", "ENOENT", "stack trace"]
},
"debugging-mindset": {
"name": "Debugging Mindset",
"xp_to_master": 20,
"prerequisites": ["error-reading"],
"description": "Systematic approach to finding and fixing bugs",
"triggers": ["debug", "breakpoint", "console.log", "print("]
},
"common-errors": {
"name": "Common Errors",
"xp_to_master": 25,
"prerequisites": ["error-reading", "debugging-mindset"],
"description": "Recognizing and fixing common programming errors",
"triggers": ["TypeError", "ReferenceError", "SyntaxError", "undefined", "null"]
}
}
}
},
"total_concepts": 42,
"total_concepts": 45,
"mastery_quiz_threshold": 3
}
45 changes: 45 additions & 0 deletions data/quiz-bank.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,51 @@
"expected_understanding": "Docker packages an app with all its dependencies so it runs the same everywhere. Solves 'works on my machine' problems by creating consistent environments.",
"hint": "Think about shipping a complete kitchen vs. just a recipe."
}
],
"error-reading": [
{
"belt": "white",
"question": "What does a stack trace show you?",
"options": ["The list of files in your project", "The sequence of function calls that led to the error", "All the variables currently in memory"],
"correct": 1,
"explanation": "A stack trace is like a breadcrumb trail — it shows every function that was called, in order, up until the crash. Reading it from bottom to top tells you where the error originated and how the code got there.",
"hint": "Think of it as a history of every step the program took before it fell over."
},
{
"belt": "white",
"question": "What is the first thing you should read in an error message?",
"options": ["The line number at the very bottom", "The error type and the first line of the message", "The full stack trace from top to bottom"],
"correct": 1,
"explanation": "The error type (like `TypeError` or `SyntaxError`) and the first descriptive line tell you WHAT went wrong. Once you know what, you can use the line number and stack trace to figure out WHERE. Start at the top, not the bottom.",
"hint": "Skimming a news article — you read the headline first, then the details."
}
],
"debugging-mindset": [
{
"belt": "yellow",
"question": "What is the most effective first step when debugging?",
"options": ["Delete the code and rewrite it from scratch", "Reproduce the error reliably, then read the error message carefully", "Ask someone else to fix it"],
"correct": 1,
"explanation": "You can't fix what you can't consistently reproduce. Once you can make the bug happen on demand, read the error message carefully — it usually tells you exactly what went wrong and where. Only after understanding the error should you start changing code.",
"hint": "A doctor diagnoses before prescribing. What's the equivalent first step for a bug?"
}
],
"common-errors": [
{
"belt": "orange",
"question": "What typically causes a ReferenceError in JavaScript?",
"options": ["Using the wrong data type in a calculation", "Trying to use a variable that hasn't been declared or is out of scope", "A typo in an HTML tag"],
"correct": 1,
"explanation": "A `ReferenceError` means JavaScript looked for a variable name and couldn't find it anywhere in scope. Common causes: misspelling the variable name, using it before declaring it, or accessing it outside the block where it was defined.",
"hint": "The error name says 'reference' — what does it mean when a reference points to nothing?"
},
{
"belt": "orange",
"format": "free_response",
"question": "What's the difference between a syntax error and a runtime error? Give an example of each.",
"expected_understanding": "A syntax error is caught before the code runs — it's a grammar mistake the interpreter can't parse (e.g., missing closing bracket). A runtime error happens while the code is running, when an operation fails on valid-looking code (e.g., calling a method on null).",
"hint": "Think about the difference between a grammatically incorrect sentence and a sentence that makes sense but describes something impossible."
}
]
}
}
51 changes: 51 additions & 0 deletions scripts/track-command.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,60 @@ if command -v jq &> /dev/null; then
# Sanitize command for JSON (remove quotes and special chars)
SAFE_CMD=$(echo "$COMMAND" | head -c 80 | tr '"' "'" | tr '\\' '/')

# Check if this is a test runner command — skip error detection for those
IS_TEST_RUNNER="false"
case "$COMMAND" in
jest\ *|"jest"|\
pytest\ *|"pytest"|\
vitest\ *|"vitest"|\
bats\ *|"bats"|\
mocha\ *|"mocha"|\
"npm test"*|"npm run test"*|\
"yarn test"*|"yarn run test"*|\
"npx jest"*|"npx vitest"*)
IS_TEST_RUNNER="true"
;;
esac

# Detect error patterns in command output (only for non-test-runner commands)
ERROR_CONCEPT=""
if [ "$IS_TEST_RUNNER" = "false" ]; then
TOOL_RESPONSE=$(echo "$INPUT" | jq -r '.tool_response // ""' 2>/dev/null || echo "")
STDOUT=$(echo "$INPUT" | jq -r '.tool_response.stdout // ""' 2>/dev/null || echo "")
STDERR=$(echo "$INPUT" | jq -r '.tool_response.stderr // ""' 2>/dev/null || echo "")
OUTPUT="${STDOUT}${STDERR}${TOOL_RESPONSE}"

case "$OUTPUT" in
*"Traceback (most recent call last):"*)
ERROR_CONCEPT="error-reading"
;;
*"TypeError"*|*"ReferenceError"*|*"SyntaxError"*)
ERROR_CONCEPT="common-errors"
;;
*"Error:"*|*"ERROR:"*|*"error:"*)
ERROR_CONCEPT="error-reading"
;;
*"ENOENT"*|*"EACCES"*|*"EPERM"*)
ERROR_CONCEPT="error-reading"
;;
*"command not found"*)
ERROR_CONCEPT="error-reading"
;;
*"ModuleNotFoundError"*|*"ImportError"*)
ERROR_CONCEPT="error-reading"
;;
*"fatal:"*)
ERROR_CONCEPT="error-reading"
;;
esac
fi

if [ "$IS_FIRST_EVER" = "true" ] && [ -n "$CONCEPT" ]; then
# First-time encounter: micro-lesson about the concept
CONTEXT="🥋 CodeSensei micro-lesson trigger: The user just encountered '$CONCEPT' for the FIRST TIME (command: $SAFE_CMD). Their belt level is '$BELT'. Provide a brief 2-sentence explanation of what $CONCEPT means and why it matters. Adapt language to their belt level. Keep it concise and non-intrusive."
elif [ -n "$ERROR_CONCEPT" ]; then
# Error detected in command output: teach debugging
CONTEXT="🥋 CodeSensei inline insight: An error appeared in the command output ($SAFE_CMD). The user's belt level is '$BELT'. This is a great moment to teach '$ERROR_CONCEPT' — briefly explain how to read and interpret this type of error in 1-2 sentences, adapted to their belt level. Keep it supportive and practical."
elif [ -n "$CONCEPT" ]; then
# Already-seen concept: brief inline insight about this specific command
CONTEXT="🥋 CodeSensei inline insight: Claude just ran a '$CONCEPT' command ($SAFE_CMD). The user's belt level is '$BELT'. Provide a brief 1-sentence explanation of what this command does, adapted to their belt level. Keep it natural and non-intrusive."
Expand Down