@shaykec/bridge 0.4.25 → 0.4.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/journeys/ai-engineer.yaml +34 -0
  2. package/journeys/backend-developer.yaml +36 -0
  3. package/journeys/business-analyst.yaml +37 -0
  4. package/journeys/devops-engineer.yaml +37 -0
  5. package/journeys/engineering-manager.yaml +44 -0
  6. package/journeys/frontend-developer.yaml +41 -0
  7. package/journeys/fullstack-developer.yaml +49 -0
  8. package/journeys/mobile-developer.yaml +42 -0
  9. package/journeys/product-manager.yaml +35 -0
  10. package/journeys/qa-engineer.yaml +37 -0
  11. package/journeys/ux-designer.yaml +43 -0
  12. package/modules/README.md +52 -0
  13. package/modules/accessibility-fundamentals/content.md +126 -0
  14. package/modules/accessibility-fundamentals/exercises.md +88 -0
  15. package/modules/accessibility-fundamentals/module.yaml +43 -0
  16. package/modules/accessibility-fundamentals/quick-ref.md +71 -0
  17. package/modules/accessibility-fundamentals/quiz.md +100 -0
  18. package/modules/accessibility-fundamentals/resources.md +29 -0
  19. package/modules/accessibility-fundamentals/walkthrough.md +80 -0
  20. package/modules/adr-writing/content.md +121 -0
  21. package/modules/adr-writing/exercises.md +81 -0
  22. package/modules/adr-writing/module.yaml +41 -0
  23. package/modules/adr-writing/quick-ref.md +57 -0
  24. package/modules/adr-writing/quiz.md +73 -0
  25. package/modules/adr-writing/resources.md +29 -0
  26. package/modules/adr-writing/walkthrough.md +64 -0
  27. package/modules/ai-agents/content.md +120 -0
  28. package/modules/ai-agents/exercises.md +82 -0
  29. package/modules/ai-agents/module.yaml +42 -0
  30. package/modules/ai-agents/quick-ref.md +60 -0
  31. package/modules/ai-agents/quiz.md +103 -0
  32. package/modules/ai-agents/resources.md +30 -0
  33. package/modules/ai-agents/walkthrough.md +85 -0
  34. package/modules/ai-assisted-research/content.md +136 -0
  35. package/modules/ai-assisted-research/exercises.md +80 -0
  36. package/modules/ai-assisted-research/module.yaml +42 -0
  37. package/modules/ai-assisted-research/quick-ref.md +67 -0
  38. package/modules/ai-assisted-research/quiz.md +73 -0
  39. package/modules/ai-assisted-research/resources.md +33 -0
  40. package/modules/ai-assisted-research/walkthrough.md +85 -0
  41. package/modules/ai-pair-programming/content.md +105 -0
  42. package/modules/ai-pair-programming/exercises.md +98 -0
  43. package/modules/ai-pair-programming/module.yaml +39 -0
  44. package/modules/ai-pair-programming/quick-ref.md +58 -0
  45. package/modules/ai-pair-programming/quiz.md +73 -0
  46. package/modules/ai-pair-programming/resources.md +34 -0
  47. package/modules/ai-pair-programming/walkthrough.md +117 -0
  48. package/modules/ai-test-generation/content.md +125 -0
  49. package/modules/ai-test-generation/exercises.md +98 -0
  50. package/modules/ai-test-generation/module.yaml +39 -0
  51. package/modules/ai-test-generation/quick-ref.md +65 -0
  52. package/modules/ai-test-generation/quiz.md +74 -0
  53. package/modules/ai-test-generation/resources.md +41 -0
  54. package/modules/ai-test-generation/walkthrough.md +100 -0
  55. package/modules/api-design/content.md +189 -0
  56. package/modules/api-design/exercises.md +84 -0
  57. package/modules/api-design/game.yaml +113 -0
  58. package/modules/api-design/module.yaml +45 -0
  59. package/modules/api-design/quick-ref.md +73 -0
  60. package/modules/api-design/quiz.md +100 -0
  61. package/modules/api-design/resources.md +55 -0
  62. package/modules/api-design/walkthrough.md +88 -0
  63. package/modules/clean-code/content.md +136 -0
  64. package/modules/clean-code/exercises.md +137 -0
  65. package/modules/clean-code/game.yaml +172 -0
  66. package/modules/clean-code/module.yaml +44 -0
  67. package/modules/clean-code/quick-ref.md +44 -0
  68. package/modules/clean-code/quiz.md +105 -0
  69. package/modules/clean-code/resources.md +40 -0
  70. package/modules/clean-code/walkthrough.md +78 -0
  71. package/modules/clean-code/workshop.yaml +149 -0
  72. package/modules/code-review/content.md +130 -0
  73. package/modules/code-review/exercises.md +95 -0
  74. package/modules/code-review/game.yaml +83 -0
  75. package/modules/code-review/module.yaml +42 -0
  76. package/modules/code-review/quick-ref.md +77 -0
  77. package/modules/code-review/quiz.md +105 -0
  78. package/modules/code-review/resources.md +40 -0
  79. package/modules/code-review/walkthrough.md +106 -0
  80. package/modules/daily-workflow/content.md +81 -0
  81. package/modules/daily-workflow/exercises.md +50 -0
  82. package/modules/daily-workflow/module.yaml +33 -0
  83. package/modules/daily-workflow/quick-ref.md +37 -0
  84. package/modules/daily-workflow/quiz.md +65 -0
  85. package/modules/daily-workflow/resources.md +38 -0
  86. package/modules/daily-workflow/walkthrough.md +83 -0
  87. package/modules/debugging-systematically/content.md +139 -0
  88. package/modules/debugging-systematically/exercises.md +91 -0
  89. package/modules/debugging-systematically/module.yaml +46 -0
  90. package/modules/debugging-systematically/quick-ref.md +59 -0
  91. package/modules/debugging-systematically/quiz.md +105 -0
  92. package/modules/debugging-systematically/resources.md +42 -0
  93. package/modules/debugging-systematically/walkthrough.md +84 -0
  94. package/modules/debugging-systematically/workshop.yaml +127 -0
  95. package/modules/demo-test/content.md +68 -0
  96. package/modules/demo-test/exercises.md +28 -0
  97. package/modules/demo-test/game.yaml +171 -0
  98. package/modules/demo-test/module.yaml +41 -0
  99. package/modules/demo-test/quick-ref.md +54 -0
  100. package/modules/demo-test/quiz.md +74 -0
  101. package/modules/demo-test/resources.md +21 -0
  102. package/modules/demo-test/walkthrough.md +122 -0
  103. package/modules/demo-test/workshop.yaml +31 -0
  104. package/modules/design-critique/content.md +93 -0
  105. package/modules/design-critique/exercises.md +71 -0
  106. package/modules/design-critique/module.yaml +41 -0
  107. package/modules/design-critique/quick-ref.md +63 -0
  108. package/modules/design-critique/quiz.md +73 -0
  109. package/modules/design-critique/resources.md +27 -0
  110. package/modules/design-critique/walkthrough.md +68 -0
  111. package/modules/design-patterns/content.md +335 -0
  112. package/modules/design-patterns/exercises.md +82 -0
  113. package/modules/design-patterns/game.yaml +55 -0
  114. package/modules/design-patterns/module.yaml +45 -0
  115. package/modules/design-patterns/quick-ref.md +44 -0
  116. package/modules/design-patterns/quiz.md +101 -0
  117. package/modules/design-patterns/resources.md +40 -0
  118. package/modules/design-patterns/walkthrough.md +64 -0
  119. package/modules/exploratory-testing/content.md +133 -0
  120. package/modules/exploratory-testing/exercises.md +88 -0
  121. package/modules/exploratory-testing/module.yaml +41 -0
  122. package/modules/exploratory-testing/quick-ref.md +68 -0
  123. package/modules/exploratory-testing/quiz.md +75 -0
  124. package/modules/exploratory-testing/resources.md +39 -0
  125. package/modules/exploratory-testing/walkthrough.md +87 -0
  126. package/modules/git/content.md +128 -0
  127. package/modules/git/exercises.md +53 -0
  128. package/modules/git/game.yaml +190 -0
  129. package/modules/git/module.yaml +44 -0
  130. package/modules/git/quick-ref.md +67 -0
  131. package/modules/git/quiz.md +89 -0
  132. package/modules/git/resources.md +49 -0
  133. package/modules/git/walkthrough.md +92 -0
  134. package/modules/git/workshop.yaml +145 -0
  135. package/modules/hiring-interviews/content.md +130 -0
  136. package/modules/hiring-interviews/exercises.md +88 -0
  137. package/modules/hiring-interviews/module.yaml +41 -0
  138. package/modules/hiring-interviews/quick-ref.md +68 -0
  139. package/modules/hiring-interviews/quiz.md +73 -0
  140. package/modules/hiring-interviews/resources.md +36 -0
  141. package/modules/hiring-interviews/walkthrough.md +75 -0
  142. package/modules/hooks/content.md +97 -0
  143. package/modules/hooks/exercises.md +69 -0
  144. package/modules/hooks/module.yaml +39 -0
  145. package/modules/hooks/quick-ref.md +93 -0
  146. package/modules/hooks/quiz.md +81 -0
  147. package/modules/hooks/resources.md +34 -0
  148. package/modules/hooks/walkthrough.md +105 -0
  149. package/modules/hooks/workshop.yaml +64 -0
  150. package/modules/incident-response/content.md +124 -0
  151. package/modules/incident-response/exercises.md +82 -0
  152. package/modules/incident-response/game.yaml +132 -0
  153. package/modules/incident-response/module.yaml +45 -0
  154. package/modules/incident-response/quick-ref.md +53 -0
  155. package/modules/incident-response/quiz.md +103 -0
  156. package/modules/incident-response/resources.md +40 -0
  157. package/modules/incident-response/walkthrough.md +82 -0
  158. package/modules/llm-fundamentals/content.md +114 -0
  159. package/modules/llm-fundamentals/exercises.md +83 -0
  160. package/modules/llm-fundamentals/module.yaml +42 -0
  161. package/modules/llm-fundamentals/quick-ref.md +64 -0
  162. package/modules/llm-fundamentals/quiz.md +103 -0
  163. package/modules/llm-fundamentals/resources.md +30 -0
  164. package/modules/llm-fundamentals/walkthrough.md +91 -0
  165. package/modules/one-on-ones/content.md +133 -0
  166. package/modules/one-on-ones/exercises.md +81 -0
  167. package/modules/one-on-ones/module.yaml +44 -0
  168. package/modules/one-on-ones/quick-ref.md +67 -0
  169. package/modules/one-on-ones/quiz.md +73 -0
  170. package/modules/one-on-ones/resources.md +37 -0
  171. package/modules/one-on-ones/walkthrough.md +69 -0
  172. package/modules/package.json +9 -0
  173. package/modules/prioritization-frameworks/content.md +130 -0
  174. package/modules/prioritization-frameworks/exercises.md +93 -0
  175. package/modules/prioritization-frameworks/module.yaml +41 -0
  176. package/modules/prioritization-frameworks/quick-ref.md +77 -0
  177. package/modules/prioritization-frameworks/quiz.md +73 -0
  178. package/modules/prioritization-frameworks/resources.md +32 -0
  179. package/modules/prioritization-frameworks/walkthrough.md +69 -0
  180. package/modules/prompt-engineering/content.md +123 -0
  181. package/modules/prompt-engineering/exercises.md +82 -0
  182. package/modules/prompt-engineering/game.yaml +101 -0
  183. package/modules/prompt-engineering/module.yaml +45 -0
  184. package/modules/prompt-engineering/quick-ref.md +65 -0
  185. package/modules/prompt-engineering/quiz.md +105 -0
  186. package/modules/prompt-engineering/resources.md +36 -0
  187. package/modules/prompt-engineering/walkthrough.md +81 -0
  188. package/modules/rag-fundamentals/content.md +111 -0
  189. package/modules/rag-fundamentals/exercises.md +80 -0
  190. package/modules/rag-fundamentals/module.yaml +45 -0
  191. package/modules/rag-fundamentals/quick-ref.md +58 -0
  192. package/modules/rag-fundamentals/quiz.md +75 -0
  193. package/modules/rag-fundamentals/resources.md +34 -0
  194. package/modules/rag-fundamentals/walkthrough.md +75 -0
  195. package/modules/react-fundamentals/content.md +140 -0
  196. package/modules/react-fundamentals/exercises.md +81 -0
  197. package/modules/react-fundamentals/game.yaml +145 -0
  198. package/modules/react-fundamentals/module.yaml +45 -0
  199. package/modules/react-fundamentals/quick-ref.md +62 -0
  200. package/modules/react-fundamentals/quiz.md +106 -0
  201. package/modules/react-fundamentals/resources.md +42 -0
  202. package/modules/react-fundamentals/walkthrough.md +89 -0
  203. package/modules/react-fundamentals/workshop.yaml +112 -0
  204. package/modules/react-native-fundamentals/content.md +141 -0
  205. package/modules/react-native-fundamentals/exercises.md +79 -0
  206. package/modules/react-native-fundamentals/module.yaml +42 -0
  207. package/modules/react-native-fundamentals/quick-ref.md +60 -0
  208. package/modules/react-native-fundamentals/quiz.md +61 -0
  209. package/modules/react-native-fundamentals/resources.md +24 -0
  210. package/modules/react-native-fundamentals/walkthrough.md +84 -0
  211. package/modules/registry.yaml +1650 -0
  212. package/modules/risk-management/content.md +162 -0
  213. package/modules/risk-management/exercises.md +86 -0
  214. package/modules/risk-management/module.yaml +41 -0
  215. package/modules/risk-management/quick-ref.md +82 -0
  216. package/modules/risk-management/quiz.md +73 -0
  217. package/modules/risk-management/resources.md +40 -0
  218. package/modules/risk-management/walkthrough.md +67 -0
  219. package/modules/running-effective-standups/content.md +119 -0
  220. package/modules/running-effective-standups/exercises.md +79 -0
  221. package/modules/running-effective-standups/module.yaml +40 -0
  222. package/modules/running-effective-standups/quick-ref.md +61 -0
  223. package/modules/running-effective-standups/quiz.md +73 -0
  224. package/modules/running-effective-standups/resources.md +36 -0
  225. package/modules/running-effective-standups/walkthrough.md +76 -0
  226. package/modules/solid-principles/content.md +154 -0
  227. package/modules/solid-principles/exercises.md +107 -0
  228. package/modules/solid-principles/module.yaml +42 -0
  229. package/modules/solid-principles/quick-ref.md +50 -0
  230. package/modules/solid-principles/quiz.md +102 -0
  231. package/modules/solid-principles/resources.md +39 -0
  232. package/modules/solid-principles/walkthrough.md +84 -0
  233. package/modules/sprint-planning/content.md +142 -0
  234. package/modules/sprint-planning/exercises.md +79 -0
  235. package/modules/sprint-planning/game.yaml +84 -0
  236. package/modules/sprint-planning/module.yaml +44 -0
  237. package/modules/sprint-planning/quick-ref.md +76 -0
  238. package/modules/sprint-planning/quiz.md +102 -0
  239. package/modules/sprint-planning/resources.md +39 -0
  240. package/modules/sprint-planning/walkthrough.md +75 -0
  241. package/modules/sql-fundamentals/content.md +160 -0
  242. package/modules/sql-fundamentals/exercises.md +87 -0
  243. package/modules/sql-fundamentals/game.yaml +105 -0
  244. package/modules/sql-fundamentals/module.yaml +45 -0
  245. package/modules/sql-fundamentals/quick-ref.md +53 -0
  246. package/modules/sql-fundamentals/quiz.md +103 -0
  247. package/modules/sql-fundamentals/resources.md +42 -0
  248. package/modules/sql-fundamentals/walkthrough.md +92 -0
  249. package/modules/sql-fundamentals/workshop.yaml +109 -0
  250. package/modules/stakeholder-communication/content.md +186 -0
  251. package/modules/stakeholder-communication/exercises.md +87 -0
  252. package/modules/stakeholder-communication/module.yaml +38 -0
  253. package/modules/stakeholder-communication/quick-ref.md +89 -0
  254. package/modules/stakeholder-communication/quiz.md +73 -0
  255. package/modules/stakeholder-communication/resources.md +41 -0
  256. package/modules/stakeholder-communication/walkthrough.md +74 -0
  257. package/modules/system-design/content.md +149 -0
  258. package/modules/system-design/exercises.md +83 -0
  259. package/modules/system-design/game.yaml +95 -0
  260. package/modules/system-design/module.yaml +46 -0
  261. package/modules/system-design/quick-ref.md +59 -0
  262. package/modules/system-design/quiz.md +102 -0
  263. package/modules/system-design/resources.md +46 -0
  264. package/modules/system-design/walkthrough.md +90 -0
  265. package/modules/team-topologies/content.md +166 -0
  266. package/modules/team-topologies/exercises.md +85 -0
  267. package/modules/team-topologies/module.yaml +41 -0
  268. package/modules/team-topologies/quick-ref.md +61 -0
  269. package/modules/team-topologies/quiz.md +101 -0
  270. package/modules/team-topologies/resources.md +37 -0
  271. package/modules/team-topologies/walkthrough.md +76 -0
  272. package/modules/technical-debt/content.md +111 -0
  273. package/modules/technical-debt/exercises.md +92 -0
  274. package/modules/technical-debt/module.yaml +39 -0
  275. package/modules/technical-debt/quick-ref.md +60 -0
  276. package/modules/technical-debt/quiz.md +73 -0
  277. package/modules/technical-debt/resources.md +25 -0
  278. package/modules/technical-debt/walkthrough.md +94 -0
  279. package/modules/technical-mentoring/content.md +128 -0
  280. package/modules/technical-mentoring/exercises.md +84 -0
  281. package/modules/technical-mentoring/module.yaml +41 -0
  282. package/modules/technical-mentoring/quick-ref.md +74 -0
  283. package/modules/technical-mentoring/quiz.md +73 -0
  284. package/modules/technical-mentoring/resources.md +33 -0
  285. package/modules/technical-mentoring/walkthrough.md +65 -0
  286. package/modules/test-strategy/content.md +136 -0
  287. package/modules/test-strategy/exercises.md +84 -0
  288. package/modules/test-strategy/game.yaml +99 -0
  289. package/modules/test-strategy/module.yaml +45 -0
  290. package/modules/test-strategy/quick-ref.md +66 -0
  291. package/modules/test-strategy/quiz.md +99 -0
  292. package/modules/test-strategy/resources.md +60 -0
  293. package/modules/test-strategy/walkthrough.md +97 -0
  294. package/modules/test-strategy/workshop.yaml +96 -0
  295. package/modules/typescript-fundamentals/content.md +127 -0
  296. package/modules/typescript-fundamentals/exercises.md +79 -0
  297. package/modules/typescript-fundamentals/game.yaml +111 -0
  298. package/modules/typescript-fundamentals/module.yaml +45 -0
  299. package/modules/typescript-fundamentals/quick-ref.md +55 -0
  300. package/modules/typescript-fundamentals/quiz.md +104 -0
  301. package/modules/typescript-fundamentals/resources.md +42 -0
  302. package/modules/typescript-fundamentals/walkthrough.md +71 -0
  303. package/modules/typescript-fundamentals/workshop.yaml +146 -0
  304. package/modules/user-story-mapping/content.md +123 -0
  305. package/modules/user-story-mapping/exercises.md +87 -0
  306. package/modules/user-story-mapping/module.yaml +41 -0
  307. package/modules/user-story-mapping/quick-ref.md +64 -0
  308. package/modules/user-story-mapping/quiz.md +73 -0
  309. package/modules/user-story-mapping/resources.md +29 -0
  310. package/modules/user-story-mapping/walkthrough.md +86 -0
  311. package/modules/writing-prds/content.md +133 -0
  312. package/modules/writing-prds/exercises.md +93 -0
  313. package/modules/writing-prds/game.yaml +83 -0
  314. package/modules/writing-prds/module.yaml +44 -0
  315. package/modules/writing-prds/quick-ref.md +77 -0
  316. package/modules/writing-prds/quiz.md +103 -0
  317. package/modules/writing-prds/resources.md +30 -0
  318. package/modules/writing-prds/walkthrough.md +87 -0
  319. package/package.json +1 -1
