codewhale.history 2.7.0 → 2.8.0

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.0",
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,284 @@
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
+
30
+ If no level is specified, default to **level 3** and adjust based on
31
+ performance across rounds.
32
+
33
+ ## Session Lifecycle
34
+
35
+ ### 1. Discovery — Map the Project
36
+
37
+ Before presenting the first snippet:
38
+
39
+ ```
40
+ A. Use file_search or list_dir to find source directories.
41
+ B. Use grep_files to count function/class definitions per file.
42
+ C. Build a mental index: file path → rough function/class count.
43
+ D. Determine the primary language(s) from file extensions.
44
+ E. Report: "Found ~N candidates across M files. Starting at level X. Ready."
45
+ ```
46
+
47
+ If the user specified a scope, apply it during discovery. If the user
48
+ specified a language, filter by extension.
49
+
50
+ ### 2. Selection — Pick a Snippet
51
+
52
+ Randomly select a file from the index, then randomly select a function,
53
+ method, or logical block from that file. Use these rules:
54
+
55
+ #### Good Snippets (select these)
56
+ - Functions or methods 5–55 lines long (after stripping docstrings and blank lines)
57
+ - Classes with 10–60 lines of method bodies
58
+ - Blocks containing: decorators, comprehensions, generators, context managers,
59
+ async/await, error handling, design patterns, algorithm implementations,
60
+ non-obvious control flow, or domain-specific logic
61
+ - Code that can be understood with at most one level of external context
62
+
63
+ #### Avoid (skip these)
64
+ - Pure getters/setters/properties (single-line `return self._x`)
65
+ - Imports, module-level constants, config dicts, `__init__.py` with only imports
66
+ - Boilerplate: `if __name__ == "__main__"`, argument parsers, logging setup
67
+ - Dunder methods that only delegate
68
+ - Functions shorter than 5 effective lines or longer than 60 lines
69
+ - Code that requires reading 3+ other files to understand
70
+
71
+ #### Difficulty → Line Ranges
72
+
73
+ | Level | Lines | Suitable patterns |
74
+ |-------|--------|-------------------|
75
+ | 1 | 5–15 | Straight-line logic, `if`/`else`, basic function calls |
76
+ | 2 | 8–20 | Loops, list/dict operations, simple `try`/`except` |
77
+ | 3 | 12–30 | Comprehensions, decorators, `with` statements, multiple branches |
78
+ | 4 | 18–45 | Generators, `async`/`await`, descriptors, threading, closures |
79
+ | 5 | 25–55 | Metaclasses, complex async patterns, multi-threading with synchronization, architectural glue code |
80
+
81
+ #### No-repeats rule
82
+ Track which snippets have been shown this session (file + line range).
83
+ Do not repeat a snippet unless the user explicitly asks or all candidates
84
+ are exhausted. Prefer cycling through files before returning to the same
85
+ file.
86
+
87
+ ### 3. Presentation — Show the Snippet
88
+
89
+ For each round, present the snippet with its filename:
90
+
91
+ ```
92
+ ---
93
+ ## Round N — Level X | `path/to/file.py` (lines A–B)
94
+
95
+ ```python
96
+ 42 def calculate_position_size(
97
+ 43 capital: float,
98
+ 44 risk_per_trade: float,
99
+ 45 entry_price: float,
100
+ 46 stop_loss: float
101
+ 47 ) -> int:
102
+ 48 risk_amount = capital * (risk_per_trade / 100)
103
+ 49 price_risk = abs(entry_price - stop_loss)
104
+ 50 if price_risk == 0:
105
+ 51 return 0
106
+ 52 shares = int(risk_amount / price_risk)
107
+ 53 return max(shares, 0)
108
+ ```
109
+
110
+ **Your turn:** Explain what this code does (application logic) AND how it
111
+ works (syntax and semantics). Include any edge cases you notice.
112
+
113
+ Type `hint` for a clue, `skip` to see the answer, or `stop` to end.
114
+ ---
115
+ ```
116
+
117
+ Guidelines:
118
+ - Include realistic line numbers (1-based from the actual file)
119
+ - Strip only excessive blank lines; keep natural spacing
120
+ - Show the function/class signature with its decorators
121
+ - Show the filename and line range in the header
122
+ - If the snippet depends on one obvious external type or constant, include a
123
+ brief inline note
124
+ - **Before presenting, scan for secrets.** Redact API keys, tokens, passwords,
125
+ connection strings with `[REDACTED]`. Skip snippets that are entirely
126
+ secrets or contain PII/email addresses/personal identifiers.
127
+
128
+ ### 4. Evaluation — Assess the Answer
129
+
130
+ Evaluate across two dimensions, scaled to the current difficulty level.
131
+
132
+ #### A. Application Logic (what the code does in the project)
133
+
134
+ | Level | Expectation |
135
+ |-------|-------------|
136
+ | 1 | Names what the function does at a basic level |
137
+ | 2 | Identifies inputs, outputs, and at least one edge case |
138
+ | 3 | Explains the module role, failure modes, and upstream/downstream connections |
139
+ | 4 | Identifies the design pattern, multi-component interaction, and concurrency edge cases |
140
+ | 5 | Explains architectural role across system layers, performance implications, and subtle bugs or limitations |
141
+
142
+ #### B. Language Mechanics (syntax and semantics)
143
+
144
+ | Level | Expectation |
145
+ |-------|-------------|
146
+ | 1 | Basic types, function definition syntax, simple `if`/`else` |
147
+ | 2 | Loop mechanics, list/dict operations, basic `try`/`except`, string formatting |
148
+ | 3 | Comprehensions, decorator syntax and effect, `with` / context managers, type hints, exception chaining |
149
+ | 4 | Generator mechanics (`yield`), `async`/`await` internals, descriptor protocol, closures, threading primitives |
150
+ | 5 | Coroutine internals, metaclass programming, GIL implications, memory model, `__slots__`, MRO, weak references |
151
+
152
+ #### The Three-Strikes Rule
153
+
154
+ If the user's answer does **not** meet the expectations for the current
155
+ difficulty level:
156
+
157
+ **Strike 1** — Give a category-level nudge:
158
+ ```
159
+ Good start, but at Level N I'd expect you to also notice [category — e.g.,
160
+ "how errors are handled" or "what the decorator is doing"]. Try again —
161
+ what about [specific nudge — e.g., "the return type on line 47"]?
162
+ ```
163
+
164
+ **Strike 2** — Give a near-explicit hint:
165
+ ```
166
+ Getting closer. One more thing — [nearly names the concept — e.g., "that
167
+ @retry decorator wraps the function"]. Look at line X.
168
+ ```
169
+
170
+ **Strike 3** — Reveal the full answer and move on:
171
+ ```
172
+ Let me walk you through it.
173
+ ```
174
+ Then deliver the complete evaluation (both axes) as if they had skipped.
175
+ After the evaluation, proceed directly to the next round — do not ask
176
+ "another round?" after a strike-3 reveal; just present the next snippet.
177
+
178
+ If the user gets it on attempt 2 or 3:
179
+ ```
180
+ There you go! Now let me fill in what else is notable.
181
+ ```
182
+ Then provide the remaining feedback they missed, and ask "Another round?".
183
+
184
+ If the user's answer **meets** expectations (any attempt):
185
+ - Highlight 2–4 specific things they got right
186
+ - Add 1–3 things they could sharpen (even a strong answer has nuance)
187
+ - Reveal the file context
188
+ - Ask "Another round?"
189
+
190
+ #### Feedback structure (success or strike-3)
191
+
192
+ ```
193
+ **What you got right:**
194
+ - [2–4 specific things correctly identified]
195
+
196
+ **What you missed or could sharpen:**
197
+ - [1–3 things, with brief explanation]
198
+
199
+ **Context:** `services/position_sizer.py` — called by the OrderManager before
200
+ placing any trade. Sits between the signal generator and the exchange adapter.
201
+ ```
202
+
203
+ Keep feedback constructive. The goal is learning, not grading. If they
204
+ nailed everything at-level, say so and highlight the nuance they caught.
205
+
206
+ #### Handling commands mid-round
207
+
208
+ | Command | Behavior |
209
+ |---------|----------|
210
+ | `hint` | Give one strike-1 level nudge (counts as an attempt in the strike system) |
211
+ | `skip` / `reveal` | Show full evaluation immediately. Move to next round. |
212
+ | `next` / `another` | Skip this snippet, draw a new one. No strike counted. |
213
+ | `level N` / `lN` (e.g. `level 5`, `l2`) | Adjust difficulty for subsequent rounds. |
214
+ | `easier` | Decrease level by 1 (minimum 1). |
215
+ | `harder` | Increase level by 1 (maximum 5). |
216
+ | `stop` / `done` / `end` | End session. Deliver summary. |
217
+
218
+ ### 5. Loop — Keep Going
219
+
220
+ After a successful evaluation or a `next` skip, ask:
221
+ "Another round? (yes / no / level N / stop)"
222
+
223
+ After a strike-3 reveal, do **not** ask — proceed directly to the next
224
+ round with: "Round N+1 — Level X | `file.py`"
225
+
226
+ ### End-of-Session Summary
227
+
228
+ When the user says `stop`:
229
+
230
+ ```
231
+ ## Session Summary
232
+
233
+ Rounds completed: 5
234
+ Level played: 3
235
+ Files covered:
236
+ - services/position_sizer.py (rounds 1, 4)
237
+ - agents/news_agent.py (round 2)
238
+ - utils/fuzzy_dedup.py (round 3)
239
+ - database.py (round 5)
240
+
241
+ What you're strong on: [concepts consistently identified]
242
+ What to review: [concepts missed across multiple rounds]
243
+ Suggested next level: [3 → 4, or stay, or 3 → 2]
244
+ ```
245
+
246
+ ## Multilingual Projects
247
+
248
+ If the project contains multiple languages, let the user's `teach me <lang>`
249
+ filter govern. If no filter, sample all languages proportionally but announce
250
+ the language in each round header. Use language-appropriate evaluation
251
+ criteria for the Mechanics axis:
252
+
253
+ - **Python:** decorators, generators, descriptors, `async`/`await`, type hints,
254
+ context managers, MRO, slots, data classes
255
+ - **JavaScript/TypeScript:** closures, prototypes, `this` binding, promises,
256
+ async/await, destructuring, spread, arrow functions, TypeScript generics
257
+ - **Rust:** ownership, borrowing, lifetimes, pattern matching, `Result`/`Option`,
258
+ traits, generics, macros
259
+ - **Go:** goroutines, channels, interfaces, defer, error handling conventions,
260
+ zero values
261
+ - **Java:** streams, generics, annotations, try-with-resources, concurrency
262
+ primitives, inheritance vs composition
263
+
264
+ ## Guardrails
265
+
266
+ - **Never show secrets.** Scan every snippet before display. Redact API keys,
267
+ tokens, passwords, connection strings with `[REDACTED]`. Skip entire snippets
268
+ that are only secrets/config.
269
+ - **Never show user data.** Skip snippets containing PII, email addresses,
270
+ phone numbers, or personal identifiers.
271
+ - **One snippet per turn.** Wait for the user's response before showing the next.
272
+ - **Respect stop immediately.** If the user says `stop`, deliver the summary —
273
+ do not squeeze in another round.
274
+ - **Stay in teaching mode.** Do not fix bugs, refactor, or edit code during a
275
+ teaching session unless the user explicitly asks to switch modes.
276
+
277
+ ## Verification
278
+
279
+ After each round, confirm:
280
+ - The snippet was actually read from the file (not hallucinated)
281
+ - The line numbers match the source
282
+ - The feedback accurately describes what the code does
283
+ - No secrets or PII were exposed
284
+ - 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
  }