codewhale.history 2.7.0 → 2.8.1

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # CodeWhale Tools Pack
2
2
 
3
- A portable pack of global CodeWhale commands: `//tools`, `//history`, and `//snapshot`.
3
+ A portable pack of global CodeWhale commands: `//tools`, `//history`, `//snapshot`, and `//teach-me`.
4
4
 
5
5
  Cross-platform — works on Windows, Mac, Linux.
6
6
 
@@ -14,6 +14,7 @@ tools_for_codewhale/
14
14
  ├── skills/
15
15
  │ ├── history/SKILL.md # //history — calls codewhale-history
16
16
  │ ├── snapshot/SKILL.md # //snapshot — pre-edit file backups
17
+ │ ├── teach-me/SKILL.md # //teach-me — interactive code quiz
17
18
  │ └── tools/tools-skill/SKILL.md # //tools — lists all available tools
18
19
  ├── instructions.md # Trigger config (drop into any .codewhale/)
19
20
  └── README.md # This file
@@ -40,6 +41,7 @@ codewhale-tools-install -p <target-path> # specific workspace
40
41
  - **`//tools`** — lists every tool available in the current session
41
42
  - **`//history`** — lists all chat sessions for the current workspace with cost totals
42
43
  - **`//snapshot`** — toggle pre-edit file backups (`on`, `off`, `status`)
44
+ - **`//teach-me`** — interactive code quiz that tests your knowledge of the current codebase
43
45
 
44
46
  ## Requirements
45
47
  - Node.js (for the `codewhale-history` command)