@@ -0,0 +1,75 @@
1
+ # Technical Hiring — Walkthrough
2
+
3
+ ## Before We Begin
4
+
5
+ **Diagnostic Question:** What's the difference between a structured interview and an unstructured one? When might each be appropriate?
6
+
7
+ **Checkpoint:** You recognize that structured interviews use consistent questions and rubrics for fairness; unstructured interviews feel more natural but risk bias. Both have tradeoffs.
8
+
9
+ ---
10
+
11
+ ## Step 1: Create an Interview Scorecard
12
+
13
+ <!-- hint:list style="cards" -->
14
+
15
+ **Task:** For a role you hire for (or a hypothetical mid-level engineer), create a scorecard. List 4–6 competencies. Mark each as must-have or nice-to-have. For each, specify how you'll assess it (behavioral, technical, system design, resume).
16
+
17
+ **Question:** How do you avoid "kitchen sink" scorecards? What makes a competency truly must-have?
18
+
19
+ **Checkpoint:** Scorecard has 4–6 competencies, must/nice classification, and assessment method for each.
20
+
21
+ ---
22
+
23
+ ## Step 2: Write a Behavioral Question + Rubric
24
+
25
+ <!-- hint:buttons type="single" prompt="Which format structures behavioral answers?" options="STAR,SMART,DRY" -->
26
+
27
+ **Task:** Pick one must-have competency from your scorecard. Write a behavioral question in STAR format. Then write a 3-level rubric: strong, medium, weak. What would each look like in practice?
28
+
29
+ **Question:** How do you make the rubric useful without being rigid? What if the candidate's story doesn't fit the expected mold?
30
+
31
+ **Checkpoint:** One question and rubric; usable by another interviewer.
32
+
33
+ ---
34
+
35
+ ## Step 3: Write a Technical Question + Rubric
36
+
37
+ **Task:** Pick one technical competency. Write a coding or debugging question that's bounded (15–20 min). Write a rubric: what does strong/medium/weak look like? Include: correctness, edge cases, explanation quality.
38
+
39
+ **Question:** How do you balance "can they code?" with "can they think?"? When do hints help vs. hurt?
40
+
41
+ **Checkpoint:** Question is unambiguous; rubric has clear levels.
42
+
43
+ ---
44
+
45
+ ## Step 4: Design Your Debrief Process
46
+
47
+ **Task:** Document your debrief process: Who attends? Do interviewers score before or during? How do you resolve disagreement? What's the hire/no-hire bar? Keep it to one page.
48
+
49
+ **Question:** What happens when two interviewers strongly disagree? How do you avoid groupthink?
50
+
51
+ **Checkpoint:** Process is documented; disagreement resolution is clear.
52
+
53
+ ---
54
+
55
+ ## Step 5: Audit for Bias
56
+
57
+ <!-- hint:card type="warning" title="Bias" -->
58
+
59
+ **Task:** Review your current (or a past) interview process. List 3 potential bias sources (e.g., similarity bias, halo effect, anchoring). For each, propose one mitigation.
60
+
61
+ **Question:** What's the tension between "culture fit" and bias? How do you assess culture add without filtering for similarity?
62
+
63
+ **Checkpoint:** Three bias sources identified; three mitigations proposed.
64
+
65
+ ---
66
+
67
+ ## Step 6: Improve Candidate Experience
68
+
69
+ <!-- hint:celebrate -->
70
+
71
+ **Task:** Map the candidate journey from application to offer/reject. Identify 3 pain points (e.g., long wait, unclear feedback, disorganized onsite). Propose one improvement for each.
72
+
73
+ **Question:** What does a great candidate experience cost? What does a bad one cost?
74
+
75
+ **Checkpoint:** Journey mapped; three improvements proposed.
@@ -0,0 +1,97 @@
1
+ # Claude Code Hooks
2
+
3
+ > **Level: 🌿 Intermediate**
4
+
5
+ ## What Are Hooks?
6
+
7
+ Hooks are shell commands that Claude Code executes automatically in response to lifecycle events. They let you automate workflows without manual intervention — run linters after edits, track usage statistics, validate changes before commits, and more.
8
+
9
+ ## Lifecycle Events
10
+
11
+ | Event | When It Fires | Use Cases |
12
+ |---|---|---|
13
+ | **PostToolUse** | After any tool is used (Edit, Write, Bash, etc.) | Linting, formatting, usage tracking |
14
+ | **UserPromptSubmit** | When the user sends a message | Input validation, command detection |
15
+ | **Stop** | When the agent finishes a response | Session tracking, cleanup, notifications |
16
+
17
+ ## Configuration
18
+
19
+ Hooks are defined in `hooks.json` (for plugins) or in `.claude/settings.json` (for user hooks):
20
+
21
+ ```json
22
+ {
23
+ "hooks": {
24
+ "PostToolUse": [
25
+ {
26
+ "command": "./scripts/on-tool-use.sh",
27
+ "timeout": 5000
28
+ }
29
+ ],
30
+ "UserPromptSubmit": [
31
+ {
32
+ "command": "./scripts/on-prompt.sh",
33
+ "timeout": 3000
34
+ }
35
+ ],
36
+ "Stop": [
37
+ {
38
+ "command": "./scripts/on-stop.sh",
39
+ "timeout": 5000
40
+ }
41
+ ]
42
+ }
43
+ }
44
+ ```
45
+
46
+ ## Environment Variables
47
+
48
+ Hook scripts receive context via environment variables:
49
+
50
+ ### PostToolUse
51
+ - `TOOL_NAME` — name of the tool that was used (e.g., "Edit", "Bash")
52
+ - `TOOL_INPUT` — JSON string of the tool's input parameters
53
+ - `TOOL_OUTPUT` — JSON string of the tool's output
54
+
55
+ ### UserPromptSubmit
56
+ - `USER_PROMPT` — the text the user submitted
57
+
58
+ ### Stop
59
+ - `STOP_REASON` — why the agent stopped (e.g., "end_turn", "max_tokens")
60
+ - `TOKEN_USAGE` — JSON with input/output token counts
61
+
62
+ ## Example: Auto-Format on Edit
63
+
64
+ ```bash
65
+ #!/bin/bash
66
+ # scripts/auto-format.sh — runs after PostToolUse
67
+ if [ "$TOOL_NAME" = "Edit" ] || [ "$TOOL_NAME" = "Write" ]; then
68
+ FILE=$(echo "$TOOL_INPUT" | jq -r '.file_path // empty')
69
+ if [ -n "$FILE" ] && [ -f "$FILE" ]; then
70
+ npx prettier --write "$FILE" 2>/dev/null
71
+ fi
72
+ fi
73
+ ```
74
+
75
+ ## Example: Track Tool Usage
76
+
77
+ ```bash
78
+ #!/bin/bash
79
+ # scripts/track-usage.sh — counts tool usage per category
80
+ DATA_FILE=".local/usage.json"
81
+ CATEGORY=$(echo "$TOOL_NAME" | tr '[:upper:]' '[:lower:]')
82
+
83
+ if [ ! -f "$DATA_FILE" ]; then
84
+ echo '{}' > "$DATA_FILE"
85
+ fi
86
+
87
+ jq --arg cat "$CATEGORY" '.[$cat] = ((.[$cat] // 0) + 1)' "$DATA_FILE" > "${DATA_FILE}.tmp"
88
+ mv "${DATA_FILE}.tmp" "$DATA_FILE"
89
+ ```
90
+
91
+ ## Best Practices
92
+
93
+ 1. **Keep hooks fast** — they block the agent while running. Use the `timeout` field.
94
+ 2. **Fail gracefully** — a hook error shouldn't break the user's workflow.
95
+ 3. **Use exit codes** — exit 0 for success, non-zero to signal the agent.
96
+ 4. **Log, don't print** — write to files, not stdout (stdout goes back to the agent).
97
+ 5. **Test independently** — run your hook scripts manually before configuring them.
@@ -0,0 +1,69 @@
1
+ # Claude Code Hooks — Exercises
2
+
3
+ ## Exercise 1: Write a Linting Hook
4
+
5
+ **Task:** Create a PostToolUse hook that runs a linter (e.g., ESLint, ShellCheck, or a language-appropriate linter) on files when the Edit or Write tool is used. Only run on files that match your project's conventions (e.g., `*.js`, `*.sh`).
6
+
7
+ **Validation:**
8
+ - [ ] Hook configured in `.claude/settings.json` under PostToolUse
9
+ - [ ] Hook checks `TOOL_NAME` and only runs for Edit/Write
10
+ - [ ] File path extracted from `TOOL_INPUT` (e.g., via `jq`)
11
+ - [ ] Linter runs on the edited file and results are written to a log file (not stdout)
12
+ - [ ] Hook has a reasonable timeout (e.g., 5000ms)
13
+
14
+ **Hints:**
15
+ 1. Parse `TOOL_INPUT` with `jq`: `FILE=$(echo "$TOOL_INPUT" | jq -r '.file_path // empty')`
16
+ 2. Check file extension before invoking the linter
17
+ 3. Redirect linter output to a file: `eslint "$FILE" >> .local/lint.log 2>&1`
18
+
19
+ ---
20
+
21
+ ## Exercise 2: Write a Usage Tracking Hook
22
+
23
+ **Task:** Create a PostToolUse hook that increments a counter for each tool category in a JSON file (e.g., `.local/usage.json`). Structure: `{"edit": 5, "write": 3, "bash": 2}`. Use the hook's env vars to determine the tool.
24
+
25
+ **Validation:**
26
+ - [ ] Hook writes to a JSON file (create it if missing)
27
+ - [ ] Each tool use increments the correct key
28
+ - [ ] File is updated atomically (write to temp, then mv) to avoid corruption
29
+ - [ ] Hook exits 0 on success so it doesn't break the session
30
+
31
+ **Hints:**
32
+ 1. Use `jq` to merge: `jq --arg cat "$TOOL_NAME" '.[$cat] = ((.[$cat] // 0) + 1)' file.json`
33
+ 2. For atomic write: `jq ... file.json > file.json.tmp && mv file.json.tmp file.json`
34
+ 3. Normalize tool name: `$(echo "$TOOL_NAME" | tr '[:upper:]' '[:lower:]')`
35
+
36
+ ---
37
+
38
+ ## Exercise 3: Write a Validation Hook
39
+
40
+ **Task:** Create a UserPromptSubmit hook that checks if the user's prompt contains a blocklisted word or pattern (e.g., "delete everything"). If detected, write a warning to a file and optionally append the prompt to an audit log. Do not block the agent — just log.
41
+
42
+ **Validation:**
43
+ - [ ] Hook reads `USER_PROMPT` from the environment
44
+ - [ ] Pattern matching implemented (grep, case statement, or simple `[[ == *pattern* ]]`)
45
+ - [ ] Warning written to a file when pattern matches
46
+ - [ ] Hook fails gracefully (handles empty `USER_PROMPT`, missing files)
47
+ - [ ] Hook has a short timeout (e.g., 2000ms)
48
+
49
+ **Hints:**
50
+ 1. `if [[ "$USER_PROMPT" == *"delete everything"* ]]; then ...`
51
+ 2. Write audit trail: `echo "$(date -Iseconds) $USER_PROMPT" >> .local/audit.log`
52
+ 3. Use `set +e` or ensure script exits 0 even when pattern matches — you're logging, not blocking
53
+
54
+ ---
55
+
56
+ ## Exercise 4: Chain Multiple Hooks
57
+
58
+ **Task:** Configure at least two different hooks for the same project: (1) a PostToolUse hook that runs your linter, and (2) a Stop hook that logs token usage. Verify both run correctly in a single session.
59
+
60
+ **Validation:**
61
+ - [ ] PostToolUse hook runs during the session (check log/file output)
62
+ - [ ] Stop hook runs when the agent finishes (check log/file output)
63
+ - [ ] Both hooks are in `.claude/settings.json`
64
+ - [ ] Session completes without errors from the hooks
65
+
66
+ **Hints:**
67
+ 1. Hooks are arrays — you can have multiple commands per event: `"PostToolUse": [{...}, {...}]`
68
+ 2. Run a quick Edit in Claude Code, then check your hook output files
69
+ 3. Ensure each script has a unique log file so you can distinguish them
@@ -0,0 +1,39 @@
1
+ slug: hooks
2
+ title: "Claude Code Hooks"
3
+ version: 1.0.0
4
+ description: "Automate workflows with lifecycle hooks — PostToolUse, UserPromptSubmit, Stop events."
5
+ category: claude-code
6
+ tags: [hooks, automation, claude-code, lifecycle]
7
+ difficulty: intermediate
8
+
9
+ xp:
10
+ read: 15
11
+ walkthrough: 30
12
+ exercise: 20
13
+ quiz: 15
14
+ quiz-perfect-bonus: 10
15
+ game: 25
16
+ game-perfect-bonus: 15
17
+
18
+ time:
19
+ quick: 5
20
+ read: 10
21
+ guided: 45
22
+
23
+ prerequisites: []
24
+ related: [skills, sub-agents]
25
+
26
+ triggers:
27
+ - "How do hooks work in Claude Code?"
28
+ - "How do I run a script after every tool use?"
29
+ - "What lifecycle events are available?"
30
+
31
+ visuals:
32
+ diagrams: [diagram-flow, diagram-architecture]
33
+ quiz-types: [quiz-timed-choice, quiz-fill-blank, quiz-drag-order]
34
+ playground: javascript
35
+ workshop: true
36
+
37
+ sources:
38
+ - url: "https://docs.anthropic.com/en/docs/claude-code"
39
+ label: "Claude Code Documentation"
@@ -0,0 +1,93 @@
1
+ # Claude Code Hooks — Quick Reference
2
+
3
+ ## Lifecycle Events
4
+
5
+ | Event | When It Fires | Use Cases |
6
+ |---|---|---|
7
+ | **PostToolUse** | After any tool is used (Edit, Write, Bash, etc.) | Linting, formatting, usage tracking |
8
+ | **UserPromptSubmit** | When the user sends a message | Input validation, command detection |
9
+ | **Stop** | When the agent finishes a response | Session tracking, cleanup, notifications |
10
+
11
+ ## Environment Variables by Event
12
+
13
+ ### PostToolUse
14
+ | Variable | Description |
15
+ |---|---|
16
+ | `TOOL_NAME` | Name of the tool (e.g., "Edit", "Write", "Bash") |
17
+ | `TOOL_INPUT` | JSON string of the tool's input parameters |
18
+ | `TOOL_OUTPUT` | JSON string of the tool's output |
19
+
20
+ ### UserPromptSubmit
21
+ | Variable | Description |
22
+ |---|---|
23
+ | `USER_PROMPT` | The text the user submitted |
24
+
25
+ ### Stop
26
+ | Variable | Description |
27
+ |---|---|
28
+ | `STOP_REASON` | Why the agent stopped (e.g., "end_turn", "max_tokens") |
29
+ | `TOKEN_USAGE` | JSON with input/output token counts |
30
+
31
+ ## Configuration Syntax
32
+
33
+ Hooks are defined in `.claude/settings.json` or `hooks.json`:
34
+
35
+ ```json
36
+ {
37
+ "hooks": {
38
+ "PostToolUse": [
39
+ {
40
+ "command": "./scripts/on-tool-use.sh",
41
+ "timeout": 5000
42
+ }
43
+ ],
44
+ "UserPromptSubmit": [
45
+ {
46
+ "command": "./scripts/on-prompt.sh",
47
+ "timeout": 3000
48
+ }
49
+ ],
50
+ "Stop": [
51
+ {
52
+ "command": "./scripts/on-stop.sh",
53
+ "timeout": 5000
54
+ }
55
+ ]
56
+ }
57
+ }
58
+ ```
59
+
60
+ ## Parsing Tool Input (PostToolUse)
61
+
62
+ ```bash
63
+ # Get file path from Edit/Write tool input
64
+ FILE=$(echo "$TOOL_INPUT" | jq -r '.file_path // empty')
65
+
66
+ # Check if it's a code file
67
+ if [ -n "$FILE" ] && [[ "$FILE" == *.js ]]; then
68
+ npx eslint "$FILE" >> .local/lint.log 2>&1
69
+ fi
70
+ ```
71
+
72
+ ## Best Practices
73
+
74
+ | Practice | Reason |
75
+ |---|---|
76
+ | **Keep hooks fast** | They block the agent; use `timeout` |
77
+ | **Fail gracefully** | A hook error shouldn't break the user's workflow |
78
+ | **Log, don't print** | Stdout can be fed back to the agent |
79
+ | **Test independently** | Run scripts manually with fake env vars first |
80
+ | **Use exit codes** | Exit 0 for success; document non-zero semantics |
81
+
82
+ ## Testing Hooks Manually
83
+
84
+ ```bash
85
+ # Simulate PostToolUse
86
+ TOOL_NAME=Edit TOOL_INPUT='{"file_path":"src/app.js"}' TOOL_OUTPUT='{}' ./scripts/on-tool-use.sh
87
+
88
+ # Simulate UserPromptSubmit
89
+ USER_PROMPT="Review this PR" ./scripts/on-prompt.sh
90
+
91
+ # Simulate Stop
92
+ STOP_REASON=end_turn TOKEN_USAGE='{"input":1000,"output":500}' ./scripts/on-stop.sh
93
+ ```
@@ -0,0 +1,81 @@
1
+ # Claude Code Hooks — Quiz
2
+
3
+ ## Question 1
4
+
5
+ What are Claude Code hooks?
6
+
7
+ A) AI-generated code snippets
8
+ B) Shell commands that run automatically in response to lifecycle events
9
+ C) Plugins that extend the Claude Code UI
10
+ D) Environment variables set by the user
11
+
12
+ <!-- ANSWER: B -->
13
+ <!-- EXPLANATION: Hooks are shell commands defined in hooks.json or .claude/settings.json. Claude Code executes them automatically when events like PostToolUse, UserPromptSubmit, or Stop occur. -->
14
+
15
+ ## Question 2
16
+
17
+ <!-- VISUAL: fill-blank -->
18
+
19
+ Complete the hook configuration. To run a script after every tool use, you add it under the __________ key in `.claude/settings.json`:
20
+
21
+ ```json
22
+ {
23
+ "hooks": {
24
+ "__________": [
25
+ { "command": "./scripts/on-tool-use.sh", "timeout": 5000 }
26
+ ]
27
+ }
28
+ }
29
+ ```
30
+
31
+ <!-- ANSWER: PostToolUse -->
32
+ <!-- EXPLANATION: PostToolUse is the lifecycle event that fires after any tool is used (Edit, Write, Bash, etc.). The configuration key must match the exact event name. -->
33
+
34
+ ## Question 3
35
+
36
+ Which environment variable is available in a PostToolUse hook?
37
+
38
+ A) `USER_PROMPT`
39
+ B) `TOOL_NAME`
40
+ C) `STOP_REASON`
41
+ D) `TOKEN_USAGE`
42
+
43
+ <!-- ANSWER: B -->
44
+ <!-- EXPLANATION: PostToolUse hooks receive TOOL_NAME, TOOL_INPUT, and TOOL_OUTPUT. USER_PROMPT is for UserPromptSubmit; STOP_REASON and TOKEN_USAGE are for Stop. -->
45
+
46
+ ## Question 4
47
+
48
+ <!-- VISUAL: drag-order -->
49
+
50
+ Put these lifecycle events in the order they occur during a single agent turn:
51
+
52
+ A) Stop
53
+ B) UserPromptSubmit
54
+ C) PostToolUse (may fire multiple times)
55
+
56
+ <!-- ANSWER: B,C,A -->
57
+ <!-- EXPLANATION: UserPromptSubmit fires when the user sends a message (start of turn). PostToolUse fires after each tool call during the turn. Stop fires when the agent finishes its response (end of turn). -->
58
+
59
+ ## Question 5
60
+
61
+ Why should hook scripts "log, don't print"?
62
+
63
+ A) Printing is slower than file I/O
64
+ B) Stdout from hooks can be fed back to the agent and confuse it
65
+ C) Logs are required by Claude Code
66
+ D) Printing only works in certain shells
67
+
68
+ <!-- ANSWER: B -->
69
+ <!-- EXPLANATION: When a hook runs, its stdout may be captured and sent to the agent as context. Writing diagnostic output to stdout could pollute the agent's context. Writing to files keeps the agent's input clean. -->
70
+
71
+ ## Question 6
72
+
73
+ What is a key reason to set a `timeout` on a hook?
74
+
75
+ A) Hooks are asynchronous by default
76
+ B) Hooks block the agent — a slow or stuck hook delays the whole session
77
+ C) Timeouts are required for security
78
+ D) Without a timeout, hooks run indefinitely in the background
79
+
80
+ <!-- ANSWER: B -->
81
+ <!-- EXPLANATION: Hooks run synchronously. While a hook is executing, the agent waits. A hung or very slow hook (e.g., a network call) would block the user's workflow. The timeout field prevents runaway hooks. -->
@@ -0,0 +1,34 @@
1
+ # Claude Code Hooks — Resources
2
+
3
+ ## Official Docs
4
+
5
+ - [Claude Code Documentation](https://docs.anthropic.com/en/docs/claude-code) — Main reference for hooks configuration, lifecycle events, and environment variables.
6
+ - [Claude Code Settings](https://docs.anthropic.com/en/docs/claude-code/settings) — Where hooks are configured in `.claude/settings.json`.
7
+
8
+ ## Videos
9
+
10
+ - [Claude Code Deep Dive](https://www.youtube.com/results?search_query=claude+code+hooks+automation) — Walkthroughs demonstrating hook-based automation.
11
+ - [Git Hooks Explained](https://www.youtube.com/watch?v=egfuwOe8nXc) — Fireship. Conceptually similar lifecycle hooks in Git — helpful mental model.
12
+
13
+ ## Articles and Readings
14
+
15
+ - [Anthropic Cookbook — Tool Use](https://github.com/anthropics/anthropic-cookbook/tree/main/tool_use) — Patterns for extending agent behavior, relevant to hook design.
16
+ - [Git Hooks Documentation](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) — Pro Git. Lifecycle hook patterns that inspired Claude Code hooks.
17
+ - [Husky — Git Hooks Made Easy](https://typicode.github.io/husky/) — Popular tool for managing Git hooks, illustrates the hook automation pattern.
18
+
19
+ ## Books
20
+
21
+ - **The Pragmatic Programmer** by Hunt & Thomas — Chapter on "Domain Languages" covers automation pipelines relevant to hook scripting. [pragprog.com](https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edition/).
22
+
23
+ ## Tools and Frameworks
24
+
25
+ - [jq](https://jqlang.github.io/jq/) — Lightweight JSON processor used in hook scripts to parse tool input/output.
26
+ - [Prettier](https://prettier.io/) — Code formatter commonly invoked from PostToolUse hooks for auto-formatting.
27
+ - [ESLint](https://eslint.org/) — Linter frequently wired into hooks for real-time code quality checks.
28
+ - [ShellCheck](https://www.shellcheck.net/) — Static analysis for bash scripts — useful for validating your hook scripts.
29
+ - [lefthook](https://github.com/evilmartians/lefthook) — Fast hook runner for Git, useful pattern reference for lifecycle automation.
30
+
31
+ ## Related Concepts
32
+
33
+ - [Webhooks (MDN)](https://developer.mozilla.org/en-US/docs/Glossary/Webhook) — The broader pattern of event-driven callbacks that hooks implement.
34
+ - [Observer Pattern (Refactoring Guru)](https://refactoring.guru/design-patterns/observer) — Design pattern behind lifecycle event systems.
@@ -0,0 +1,105 @@
1
+ # Claude Code Hooks — Walkthrough
2
+
3
+ ## Before We Begin
4
+
5
+ <!-- hint:card type="concept" title="Automation runs in response to events" -->
6
+
7
+ **Warm-up:** Think about automation you use today — Git hooks, CI pipelines, formatters that run on save. What do they have in common? What "events" trigger them, and what happens after?
8
+
9
+ **Checkpoint:** The user should recognize that automation is often event-driven: something happens (a commit, a push, a file save), and a script runs. Hooks extend this pattern to the AI coding session.
10
+
11
+ ---
12
+
13
+ ## Step 1: What Are Hooks?
14
+
15
+ Hooks are shell commands that Claude Code runs automatically when certain events occur.
16
+
17
+ <!-- hint:diagram mermaid-type="flowchart" topic="Hook flow: event fires → script runs → continues" -->
18
+
19
+ **Task:** Look at your project's `.claude/settings.json` (or the hooks docs). See if any hooks are already configured.
20
+
21
+ **Question:** Why might you want a script to run *after* the agent uses a tool, rather than manually running it yourself?
22
+
23
+ **Checkpoint:** The user should understand that hooks automate repetitive workflows — e.g., linting after every edit, so you never forget. They run transparently in the background of the session.
24
+
25
+ ---
26
+
27
+ ## Step 2: Lifecycle Events
28
+
29
+ Claude Code fires hooks at three lifecycle points: PostToolUse, UserPromptSubmit, and Stop.
30
+
31
+ **Task:** Review the table of events. For each event, name one concrete use case from your own workflow.
32
+
33
+ **Question:** PostToolUse runs after *every* tool call — Edit, Write, Bash, etc. What's the trade-off? When might that be too frequent?
34
+
35
+ **Checkpoint:** The user should see that PostToolUse is powerful but can be noisy — you might want to filter by tool name (e.g., only run on Edit/Write) or add a timeout to avoid slowdown.
36
+
37
+ ---
38
+
39
+ ## Step 3: Writing a PostToolUse Hook
40
+
41
+ PostToolUse receives `TOOL_NAME`, `TOOL_INPUT`, and `TOOL_OUTPUT` as environment variables.
42
+
43
+ <!-- hint:terminal -->
44
+
45
+ **Task:** Write a minimal PostToolUse hook that logs the tool name to a file (e.g., `.local/hook-log.txt`) when the tool is Edit or Write. Configure it in `.claude/settings.json`.
46
+
47
+ **Question:** How would you extract the file path from `TOOL_INPUT` inside a shell script? (Hint: it's JSON.)
48
+
49
+ **Checkpoint:** The user should use `jq` or similar to parse `TOOL_INPUT` and get `file_path`. They should configure the hook with a timeout.
50
+
51
+ ---
52
+
53
+ ## Step 4: Writing a UserPromptSubmit Hook
54
+
55
+ UserPromptSubmit fires when the user sends a message, before the agent responds.
56
+
57
+ <!-- hint:card type="concept" title="UserPromptSubmit runs before the agent thinks" -->
58
+
59
+ **Task:** Write a UserPromptSubmit hook that writes the first 100 characters of the user's prompt to a log file. Use the `USER_PROMPT` environment variable.
60
+
61
+ **Question:** What could you use UserPromptSubmit for? Think beyond logging — validation, command detection, rate limiting.
62
+
63
+ **Checkpoint:** The user should identify uses like: detecting `/teach` and routing to a specific handler; validating prompt length; blocking unsafe prompts.
64
+
65
+ ---
66
+
67
+ ## Step 5: Writing a Stop Hook
68
+
69
+ Stop fires when the agent finishes a response. It receives `STOP_REASON` and `TOKEN_USAGE`.
70
+
71
+ <!-- hint:terminal -->
72
+
73
+ **Task:** Write a Stop hook that appends the session's token usage to a file. Parse `TOKEN_USAGE` (JSON) and log input/output counts.
74
+
75
+ **Question:** Why run something at "Stop" rather than at "PostToolUse"? What kinds of things only make sense at the end of a turn?
76
+
77
+ **Checkpoint:** The user should recognize that session-level metrics (duration, token usage, cleanup) only make sense when the turn is complete. PostToolUse would fire many times per turn; Stop fires once.
78
+
79
+ ---
80
+
81
+ ## Step 6: Testing Hooks
82
+
83
+ Hooks block the agent while they run. Slow or failing hooks hurt the experience.
84
+
85
+ <!-- hint:terminal -->
86
+
87
+ **Task:** Run your PostToolUse hook script manually with fake env vars: `TOOL_NAME=Edit TOOL_INPUT='{"file_path":"test.txt"}' ./scripts/on-tool-use.sh`. Verify it behaves correctly.
88
+
89
+ **Question:** What happens if your hook script exits with code 1? Should it? How does the agent interpret non-zero exit?
90
+
91
+ **Checkpoint:** The user should test hooks in isolation before wiring them up. They should consider: hooks should fail gracefully — a lint failure shouldn't crash the session. Exit codes can signal the agent; document the contract.
92
+
93
+ ---
94
+
95
+ ## Step 7: Error Handling and Best Practices
96
+
97
+ Hooks run synchronously. They can slow down or break the workflow if misused.
98
+
99
+ <!-- hint:card type="concept" title="Keep hooks fast; fail gracefully" -->
100
+
101
+ **Task:** Add a `timeout` to each hook in your config. Ensure your scripts handle missing or malformed env vars (e.g., empty `TOOL_INPUT`).
102
+
103
+ **Question:** The content says "Log, don't print" — why? What happens to stdout when a hook runs?
104
+
105
+ **Checkpoint:** The user should understand that stdout from hooks can be fed back to the agent, which may confuse it. Write to files instead. Use `timeout` to prevent runaway hooks.
@@ -0,0 +1,64 @@
1
+ scenarios:
2
+ - id: lint-hook
3
+ title: "Build a Lint Hook"
4
+ difficulty: beginner
5
+ xp: 25
6
+ setup: []
7
+ files:
8
+ - name: scripts/lint-hook.sh
9
+ content: |
10
+ #!/bin/bash
11
+ # TODO: Implement PostToolUse hook that checks for leftover TODO comments
12
+ exit 0
13
+ language: bash
14
+ readonly: false
15
+ task: "Write a PostToolUse hook that runs after Edit or Write and checks the modified file for leftover TODO comments. If any are found, append the file path and line numbers to .local/todo-report.txt. Configure the hook in .claude/settings.json with a 5000ms timeout."
16
+ validations:
17
+ - label: "Hook script exists and is executable"
18
+ check: output-contains
19
+ pattern: "lint-hook|todo-report|TODO"
20
+ - label: "Hook configured in settings"
21
+ check: output-contains
22
+ pattern: "PostToolUse|hooks|settings.json"
23
+ - label: "TODO detection implemented"
24
+ check: output-contains
25
+ pattern: "grep|TODO|todo"
26
+ hints:
27
+ - "Parse TOOL_INPUT with jq to get file_path. Only run when TOOL_NAME is Edit or Write."
28
+ - "Use grep -n 'TODO' to find lines. Append results to .local/todo-report.txt."
29
+ - "Ensure the script handles missing files and exits 0 to avoid breaking the session."
30
+ agent_prompts:
31
+ on_start: "What's the difference between a hook that runs on every tool and one that only runs on Edit/Write? Why might you want to filter?"
32
+ on_complete: "How would you extend this hook to also check for FIXME or XXX comments? What about excluding comments in test files?"
33
+
34
+ - id: session-tracker
35
+ title: "Build a Session Tracker"
36
+ difficulty: beginner
37
+ xp: 20
38
+ setup: []
39
+ files:
40
+ - name: scripts/session-tracker.sh
41
+ content: |
42
+ #!/bin/bash
43
+ # TODO: Implement Stop hook that logs session duration
44
+ exit 0
45
+ language: bash
46
+ readonly: false
47
+ task: "Write a Stop hook that logs the session end time and token usage to .local/session-log.json. Each entry should include: timestamp, STOP_REASON, and parsed input/output token counts from TOKEN_USAGE. Configure it in .claude/settings.json."
48
+ validations:
49
+ - label: "Stop hook script exists"
50
+ check: output-contains
51
+ pattern: "session-tracker|session-log|STOP_REASON|TOKEN_USAGE"
52
+ - label: "Hook configured for Stop event"
53
+ check: output-contains
54
+ pattern: "Stop|hooks"
55
+ - label: "JSON logging implemented"
56
+ check: output-contains
57
+ pattern: "jq|json|timestamp"
58
+ hints:
59
+ - "STOP_REASON and TOKEN_USAGE are in the environment. TOKEN_USAGE is JSON."
60
+ - "Use jq to parse TOKEN_USAGE and build a log entry. Append to .local/session-log.json as a new line (JSONL format)."
61
+ - "For timestamp: date -Iseconds or date +%Y-%m-%dT%H:%M:%S"
62
+ agent_prompts:
63
+ on_start: "Why does a session tracker belong in a Stop hook rather than PostToolUse? What would happen if you used PostToolUse?"
64
+ on_complete: "How could you extend this to also record session duration? What would you need to capture at the start of a session?"