package/instructions.md CHANGED
@@ -8,3 +8,6 @@ When the user types `//history`, immediately load the `history` skill (from `his
8
8
 
9
9
  ## //snapshot Command
10
10
  When the user types `//snapshot`, immediately load the `snapshot` skill (from `snapshot/SKILL.md`) and follow its instructions. `//snapshot on` enables automatic pre-edit file backups to `_snapshots/` when no Git repo is present. `//snapshot off` disables it. `//snapshot status` reports the current state. This works in all sessions once the skill is installed globally.
11
+
12
+ ## //teach-me Command
13
+ When the user types `//teach-me` (or any trigger phrase from the teach-me skill, including `teach me`, `quiz me`, `test my knowledge`, `code quiz`, `drill me`), immediately load the `teach-me` skill (from `teach-me/SKILL.md`) and start an interactive code-teaching quiz. Supports optional modifiers: `teach me <language>`, `teach me level N`, `teach me <file/module>`. This works in all sessions once the skill is installed globally.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "codewhale.history",
3
- "version": "2.7.0",
4
- "description": "CodeWhale utility commands: session history, tool listing, file snapshot — global install",
3
+ "version": "2.8.1",
4
+ "description": "CodeWhale utility commands: session history, tool listing, file snapshot, interactive code quiz — global install",
5
5
  "bin": {
6
6
  "codewhale-history": "./_list_sessions.js",
7
7
  "codewhale-tools-install": "./tools-install.js"
@@ -0,0 +1,325 @@
1
+ ---
2
+ name: teach-me
3
+ description: Interactive code-teaching quiz. Selects random snippets from the current project and quizzes the user on application logic and language semantics. Triggered by 'teach me', 'quiz me', 'test my knowledge', 'code quiz', or 'drill me'. Supports difficulty levels 1–5.
4
+ ---
5
+
6
+ # Teach Me — Interactive Code Quiz
7
+
8
+ An interactive teaching session that randomly selects code snippets from the
9
+ current project, presents them to the user, asks the user to explain them, and
10
+ provides constructive feedback on both **application logic** (what the code
11
+ accomplishes) and **language mechanics** (syntax and semantics).
12
+
13
+ ## Session Trigger
14
+
15
+ Activate when the user says any of:
16
+
17
+ - `teach me`
18
+ - `quiz me`
19
+ - `test my knowledge`
20
+ - `code quiz`
21
+ - `drill me`
22
+ - `explain this codebase`
23
+
24
+ Optionally followed by modifiers:
25
+
26
+ - `teach me python` — restrict to a specific language
27
+ - `teach me level 3` / `teach me l3` — set difficulty (1–5)
28
+ - `teach me <file or module>` — narrow scope to a specific file, directory, or module
29
+ - `teach me <concept>` — target a specific language concept. Examples:
30
+ `teach me decorators`, `teach me async`, `teach me generators`,
31
+ `teach me context managers`, `teach me comprehensions`,
32
+ `teach me error handling`, `teach me type hints`, `teach me threading`
33
+
34
+ Modifiers combine freely: `teach me decorators level 4`,
35
+ `teach me async services/`, `teach me generators l2`
36
+
37
+ If no level is specified, default to **level 3** and adjust based on
38
+ performance across rounds.
39
+
40
+ ## Session Lifecycle
41
+
42
+ ### 1. Discovery — Map the Project
43
+
44
+ Before presenting the first snippet:
45
+
46
+ ```
47
+ A. Use file_search or list_dir to find source directories.
48
+ B. Use grep_files to count function/class definitions per file.
49
+ C. Build a mental index: file path → rough function/class count.
50
+ D. Determine the primary language(s) from file extensions.
51
+ E. Report: "Found ~N candidates across M files. Starting at level X. Ready."
52
+ ```
53
+
54
+ If the user specified a scope, apply it during discovery. If the user
55
+ specified a language, filter by extension.
56
+
57
+ ### 2. Selection — Pick a Snippet
58
+
59
+ Randomly select a file from the index, then randomly select a function,
60
+ method, or logical block from that file. Use these rules:
61
+
62
+ #### Good Snippets (select these)
63
+ - Functions or methods 5–55 lines long (after stripping docstrings and blank lines)
64
+ - Classes with 10–60 lines of method bodies
65
+ - Blocks containing: decorators, comprehensions, generators, context managers,
66
+ async/await, error handling, design patterns, algorithm implementations,
67
+ non-obvious control flow, or domain-specific logic
68
+ - Code that can be understood with at most one level of external context
69
+
70
+ #### Avoid (skip these)
71
+ - Pure getters/setters/properties (single-line `return self._x`)
72
+ - Imports, module-level constants, config dicts, `__init__.py` with only imports
73
+ - Boilerplate: `if __name__ == "__main__"`, argument parsers, logging setup
74
+ - Dunder methods that only delegate
75
+ - Functions shorter than 5 effective lines or longer than 60 lines
76
+ - Code that requires reading 3+ other files to understand
77
+
78
+ #### Difficulty → Line Ranges
79
+
80
+ | Level | Lines | Suitable patterns |
81
+ |-------|--------|-------------------|
82
+ | 1 | 5–15 | Straight-line logic, `if`/`else`, basic function calls |
83
+ | 2 | 8–20 | Loops, list/dict operations, simple `try`/`except` |
84
+ | 3 | 12–30 | Comprehensions, decorators, `with` statements, multiple branches |
85
+ | 4 | 18–45 | Generators, `async`/`await`, descriptors, threading, closures |
86
+ | 5 | 25–55 | Metaclasses, complex async patterns, multi-threading with synchronization, architectural glue code |
87
+
88
+ #### No-repeats rule
89
+ Track which snippets have been shown this session (file + line range).
90
+ Do not repeat a snippet unless the user explicitly asks or all candidates
91
+ are exhausted. Prefer cycling through files before returning to the same
92
+ file.
93
+
94
+ #### Concept Targeting
95
+
96
+ When the user targets a specific concept, filter snippets to ensure they
97
+ contain that concept. After selecting a random candidate, verify it with
98
+ `grep_files` on the file for the concept signal. If the candidate doesn't
99
+ match, pick another random snippet (retry up to 10 times; if still no
100
+ match, relax the filter and note the fallback to the user).
101
+
102
+ | Trigger phrase | Signal to verify in the snippet |
103
+ |---|---|
104
+ | `decorators` | `@` immediately above a `def` line |
105
+ | `async` | `async def` or `await` |
106
+ | `generators` | `yield` |
107
+ | `context managers` | `with` statement or `__enter__`/`__exit__` |
108
+ | `comprehensions` | `for ... in` inside `[`, `{`, or `(` |
109
+ | `error handling` | `try:`, `except`, or `finally` |
110
+ | `type hints` | `:` type annotation in function signatures or variable assignments |
111
+ | `threading` | `Thread(`, `Lock(`, `Queue(`, or `threading.` |
112
+
113
+ ### 3. Presentation — Show the Snippet
114
+
115
+ For each round, present the snippet with its filename:
116
+
117
+ ```
118
+ ---
119
+ ## Round N — Level X · concept | `path/to/file.py` (lines A–B)
120
+
121
+ ```python
122
+ 42 def calculate_position_size(
123
+ 43 capital: float,
124
+ 44 risk_per_trade: float,
125
+ 45 entry_price: float,
126
+ 46 stop_loss: float
127
+ 47 ) -> int:
128
+ 48 risk_amount = capital * (risk_per_trade / 100)
129
+ 49 price_risk = abs(entry_price - stop_loss)
130
+ 50 if price_risk == 0:
131
+ 51 return 0
132
+ 52 shares = int(risk_amount / price_risk)
133
+ 53 return max(shares, 0)
134
+ ```
135
+
136
+ **Your turn:** Explain what this code does (application logic) AND how it
137
+ works (syntax and semantics). Include any edge cases you notice.
138
+
139
+ Type `hint` for a clue, `skip` to see the answer, or `stop` to end.
140
+ ---
141
+ ```
142
+
143
+ Guidelines:
144
+ - Include realistic line numbers (1-based from the actual file)
145
+ - Strip only excessive blank lines; keep natural spacing
146
+ - Show the function/class signature with its decorators
147
+ - Show the filename and line range in the header
148
+ - The `· concept` portion only appears when a concept is targeted; omit it during free-play rounds
149
+ - If the snippet depends on one obvious external type or constant, include a
150
+ brief inline note
151
+ - **Before presenting, scan for secrets.** Redact API keys, tokens, passwords,
152
+ connection strings with `[REDACTED]`. Skip snippets that are entirely
153
+ secrets or contain PII/email addresses/personal identifiers.
154
+
155
+ ### 4. Evaluation — Assess the Answer
156
+
157
+ Evaluate across two dimensions, scaled to the current difficulty level.
158
+
159
+ #### A. Application Logic (what the code does in the project)
160
+
161
+ | Level | Expectation |
162
+ |-------|-------------|
163
+ | 1 | Names what the function does at a basic level |
164
+ | 2 | Identifies inputs, outputs, and at least one edge case |
165
+ | 3 | Explains the module role, failure modes, and upstream/downstream connections |
166
+ | 4 | Identifies the design pattern, multi-component interaction, and concurrency edge cases |
167
+ | 5 | Explains architectural role across system layers, performance implications, and subtle bugs or limitations |
168
+
169
+ #### B. Language Mechanics (syntax and semantics)
170
+
171
+ | Level | Expectation |
172
+ |-------|-------------|
173
+ | 1 | Basic types, function definition syntax, simple `if`/`else` |
174
+ | 2 | Loop mechanics, list/dict operations, basic `try`/`except`, string formatting |
175
+ | 3 | Comprehensions, decorator syntax and effect, `with` / context managers, type hints, exception chaining |
176
+ | 4 | Generator mechanics (`yield`), `async`/`await` internals, descriptor protocol, closures, threading primitives |
177
+ | 5 | Coroutine internals, metaclass programming, GIL implications, memory model, `__slots__`, MRO, weak references |
178
+
179
+ #### Weighted Evaluation for Targeted Concepts
180
+
181
+ When a concept is targeted (e.g., `teach me decorators`), bias the
182
+ evaluation toward that concept:
183
+
184
+ - **Mechanics axis:** The targeted concept carries extra weight. Missing
185
+ it is a significant gap even if other mechanics are handled well.
186
+ - **Strike hints:** Always steer strike 1 toward the targeted concept
187
+ before hinting about any other missed item.
188
+ - **Feedback ordering:** List the targeted concept first under "What you
189
+ missed" or "What you could sharpen."
190
+ - **Success bar:** To "meet expectations," the user must correctly
191
+ explain the targeted concept at the current level's depth.
192
+
193
+ #### The Three-Strikes Rule
194
+
195
+ If the user's answer does **not** meet the expectations for the current
196
+ difficulty level:
197
+
198
+ **Strike 1** — Give a category-level nudge:
199
+ ```
200
+ Good start, but at Level N I'd expect you to also notice [category — e.g.,
201
+ "how errors are handled" or "what the decorator is doing"]. Try again —
202
+ what about [specific nudge — e.g., "the return type on line 47"]?
203
+ ```
204
+
205
+ **Strike 2** — Give a near-explicit hint:
206
+ ```
207
+ Getting closer. One more thing — [nearly names the concept — e.g., "that
208
+ @retry decorator wraps the function"]. Look at line X.
209
+ ```
210
+
211
+ **Strike 3** — Reveal the full answer and move on:
212
+ ```
213
+ Let me walk you through it.
214
+ ```
215
+ Then deliver the complete evaluation (both axes) as if they had skipped.
216
+ After the evaluation, proceed directly to the next round — do not ask
217
+ "another round?" after a strike-3 reveal; just present the next snippet.
218
+
219
+ If the user gets it on attempt 2 or 3:
220
+ ```
221
+ There you go! Now let me fill in what else is notable.
222
+ ```
223
+ Then provide the remaining feedback they missed, and ask "Another round?".
224
+
225
+ If the user's answer **meets** expectations (any attempt):
226
+ - Highlight 2–4 specific things they got right
227
+ - Add 1–3 things they could sharpen (even a strong answer has nuance)
228
+ - Reveal the file context
229
+ - Ask "Another round?"
230
+
231
+ #### Feedback structure (success or strike-3)
232
+
233
+ ```
234
+ **What you got right:**
235
+ - [2–4 specific things correctly identified]
236
+
237
+ **What you missed or could sharpen:**
238
+ - [1–3 things, with brief explanation]
239
+
240
+ **Context:** `services/position_sizer.py` — called by the OrderManager before
241
+ placing any trade. Sits between the signal generator and the exchange adapter.
242
+ ```
243
+
244
+ Keep feedback constructive. The goal is learning, not grading. If they
245
+ nailed everything at-level, say so and highlight the nuance they caught.
246
+
247
+ #### Handling commands mid-round
248
+
249
+ | Command | Behavior |
250
+ |---------|----------|
251
+ | `hint` | Give one strike-1 level nudge (counts as an attempt in the strike system) |
252
+ | `skip` / `reveal` | Show full evaluation immediately. Move to next round. |
253
+ | `next` / `another` | Skip this snippet, draw a new one. No strike counted. |
254
+ | `level N` / `lN` (e.g. `level 5`, `l2`) | Adjust difficulty for subsequent rounds. |
255
+ | `easier` | Decrease level by 1 (minimum 1). |
256
+ | `harder` | Increase level by 1 (maximum 5). |
257
+ | `stop` / `done` / `end` | End session. Deliver summary. |
258
+
259
+ ### 5. Loop — Keep Going
260
+
261
+ After a successful evaluation or a `next` skip, ask:
262
+ "Another round? (yes / no / level N / stop)"
263
+
264
+ After a strike-3 reveal, do **not** ask — proceed directly to the next
265
+ round with: "Round N+1 — Level X | `file.py`"
266
+
267
+ ### End-of-Session Summary
268
+
269
+ When the user says `stop`:
270
+
271
+ ```
272
+ ## Session Summary
273
+
274
+ Rounds completed: 5
275
+ Level played: 3
276
+ Files covered:
277
+ - services/position_sizer.py (rounds 1, 4)
278
+ - agents/news_agent.py (round 2)
279
+ - utils/fuzzy_dedup.py (round 3)
280
+ - database.py (round 5)
281
+
282
+ What you're strong on: [concepts consistently identified]
283
+ What to review: [concepts missed across multiple rounds]
284
+ Suggested next level: [3 → 4, or stay, or 3 → 2]
285
+ ```
286
+
287
+ ## Multilingual Projects
288
+
289
+ If the project contains multiple languages, let the user's `teach me <lang>`
290
+ filter govern. If no filter, sample all languages proportionally but announce
291
+ the language in each round header. Use language-appropriate evaluation
292
+ criteria for the Mechanics axis:
293
+
294
+ - **Python:** decorators, generators, descriptors, `async`/`await`, type hints,
295
+ context managers, MRO, slots, data classes
296
+ - **JavaScript/TypeScript:** closures, prototypes, `this` binding, promises,
297
+ async/await, destructuring, spread, arrow functions, TypeScript generics
298
+ - **Rust:** ownership, borrowing, lifetimes, pattern matching, `Result`/`Option`,
299
+ traits, generics, macros
300
+ - **Go:** goroutines, channels, interfaces, defer, error handling conventions,
301
+ zero values
302
+ - **Java:** streams, generics, annotations, try-with-resources, concurrency
303
+ primitives, inheritance vs composition
304
+
305
+ ## Guardrails
306
+
307
+ - **Never show secrets.** Scan every snippet before display. Redact API keys,
308
+ tokens, passwords, connection strings with `[REDACTED]`. Skip entire snippets
309
+ that are only secrets/config.
310
+ - **Never show user data.** Skip snippets containing PII, email addresses,
311
+ phone numbers, or personal identifiers.
312
+ - **One snippet per turn.** Wait for the user's response before showing the next.
313
+ - **Respect stop immediately.** If the user says `stop`, deliver the summary —
314
+ do not squeeze in another round.
315
+ - **Stay in teaching mode.** Do not fix bugs, refactor, or edit code during a
316
+ teaching session unless the user explicitly asks to switch modes.
317
+
318
+ ## Verification
319
+
320
+ After each round, confirm:
321
+ - The snippet was actually read from the file (not hallucinated)
322
+ - The line numbers match the source
323
+ - The feedback accurately describes what the code does
324
+ - No secrets or PII were exposed
325
+ - The strike count was tracked correctly
package/tools-install.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * CodeWhale Tools Installer
4
4
  *
5
- * Installs global skills and workspace triggers for //tools, //history, and //snapshot.
5
+ * Installs global skills and workspace triggers for //tools, //history, //snapshot, and //teach-me.
6
6
  *
7
7
  * Usage:
8
8
  * node tools-install.js # current directory
@@ -55,12 +55,12 @@ if (fs.existsSync(instructionsSource)) {
55
55
  if (fs.existsSync(instructionsDest)) {
56
56
  const existingContent = fs.readFileSync(instructionsDest, 'utf-8');
57
57
  // Only append if it's not already there (idempotent)
58
- if (!existingContent.includes('## //tools Command') && !existingContent.includes('## //history Command') && !existingContent.includes('## //snapshot Command')) {
58
+ if (!existingContent.includes('## //tools Command') && !existingContent.includes('## //history Command') && !existingContent.includes('## //snapshot Command') && !existingContent.includes('## //teach-me Command')) {
59
59
  const separator = `\n\n---\n\n`;
60
60
  fs.writeFileSync(instructionsDest, existingContent + separator + newContent, 'utf-8');
61
- console.log(' Appended //tools, //history, and //snapshot instructions to existing instructions.md');
61
+ console.log(' Appended //tools, //history, //snapshot, and //teach-me instructions to existing instructions.md');
62
62
  } else {
63
- console.log(' //tools, //history, and //snapshot already present in instructions.md — skipped.');
63
+ console.log(' //tools, //history, //snapshot, and //teach-me already present in instructions.md — skipped.');
64
64
  }
65
65
  } else {
66
66
  fs.writeFileSync(instructionsDest, newContent, 'utf-8');
@@ -78,6 +78,7 @@ const checklist = {
78
78
  'history skill': path.join(skillsDest, 'history', 'SKILL.md'),
79
79
  'tools skill': path.join(skillsDest, 'tools', 'tools-skill', 'SKILL.md'),
80
80
  'snapshot skill': path.join(skillsDest, 'snapshot', 'SKILL.md'),
81
+ 'teach-me skill': path.join(skillsDest, 'teach-me', 'SKILL.md'),
81
82
  'workspace instructions': instructionsDest
82
83
  };
83
84
 
@@ -94,7 +95,7 @@ console.log('');
94
95
  if (errors === 0) {
95
96
  console.log('=== Installation complete! ===');
96
97
  console.log('Make sure codewhale-history is installed globally: npm install -g <path-to-tools_for_codewhale>');
97
- console.log('Then type //tools, //history, or //snapshot in any CodeWhale session.');
98
+ console.log('Then type //tools, //history, //snapshot, or //teach-me in any CodeWhale session.');
98
99
  } else {
99
100
  console.log(`=== Installation finished with ${errors} error(s). ===`);
100
101
  }