@wbern/claude-instructions 1.17.0 → 1.18.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 +2 -1
- package/bin/cli.js +6 -11
- package/downloads/with-beads/code-review.md +0 -6
- package/downloads/with-beads/commands-metadata.json +10 -0
- package/downloads/with-beads/kata.md +444 -0
- package/downloads/with-beads/worktree-add.md +3 -2
- package/downloads/without-beads/code-review.md +0 -6
- package/downloads/without-beads/commands-metadata.json +10 -0
- package/downloads/without-beads/kata.md +442 -0
- package/downloads/without-beads/worktree-add.md +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://claude.ai/code)
|
|
10
10
|
[](https://github.com/wbern/claude-instructions/graphs/contributors)
|
|
11
11
|
[](https://github.com/wbern/claude-instructions/pulls)
|
|
12
|
-
[](https://github.com/wbern/claude-instructions#available-commands)
|
|
13
13
|
|
|
14
14
|
```
|
|
15
15
|
_==/ i i \==_
|
|
@@ -239,6 +239,7 @@ flowchart TB
|
|
|
239
239
|
|
|
240
240
|
- `/beepboop` - Communicate AI-generated content with transparent attribution
|
|
241
241
|
- `/add-command` - Guide for creating new slash commands
|
|
242
|
+
- `/kata` - Generate a TDD practice challenge with boilerplate test setup
|
|
242
243
|
|
|
243
244
|
## Getting Started
|
|
244
245
|
|
package/bin/cli.js
CHANGED
|
@@ -409,6 +409,7 @@ var DIRECTORIES = {
|
|
|
409
409
|
DOWNLOADS: "downloads"
|
|
410
410
|
};
|
|
411
411
|
var TEMPLATE_SOURCE_FILES = ["CLAUDE.md", "AGENTS.md"];
|
|
412
|
+
var REQUESTED_TOOLS_KEY = "_requested-tools";
|
|
412
413
|
var ELLIPSIS = "...";
|
|
413
414
|
function truncatePathFromLeft(pathStr, maxLength) {
|
|
414
415
|
if (pathStr.length <= maxLength) {
|
|
@@ -465,9 +466,6 @@ async function checkExistingFiles(outputPath, variant, scope, options) {
|
|
|
465
466
|
variant || VARIANTS.WITH_BEADS
|
|
466
467
|
);
|
|
467
468
|
const destinationPath = outputPath || getDestinationPath(outputPath, scope);
|
|
468
|
-
if (!destinationPath) {
|
|
469
|
-
return [];
|
|
470
|
-
}
|
|
471
469
|
const allFiles = await fs.readdir(sourcePath);
|
|
472
470
|
const files = options?.commands ? allFiles.filter((f) => options.commands.includes(f)) : allFiles;
|
|
473
471
|
const existingFiles = [];
|
|
@@ -487,7 +485,7 @@ async function checkExistingFiles(outputPath, variant, scope, options) {
|
|
|
487
485
|
let newContent = await fs.readFile(sourceFilePath, "utf-8");
|
|
488
486
|
if (metadata && allowedToolsSet) {
|
|
489
487
|
const commandMetadata = metadata[file];
|
|
490
|
-
const requestedTools = commandMetadata?.[
|
|
488
|
+
const requestedTools = commandMetadata?.[REQUESTED_TOOLS_KEY] || [];
|
|
491
489
|
const toolsForCommand = requestedTools.filter(
|
|
492
490
|
(tool) => allowedToolsSet.has(tool)
|
|
493
491
|
);
|
|
@@ -582,9 +580,9 @@ async function getRequestedToolsOptions(variant) {
|
|
|
582
580
|
const metadata = await loadCommandsMetadata(variant);
|
|
583
581
|
const toolToCommands = /* @__PURE__ */ new Map();
|
|
584
582
|
for (const [filename, data] of Object.entries(metadata)) {
|
|
585
|
-
if (data[
|
|
583
|
+
if (data[REQUESTED_TOOLS_KEY]) {
|
|
586
584
|
const commandName = filename.replace(/\.md$/, "");
|
|
587
|
-
for (const tool of data[
|
|
585
|
+
for (const tool of data[REQUESTED_TOOLS_KEY]) {
|
|
588
586
|
const commands = toolToCommands.get(tool) || [];
|
|
589
587
|
commands.push(commandName);
|
|
590
588
|
toolToCommands.set(tool, commands);
|
|
@@ -607,7 +605,7 @@ function getDestinationPath(outputPath, scope) {
|
|
|
607
605
|
if (scope === SCOPES.USER) {
|
|
608
606
|
return path2.join(os.homedir(), DIRECTORIES.CLAUDE, DIRECTORIES.COMMANDS);
|
|
609
607
|
}
|
|
610
|
-
|
|
608
|
+
throw new Error("Either outputPath or scope must be provided");
|
|
611
609
|
}
|
|
612
610
|
function extractTemplateBlocks(content) {
|
|
613
611
|
const blocks = [];
|
|
@@ -634,9 +632,6 @@ async function generateToDirectory(outputPath, variant, scope, options) {
|
|
|
634
632
|
variant || VARIANTS.WITH_BEADS
|
|
635
633
|
);
|
|
636
634
|
const destinationPath = getDestinationPath(outputPath, scope);
|
|
637
|
-
if (!destinationPath) {
|
|
638
|
-
throw new Error("Either outputPath or scope must be provided");
|
|
639
|
-
}
|
|
640
635
|
const allFiles = await fs.readdir(sourcePath);
|
|
641
636
|
let files = options?.commands ? allFiles.filter((f) => options.commands.includes(f)) : allFiles;
|
|
642
637
|
if (options?.skipFiles) {
|
|
@@ -660,7 +655,7 @@ async function generateToDirectory(outputPath, variant, scope, options) {
|
|
|
660
655
|
const allowedToolsSet = new Set(options.allowedTools);
|
|
661
656
|
for (const file of files) {
|
|
662
657
|
const commandMetadata = metadata[file];
|
|
663
|
-
const requestedTools = commandMetadata?.[
|
|
658
|
+
const requestedTools = commandMetadata?.[REQUESTED_TOOLS_KEY] || [];
|
|
664
659
|
const toolsForCommand = requestedTools.filter(
|
|
665
660
|
(tool) => allowedToolsSet.has(tool)
|
|
666
661
|
);
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Code review using dynamic category detection and domain-specific analysis
|
|
3
3
|
argument-hint: (optional) [branch, PR#, or PR URL] - defaults to current branch
|
|
4
|
-
- Bash(git diff:*)
|
|
5
|
-
- Bash(git status:*)
|
|
6
|
-
- Bash(git log:*)
|
|
7
|
-
- Bash(git rev-parse:*)
|
|
8
|
-
- Bash(git merge-base:*)
|
|
9
|
-
- Bash(git branch:*)
|
|
10
4
|
---
|
|
11
5
|
|
|
12
6
|
## General Guidelines
|
|
@@ -68,6 +68,16 @@
|
|
|
68
68
|
"category": "Planning",
|
|
69
69
|
"order": 1
|
|
70
70
|
},
|
|
71
|
+
"kata.md": {
|
|
72
|
+
"description": "Generate a TDD practice challenge with boilerplate test setup",
|
|
73
|
+
"hint": "Practice kata",
|
|
74
|
+
"category": "Utilities",
|
|
75
|
+
"order": 10,
|
|
76
|
+
"_requested-tools": [
|
|
77
|
+
"WebFetch(domain:raw.githubusercontent.com)",
|
|
78
|
+
"WebFetch(domain:api.github.com)"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
71
81
|
"plan.md": {
|
|
72
82
|
"description": "Create implementation plan from feature/requirement with PRD-style discovery and TDD acceptance criteria",
|
|
73
83
|
"hint": "Plan feature",
|
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate a TDD practice challenge with boilerplate test setup
|
|
3
|
+
argument-hint: (no arguments - interactive)
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Kata: TDD Practice Challenge Generator
|
|
7
|
+
|
|
8
|
+
Generate a complete TDD practice setup:
|
|
9
|
+
|
|
10
|
+
- `CHALLENGE.md` - Problem description
|
|
11
|
+
- Test file with first test placeholder
|
|
12
|
+
- Implementation file with empty function
|
|
13
|
+
|
|
14
|
+
## General Guidelines
|
|
15
|
+
|
|
16
|
+
### Output Style
|
|
17
|
+
|
|
18
|
+
- **Never explicitly mention TDD** in code, comments, commits, PRs, or issues
|
|
19
|
+
- Write natural, descriptive code without meta-commentary about the development process
|
|
20
|
+
- The code should speak for itself - TDD is the process, not the product
|
|
21
|
+
|
|
22
|
+
Beads is available for task tracking. Use `mcp__beads__*` tools to manage issues (the user interacts via `bd` commands).
|
|
23
|
+
|
|
24
|
+
## Input
|
|
25
|
+
|
|
26
|
+
$ARGUMENTS
|
|
27
|
+
|
|
28
|
+
(This command is interactive - arguments are ignored)
|
|
29
|
+
|
|
30
|
+
## Data Source
|
|
31
|
+
|
|
32
|
+
Exercises from [cyber-dojo](https://github.com/cyber-dojo/exercises-start-points) (60 exercises, stable 10+ years).
|
|
33
|
+
|
|
34
|
+
- **List:** `https://api.github.com/repos/cyber-dojo/exercises-start-points/contents/start-points`
|
|
35
|
+
- **Fetch:** `https://raw.githubusercontent.com/cyber-dojo/exercises-start-points/master/start-points/{NAME}/readme.txt`
|
|
36
|
+
|
|
37
|
+
## Kata Categories
|
|
38
|
+
|
|
39
|
+
<kata_categories>
|
|
40
|
+
<by_difficulty>
|
|
41
|
+
<beginner description="Simple logic, single function">
|
|
42
|
+
Fizz_Buzz, Leap_Years, Prime_Factors, Word_Wrap, Closest_To_Zero,
|
|
43
|
+
Remove_Duplicates, Array_Shuffle, Friday_13th, Five_Weekends,
|
|
44
|
+
Number_Names, Print_Diamond, LCD_Digits, Fisher_Yates_Shuffle
|
|
45
|
+
</beginner>
|
|
46
|
+
<intermediate description="Multiple rules, edge cases">
|
|
47
|
+
Roman_Numerals, Reverse_Roman, Bowling_Game, Tennis, Anagrams,
|
|
48
|
+
ISBN, Balanced_Parentheses, Calc_Stats, Recently_Used_List,
|
|
49
|
+
Phone_Numbers, Combined_Number, Group_Neighbours, Longest_Common_Prefix,
|
|
50
|
+
Yatzy, Yatzy_Cutdown, Harry_Potter, Vending_Machine, Count_Coins,
|
|
51
|
+
100_doors, Haiku_Review, ABC_Problem, Align_Columns, Best_Shuffle,
|
|
52
|
+
Filename_Range, Unsplice, 12_Days_of_Xmas
|
|
53
|
+
</intermediate>
|
|
54
|
+
<advanced description="Complex algorithms, state management">
|
|
55
|
+
Game_of_Life, Mars_Rover, Mine_Sweeper, Mine_Field, Eight_Queens,
|
|
56
|
+
Knights_Tour, Reversi, Poker_Hands, Levenshtein_Distance,
|
|
57
|
+
Magic_Square, Saddle_Points, Tiny_Maze, Gray_Code, Monty_Hall,
|
|
58
|
+
Number_Chains, Wonderland_Number, Zeckendorf_Number,
|
|
59
|
+
Diff_Selector, Diversion, Reordering, Fizz_Buzz_Plus
|
|
60
|
+
</advanced>
|
|
61
|
+
</by_difficulty>
|
|
62
|
+
|
|
63
|
+
<by_type>
|
|
64
|
+
<string_text description="String/Text manipulation">
|
|
65
|
+
Anagrams, Word_Wrap, Align_Columns, Best_Shuffle, Haiku_Review,
|
|
66
|
+
Phone_Numbers, 12_Days_of_Xmas, Longest_Common_Prefix, Unsplice
|
|
67
|
+
</string_text>
|
|
68
|
+
<math_numbers description="Math & Numbers">
|
|
69
|
+
Fizz_Buzz, Fizz_Buzz_Plus, Prime_Factors, Roman_Numerals, Reverse_Roman,
|
|
70
|
+
Zeckendorf_Number, Number_Names, Combined_Number, Closest_To_Zero,
|
|
71
|
+
Count_Coins, ISBN, LCD_Digits, Leap_Years, Five_Weekends, Friday_13th
|
|
72
|
+
</math_numbers>
|
|
73
|
+
<data_structures description="Data Structures & Algorithms">
|
|
74
|
+
Recently_Used_List, Balanced_Parentheses, Calc_Stats, Remove_Duplicates,
|
|
75
|
+
Array_Shuffle, Fisher_Yates_Shuffle, Levenshtein_Distance, Gray_Code,
|
|
76
|
+
Number_Chains, Wonderland_Number, 100_doors, Magic_Square, Saddle_Points,
|
|
77
|
+
Diff_Selector, Diversion, Reordering
|
|
78
|
+
</data_structures>
|
|
79
|
+
<game_logic description="Game Logic & Simulation">
|
|
80
|
+
Game_of_Life, Bowling_Game, Tennis, Yatzy, Yatzy_Cutdown,
|
|
81
|
+
Mine_Sweeper, Mine_Field, Mars_Rover, Reversi, Poker_Hands,
|
|
82
|
+
Harry_Potter, Eight_Queens, Knights_Tour, Tiny_Maze, Monty_Hall,
|
|
83
|
+
Vending_Machine, Print_Diamond, ABC_Problem, Group_Neighbours, Filename_Range
|
|
84
|
+
</game_logic>
|
|
85
|
+
</by_type>
|
|
86
|
+
</kata_categories>
|
|
87
|
+
|
|
88
|
+
## Process
|
|
89
|
+
|
|
90
|
+
Use conversational AskUserQuestion flow. User can skip to suggestions at any point.
|
|
91
|
+
|
|
92
|
+
<execution_steps>
|
|
93
|
+
|
|
94
|
+
<step_1>
|
|
95
|
+
<description>Ask about difficulty preference</description>
|
|
96
|
+
<prompt>
|
|
97
|
+
<message>What difficulty level interests you?</message>
|
|
98
|
+
<options>
|
|
99
|
+
<option value="beginner">
|
|
100
|
+
<label>Beginner</label>
|
|
101
|
+
<description>Simple logic, single function (Fizz_Buzz, Leap_Years, Prime_Factors...)</description>
|
|
102
|
+
</option>
|
|
103
|
+
<option value="intermediate">
|
|
104
|
+
<label>Intermediate</label>
|
|
105
|
+
<description>Multiple rules, edge cases (Roman_Numerals, Bowling_Game, Tennis...)</description>
|
|
106
|
+
</option>
|
|
107
|
+
<option value="advanced">
|
|
108
|
+
<label>Advanced</label>
|
|
109
|
+
<description>Complex algorithms, state (Game_of_Life, Mars_Rover, Mine_Sweeper...)</description>
|
|
110
|
+
</option>
|
|
111
|
+
<option value="skip">
|
|
112
|
+
<label>Just show me suggestions!</label>
|
|
113
|
+
<description>Skip questions and see kata recommendations</description>
|
|
114
|
+
</option>
|
|
115
|
+
</options>
|
|
116
|
+
</prompt>
|
|
117
|
+
<if value="skip">Jump to step_suggest</if>
|
|
118
|
+
<set_variable>$DIFFICULTY = selected value</set_variable>
|
|
119
|
+
</step_1>
|
|
120
|
+
|
|
121
|
+
<step_2>
|
|
122
|
+
<description>Ask about challenge type</description>
|
|
123
|
+
<prompt>
|
|
124
|
+
<message>What kind of challenge interests you?</message>
|
|
125
|
+
<options>
|
|
126
|
+
<option value="string_text">
|
|
127
|
+
<label>String/Text</label>
|
|
128
|
+
<description>Text manipulation, parsing, formatting</description>
|
|
129
|
+
</option>
|
|
130
|
+
<option value="math_numbers">
|
|
131
|
+
<label>Math & Numbers</label>
|
|
132
|
+
<description>Calculations, conversions, number theory</description>
|
|
133
|
+
</option>
|
|
134
|
+
<option value="data_structures">
|
|
135
|
+
<label>Data Structures</label>
|
|
136
|
+
<description>Lists, algorithms, transformations</description>
|
|
137
|
+
</option>
|
|
138
|
+
<option value="game_logic">
|
|
139
|
+
<label>Game Logic</label>
|
|
140
|
+
<description>Games, simulations, state machines</description>
|
|
141
|
+
</option>
|
|
142
|
+
<option value="skip">
|
|
143
|
+
<label>Show me suggestions now!</label>
|
|
144
|
+
<description>Skip remaining questions</description>
|
|
145
|
+
</option>
|
|
146
|
+
</options>
|
|
147
|
+
</prompt>
|
|
148
|
+
<if value="skip">Jump to step_suggest</if>
|
|
149
|
+
<set_variable>$TYPE = selected value</set_variable>
|
|
150
|
+
</step_2>
|
|
151
|
+
|
|
152
|
+
<step_suggest>
|
|
153
|
+
<description>Show kata suggestions based on filters</description>
|
|
154
|
+
<logic>
|
|
155
|
+
- Filter kata_categories by $DIFFICULTY (if set)
|
|
156
|
+
- Filter by $TYPE (if set)
|
|
157
|
+
- If no filters, pick 3 varied suggestions
|
|
158
|
+
- Select 3 katas that match criteria
|
|
159
|
+
- For each kata, fetch a preview or use the descriptions below
|
|
160
|
+
</logic>
|
|
161
|
+
<kata_descriptions>
|
|
162
|
+
<!-- Beginner -->
|
|
163
|
+
Fizz_Buzz: Print 1-100 replacing multiples of 3/5 with Fizz/Buzz
|
|
164
|
+
Leap_Years: Determine if a year is a leap year (divisibility rules)
|
|
165
|
+
Prime_Factors: Find prime factors of a number
|
|
166
|
+
Word_Wrap: Wrap text to fit within a column width
|
|
167
|
+
Closest_To_Zero: Find the number closest to zero from a list
|
|
168
|
+
Remove_Duplicates: Remove duplicate elements from a list
|
|
169
|
+
Array_Shuffle: Randomly shuffle array elements
|
|
170
|
+
Friday_13th: Count Friday the 13ths in a given year
|
|
171
|
+
Five_Weekends: Find months with 5 Fridays, Saturdays, and Sundays
|
|
172
|
+
Number_Names: Convert numbers to English words (one, two, three...)
|
|
173
|
+
Print_Diamond: Print a diamond shape of letters
|
|
174
|
+
LCD_Digits: Display numbers as LCD-style digits
|
|
175
|
+
Fisher_Yates_Shuffle: Implement the Fisher-Yates shuffle algorithm
|
|
176
|
+
|
|
177
|
+
<!-- Intermediate -->
|
|
178
|
+
Roman_Numerals: Convert Arabic numbers to Roman numerals
|
|
179
|
+
Reverse_Roman: Convert Roman numerals back to Arabic numbers
|
|
180
|
+
Bowling_Game: Score a 10-pin bowling game with spares/strikes
|
|
181
|
+
Tennis: Track tennis game score with deuce/advantage
|
|
182
|
+
Anagrams: Find all anagrams of a word from a dictionary
|
|
183
|
+
ISBN: Validate ISBN-10 check digits
|
|
184
|
+
Balanced_Parentheses: Check if brackets are properly balanced
|
|
185
|
+
Calc_Stats: Calculate min/max/count/average from numbers
|
|
186
|
+
Recently_Used_List: Implement a most-recently-used list
|
|
187
|
+
Phone_Numbers: Convert phone numbers to words using keypad letters
|
|
188
|
+
Combined_Number: Arrange numbers to form the largest combined number
|
|
189
|
+
Group_Neighbours: Group adjacent equal elements in a list
|
|
190
|
+
Longest_Common_Prefix: Find longest common prefix among strings
|
|
191
|
+
Yatzy: Score a Yatzy dice game (full version)
|
|
192
|
+
Yatzy_Cutdown: Simplified Yatzy scoring
|
|
193
|
+
Harry_Potter: Calculate discounts for Harry Potter book sets
|
|
194
|
+
Vending_Machine: Calculate change for vending machine purchases
|
|
195
|
+
Count_Coins: Count ways to make change with given coins
|
|
196
|
+
100_doors: Toggle 100 doors puzzle (open/close pattern)
|
|
197
|
+
Haiku_Review: Validate haiku syllable structure (5-7-5)
|
|
198
|
+
ABC_Problem: Spell words using lettered blocks
|
|
199
|
+
Align_Columns: Align text into formatted columns
|
|
200
|
+
Best_Shuffle: Shuffle string so no character stays in place
|
|
201
|
+
Filename_Range: Generate filename sequences (file001, file002...)
|
|
202
|
+
Unsplice: Reverse a string splice operation
|
|
203
|
+
12_Days_of_Xmas: Generate "12 Days of Christmas" lyrics
|
|
204
|
+
|
|
205
|
+
<!-- Advanced -->
|
|
206
|
+
Game_of_Life: Conway's cellular automaton simulation
|
|
207
|
+
Mars_Rover: Navigate a rover on a grid with commands (L/R/M)
|
|
208
|
+
Mine_Sweeper: Generate numbers for a minesweeper grid
|
|
209
|
+
Mine_Field: Place mines randomly on a grid
|
|
210
|
+
Eight_Queens: Place 8 queens on a chessboard without conflicts
|
|
211
|
+
Knights_Tour: Find a path visiting all squares on a chessboard
|
|
212
|
+
Reversi: Implement Reversi/Othello game logic
|
|
213
|
+
Poker_Hands: Compare and rank poker hands
|
|
214
|
+
Levenshtein_Distance: Calculate edit distance between strings
|
|
215
|
+
Magic_Square: Generate magic squares (rows/cols/diags sum equal)
|
|
216
|
+
Saddle_Points: Find saddle points in a matrix
|
|
217
|
+
Tiny_Maze: Solve a small maze pathfinding problem
|
|
218
|
+
Gray_Code: Generate Gray code sequences
|
|
219
|
+
Monty_Hall: Simulate the Monty Hall probability problem
|
|
220
|
+
Number_Chains: Find chains where numbers link by digits
|
|
221
|
+
Wonderland_Number: Find 6-digit number with multiplication property
|
|
222
|
+
Zeckendorf_Number: Represent as sum of non-consecutive Fibonacci numbers
|
|
223
|
+
Diff_Selector: Select differences between data sets
|
|
224
|
+
Diversion: Route around obstacles
|
|
225
|
+
Reordering: Reorder elements based on rules
|
|
226
|
+
Fizz_Buzz_Plus: Extended FizzBuzz with additional rules
|
|
227
|
+
</kata_descriptions>
|
|
228
|
+
<prompt>
|
|
229
|
+
<message>Here are 3 katas that match your criteria:</message>
|
|
230
|
+
<options>
|
|
231
|
+
<option value="kata_1">
|
|
232
|
+
<label>{Kata_Name_1}</label>
|
|
233
|
+
<description>{Description from kata_descriptions}</description>
|
|
234
|
+
</option>
|
|
235
|
+
<option value="kata_2">
|
|
236
|
+
<label>{Kata_Name_2}</label>
|
|
237
|
+
<description>{Description from kata_descriptions}</description>
|
|
238
|
+
</option>
|
|
239
|
+
<option value="kata_3">
|
|
240
|
+
<label>{Kata_Name_3}</label>
|
|
241
|
+
<description>{Description from kata_descriptions}</description>
|
|
242
|
+
</option>
|
|
243
|
+
<option value="more_suggestions">
|
|
244
|
+
<label>Show me 3 different ones</label>
|
|
245
|
+
<description>Same criteria, different suggestions</description>
|
|
246
|
+
</option>
|
|
247
|
+
<option value="more_questions">
|
|
248
|
+
<label>Ask me more questions...</label>
|
|
249
|
+
<description>Refine my preferences further</description>
|
|
250
|
+
</option>
|
|
251
|
+
</options>
|
|
252
|
+
</prompt>
|
|
253
|
+
<if value="more_suggestions">Pick 3 different katas matching same criteria, repeat step_suggest</if>
|
|
254
|
+
<if value="more_questions">
|
|
255
|
+
- If user skipped from step_1: Jump to step_1 (ask difficulty)
|
|
256
|
+
- If user answered step_1 but skipped step_2: Jump to step_2 (ask type)
|
|
257
|
+
- If user answered both: Jump to step_1 to reconsider from start
|
|
258
|
+
</if>
|
|
259
|
+
<set_variable>$SELECTED_KATA = selected kata name</set_variable>
|
|
260
|
+
</step_suggest>
|
|
261
|
+
|
|
262
|
+
<step_fetch>
|
|
263
|
+
<description>Fetch kata content from cyber-dojo</description>
|
|
264
|
+
<action>
|
|
265
|
+
Use WebFetch to get:
|
|
266
|
+
https://raw.githubusercontent.com/cyber-dojo/exercises-start-points/master/start-points/{$SELECTED_KATA}/readme.txt
|
|
267
|
+
</action>
|
|
268
|
+
<store>$KATA_CONTENT = fetched readme content</store>
|
|
269
|
+
</step_fetch>
|
|
270
|
+
|
|
271
|
+
<step_confirm>
|
|
272
|
+
<description>Show full kata details and ask for language</description>
|
|
273
|
+
<display>
|
|
274
|
+
Present the full kata content to the user:
|
|
275
|
+
|
|
276
|
+
## {$SELECTED_KATA}
|
|
277
|
+
|
|
278
|
+
**Difficulty:** {$DIFFICULTY_STARS based on category - ⭐ Beginner, ⭐⭐ Intermediate, ⭐⭐⭐ Advanced}
|
|
279
|
+
|
|
280
|
+
### Problem Description
|
|
281
|
+
{$KATA_CONTENT from readme.txt}
|
|
282
|
+
</display>
|
|
283
|
+
<prompt>
|
|
284
|
+
<message>What language will you use for this kata?</message>
|
|
285
|
+
<options>
|
|
286
|
+
<option value="typescript">
|
|
287
|
+
<label>TypeScript + Vitest</label>
|
|
288
|
+
<description>Modern test runner with great DX</description>
|
|
289
|
+
</option>
|
|
290
|
+
<option value="javascript">
|
|
291
|
+
<label>JavaScript + Vitest</label>
|
|
292
|
+
<description>Same great runner, no types</description>
|
|
293
|
+
</option>
|
|
294
|
+
<option value="python">
|
|
295
|
+
<label>Python + pytest</label>
|
|
296
|
+
<description>Simple and powerful testing</description>
|
|
297
|
+
</option>
|
|
298
|
+
<option value="back">
|
|
299
|
+
<label>Show me other katas</label>
|
|
300
|
+
<description>Go back to suggestions</description>
|
|
301
|
+
</option>
|
|
302
|
+
</options>
|
|
303
|
+
</prompt>
|
|
304
|
+
<note>User can also select "Other" to type a custom language/framework</note>
|
|
305
|
+
<if value="back">Jump back to step_suggest</if>
|
|
306
|
+
<set_variable>$LANGUAGE = selected value (or custom input)</set_variable>
|
|
307
|
+
</step_confirm>
|
|
308
|
+
|
|
309
|
+
<step_generate>
|
|
310
|
+
<description>Generate kata files based on language</description>
|
|
311
|
+
<action>Create the following files based on $LANGUAGE:</action>
|
|
312
|
+
|
|
313
|
+
<file name="CHALLENGE.md">
|
|
314
|
+
# Kata: {$SELECTED_KATA}
|
|
315
|
+
|
|
316
|
+
## Difficulty
|
|
317
|
+
|
|
318
|
+
{$DIFFICULTY_STARS based on category}
|
|
319
|
+
|
|
320
|
+
## Problem
|
|
321
|
+
|
|
322
|
+
{$KATA_CONTENT from readme.txt}
|
|
323
|
+
|
|
324
|
+
## TDD Approach
|
|
325
|
+
|
|
326
|
+
Work through this kata using the red-green-refactor cycle:
|
|
327
|
+
|
|
328
|
+
1. **Red**: Write a failing test for the simplest case
|
|
329
|
+
2. **Green**: Write minimal code to pass
|
|
330
|
+
3. **Refactor**: Clean up while keeping tests green
|
|
331
|
+
4. **Repeat**: Add the next test case
|
|
332
|
+
|
|
333
|
+
## Source
|
|
334
|
+
|
|
335
|
+
[cyber-dojo: {$SELECTED_KATA}](https://cyber-dojo.org)
|
|
336
|
+
</file>
|
|
337
|
+
|
|
338
|
+
<file name="kata.ts" condition="$LANGUAGE == typescript">
|
|
339
|
+
/**
|
|
340
|
+
* {$SELECTED_KATA}
|
|
341
|
+
* See CHALLENGE.md for requirements
|
|
342
|
+
*/
|
|
343
|
+
export function solve(input: unknown): unknown {
|
|
344
|
+
throw new Error("Not implemented - start with a failing test!");
|
|
345
|
+
}
|
|
346
|
+
</file>
|
|
347
|
+
|
|
348
|
+
<file name="kata.test.ts" condition="$LANGUAGE == typescript">
|
|
349
|
+
import { describe, it, expect } from "vitest";
|
|
350
|
+
import { solve } from "./kata";
|
|
351
|
+
|
|
352
|
+
describe("{$SELECTED_KATA}", () => {
|
|
353
|
+
it.todo("should handle the simplest case");
|
|
354
|
+
|
|
355
|
+
// Add your first real test here using the red-green-refactor cycle
|
|
356
|
+
});
|
|
357
|
+
</file>
|
|
358
|
+
|
|
359
|
+
<file name="kata.js" condition="$LANGUAGE == javascript">
|
|
360
|
+
/**
|
|
361
|
+
* {$SELECTED_KATA}
|
|
362
|
+
* See CHALLENGE.md for requirements
|
|
363
|
+
*/
|
|
364
|
+
export function solve(input) {
|
|
365
|
+
throw new Error("Not implemented - start with a failing test!");
|
|
366
|
+
}
|
|
367
|
+
</file>
|
|
368
|
+
|
|
369
|
+
<file name="kata.test.js" condition="$LANGUAGE == javascript">
|
|
370
|
+
import { describe, it, expect } from "vitest";
|
|
371
|
+
import { solve } from "./kata.js";
|
|
372
|
+
|
|
373
|
+
describe("{$SELECTED_KATA}", () => {
|
|
374
|
+
it.todo("should handle the simplest case");
|
|
375
|
+
|
|
376
|
+
// Add your first real test here using the red-green-refactor cycle
|
|
377
|
+
});
|
|
378
|
+
</file>
|
|
379
|
+
|
|
380
|
+
<file name="kata.py" condition="$LANGUAGE == python">
|
|
381
|
+
"""
|
|
382
|
+
{$SELECTED_KATA}
|
|
383
|
+
See CHALLENGE.md for requirements
|
|
384
|
+
"""
|
|
385
|
+
|
|
386
|
+
def solve(input):
|
|
387
|
+
raise NotImplementedError("Start with a failing test!")
|
|
388
|
+
</file>
|
|
389
|
+
|
|
390
|
+
<file name="test_kata.py" condition="$LANGUAGE == python">
|
|
391
|
+
import pytest
|
|
392
|
+
from kata import solve
|
|
393
|
+
|
|
394
|
+
class TestKata:
|
|
395
|
+
def test_placeholder(self):
|
|
396
|
+
"""Remove this and add your first real test"""
|
|
397
|
+
pytest.skip("Start with a failing test!")
|
|
398
|
+
|
|
399
|
+
# Add your first real test here using the red-green-refactor cycle
|
|
400
|
+
</file>
|
|
401
|
+
|
|
402
|
+
<custom_language condition="$LANGUAGE is custom input (user typed via 'Other')">
|
|
403
|
+
Generate appropriate boilerplate based on user's specified language:
|
|
404
|
+
- CHALLENGE.md (always)
|
|
405
|
+
- Implementation file with idiomatic naming and empty function
|
|
406
|
+
- Test file using common test framework for that language
|
|
407
|
+
|
|
408
|
+
Examples:
|
|
409
|
+
- "Go" → kata.go + kata_test.go (testing package)
|
|
410
|
+
- "Rust" → src/lib.rs + tests/kata_test.rs (cargo test)
|
|
411
|
+
- "Java" → Kata.java + KataTest.java (JUnit)
|
|
412
|
+
- "C#" → Kata.cs + KataTests.cs (xUnit/NUnit)
|
|
413
|
+
- "Ruby" → kata.rb + kata_spec.rb (RSpec)
|
|
414
|
+
- "Elixir" → kata.ex + kata_test.exs (ExUnit)
|
|
415
|
+
- "Haskell" → Kata.hs + KataSpec.hs (Hspec)
|
|
416
|
+
- "Clojure" → kata.clj + kata_test.clj (clojure.test)
|
|
417
|
+
|
|
418
|
+
Use your knowledge of the language's conventions and popular test frameworks.
|
|
419
|
+
Follow the same pattern: empty function that throws/raises "not implemented".
|
|
420
|
+
</custom_language>
|
|
421
|
+
|
|
422
|
+
<message>
|
|
423
|
+
Kata setup complete!
|
|
424
|
+
|
|
425
|
+
Created files:
|
|
426
|
+
- CHALLENGE.md (problem description)
|
|
427
|
+
{if $LANGUAGE != other}
|
|
428
|
+
- Implementation file with empty solve() function
|
|
429
|
+
- Test file with placeholder test
|
|
430
|
+
{endif}
|
|
431
|
+
|
|
432
|
+
Start practicing with `/red` to write your first failing test!
|
|
433
|
+
</message>
|
|
434
|
+
</step_generate>
|
|
435
|
+
|
|
436
|
+
</execution_steps>
|
|
437
|
+
|
|
438
|
+
## Notes
|
|
439
|
+
|
|
440
|
+
- Kata content is fetched at runtime from cyber-dojo's GitHub repository
|
|
441
|
+
- The cyber-dojo project has been maintained for 10+ years with stable URLs
|
|
442
|
+
- All exercises are designed for TDD practice
|
|
443
|
+
- User can always go back to refine their preferences
|
|
444
|
+
- Boilerplate uses `solve()` as the main function - rename as needed for clarity
|
|
@@ -212,8 +212,9 @@ Uncommitted changes: `git status --short`
|
|
|
212
212
|
<description>Create the worktree</description>
|
|
213
213
|
<option_a_new_branch>
|
|
214
214
|
<condition>Remote branch does NOT exist</condition>
|
|
215
|
-
<command>git worktree add ${parent_path}/${branch_name} -b ${branch_name} ${base_branch}</command>
|
|
216
|
-
<example>git worktree add ../fix/issue-123
|
|
215
|
+
<command>git worktree add ${parent_path}/${branch_name} -b ${branch_name} --no-track ${base_branch}</command>
|
|
216
|
+
<example>git worktree add ../fix/issue-123 -b fix/issue-123 --no-track origin/main</example>
|
|
217
|
+
<note>--no-track prevents git from setting upstream to base_branch (which would make git push target main!)</note>
|
|
217
218
|
</option_a_new_branch>
|
|
218
219
|
<option_b_existing_branch>
|
|
219
220
|
<condition>Remote branch EXISTS</condition>
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Code review using dynamic category detection and domain-specific analysis
|
|
3
3
|
argument-hint: (optional) [branch, PR#, or PR URL] - defaults to current branch
|
|
4
|
-
- Bash(git diff:*)
|
|
5
|
-
- Bash(git status:*)
|
|
6
|
-
- Bash(git log:*)
|
|
7
|
-
- Bash(git rev-parse:*)
|
|
8
|
-
- Bash(git merge-base:*)
|
|
9
|
-
- Bash(git branch:*)
|
|
10
4
|
---
|
|
11
5
|
|
|
12
6
|
## General Guidelines
|
|
@@ -68,6 +68,16 @@
|
|
|
68
68
|
"category": "Planning",
|
|
69
69
|
"order": 1
|
|
70
70
|
},
|
|
71
|
+
"kata.md": {
|
|
72
|
+
"description": "Generate a TDD practice challenge with boilerplate test setup",
|
|
73
|
+
"hint": "Practice kata",
|
|
74
|
+
"category": "Utilities",
|
|
75
|
+
"order": 10,
|
|
76
|
+
"_requested-tools": [
|
|
77
|
+
"WebFetch(domain:raw.githubusercontent.com)",
|
|
78
|
+
"WebFetch(domain:api.github.com)"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
71
81
|
"plan.md": {
|
|
72
82
|
"description": "Create implementation plan from feature/requirement with PRD-style discovery and TDD acceptance criteria",
|
|
73
83
|
"hint": "Plan feature",
|
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate a TDD practice challenge with boilerplate test setup
|
|
3
|
+
argument-hint: (no arguments - interactive)
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Kata: TDD Practice Challenge Generator
|
|
7
|
+
|
|
8
|
+
Generate a complete TDD practice setup:
|
|
9
|
+
|
|
10
|
+
- `CHALLENGE.md` - Problem description
|
|
11
|
+
- Test file with first test placeholder
|
|
12
|
+
- Implementation file with empty function
|
|
13
|
+
|
|
14
|
+
## General Guidelines
|
|
15
|
+
|
|
16
|
+
### Output Style
|
|
17
|
+
|
|
18
|
+
- **Never explicitly mention TDD** in code, comments, commits, PRs, or issues
|
|
19
|
+
- Write natural, descriptive code without meta-commentary about the development process
|
|
20
|
+
- The code should speak for itself - TDD is the process, not the product
|
|
21
|
+
|
|
22
|
+
## Input
|
|
23
|
+
|
|
24
|
+
$ARGUMENTS
|
|
25
|
+
|
|
26
|
+
(This command is interactive - arguments are ignored)
|
|
27
|
+
|
|
28
|
+
## Data Source
|
|
29
|
+
|
|
30
|
+
Exercises from [cyber-dojo](https://github.com/cyber-dojo/exercises-start-points) (60 exercises, stable 10+ years).
|
|
31
|
+
|
|
32
|
+
- **List:** `https://api.github.com/repos/cyber-dojo/exercises-start-points/contents/start-points`
|
|
33
|
+
- **Fetch:** `https://raw.githubusercontent.com/cyber-dojo/exercises-start-points/master/start-points/{NAME}/readme.txt`
|
|
34
|
+
|
|
35
|
+
## Kata Categories
|
|
36
|
+
|
|
37
|
+
<kata_categories>
|
|
38
|
+
<by_difficulty>
|
|
39
|
+
<beginner description="Simple logic, single function">
|
|
40
|
+
Fizz_Buzz, Leap_Years, Prime_Factors, Word_Wrap, Closest_To_Zero,
|
|
41
|
+
Remove_Duplicates, Array_Shuffle, Friday_13th, Five_Weekends,
|
|
42
|
+
Number_Names, Print_Diamond, LCD_Digits, Fisher_Yates_Shuffle
|
|
43
|
+
</beginner>
|
|
44
|
+
<intermediate description="Multiple rules, edge cases">
|
|
45
|
+
Roman_Numerals, Reverse_Roman, Bowling_Game, Tennis, Anagrams,
|
|
46
|
+
ISBN, Balanced_Parentheses, Calc_Stats, Recently_Used_List,
|
|
47
|
+
Phone_Numbers, Combined_Number, Group_Neighbours, Longest_Common_Prefix,
|
|
48
|
+
Yatzy, Yatzy_Cutdown, Harry_Potter, Vending_Machine, Count_Coins,
|
|
49
|
+
100_doors, Haiku_Review, ABC_Problem, Align_Columns, Best_Shuffle,
|
|
50
|
+
Filename_Range, Unsplice, 12_Days_of_Xmas
|
|
51
|
+
</intermediate>
|
|
52
|
+
<advanced description="Complex algorithms, state management">
|
|
53
|
+
Game_of_Life, Mars_Rover, Mine_Sweeper, Mine_Field, Eight_Queens,
|
|
54
|
+
Knights_Tour, Reversi, Poker_Hands, Levenshtein_Distance,
|
|
55
|
+
Magic_Square, Saddle_Points, Tiny_Maze, Gray_Code, Monty_Hall,
|
|
56
|
+
Number_Chains, Wonderland_Number, Zeckendorf_Number,
|
|
57
|
+
Diff_Selector, Diversion, Reordering, Fizz_Buzz_Plus
|
|
58
|
+
</advanced>
|
|
59
|
+
</by_difficulty>
|
|
60
|
+
|
|
61
|
+
<by_type>
|
|
62
|
+
<string_text description="String/Text manipulation">
|
|
63
|
+
Anagrams, Word_Wrap, Align_Columns, Best_Shuffle, Haiku_Review,
|
|
64
|
+
Phone_Numbers, 12_Days_of_Xmas, Longest_Common_Prefix, Unsplice
|
|
65
|
+
</string_text>
|
|
66
|
+
<math_numbers description="Math & Numbers">
|
|
67
|
+
Fizz_Buzz, Fizz_Buzz_Plus, Prime_Factors, Roman_Numerals, Reverse_Roman,
|
|
68
|
+
Zeckendorf_Number, Number_Names, Combined_Number, Closest_To_Zero,
|
|
69
|
+
Count_Coins, ISBN, LCD_Digits, Leap_Years, Five_Weekends, Friday_13th
|
|
70
|
+
</math_numbers>
|
|
71
|
+
<data_structures description="Data Structures & Algorithms">
|
|
72
|
+
Recently_Used_List, Balanced_Parentheses, Calc_Stats, Remove_Duplicates,
|
|
73
|
+
Array_Shuffle, Fisher_Yates_Shuffle, Levenshtein_Distance, Gray_Code,
|
|
74
|
+
Number_Chains, Wonderland_Number, 100_doors, Magic_Square, Saddle_Points,
|
|
75
|
+
Diff_Selector, Diversion, Reordering
|
|
76
|
+
</data_structures>
|
|
77
|
+
<game_logic description="Game Logic & Simulation">
|
|
78
|
+
Game_of_Life, Bowling_Game, Tennis, Yatzy, Yatzy_Cutdown,
|
|
79
|
+
Mine_Sweeper, Mine_Field, Mars_Rover, Reversi, Poker_Hands,
|
|
80
|
+
Harry_Potter, Eight_Queens, Knights_Tour, Tiny_Maze, Monty_Hall,
|
|
81
|
+
Vending_Machine, Print_Diamond, ABC_Problem, Group_Neighbours, Filename_Range
|
|
82
|
+
</game_logic>
|
|
83
|
+
</by_type>
|
|
84
|
+
</kata_categories>
|
|
85
|
+
|
|
86
|
+
## Process
|
|
87
|
+
|
|
88
|
+
Use conversational AskUserQuestion flow. User can skip to suggestions at any point.
|
|
89
|
+
|
|
90
|
+
<execution_steps>
|
|
91
|
+
|
|
92
|
+
<step_1>
|
|
93
|
+
<description>Ask about difficulty preference</description>
|
|
94
|
+
<prompt>
|
|
95
|
+
<message>What difficulty level interests you?</message>
|
|
96
|
+
<options>
|
|
97
|
+
<option value="beginner">
|
|
98
|
+
<label>Beginner</label>
|
|
99
|
+
<description>Simple logic, single function (Fizz_Buzz, Leap_Years, Prime_Factors...)</description>
|
|
100
|
+
</option>
|
|
101
|
+
<option value="intermediate">
|
|
102
|
+
<label>Intermediate</label>
|
|
103
|
+
<description>Multiple rules, edge cases (Roman_Numerals, Bowling_Game, Tennis...)</description>
|
|
104
|
+
</option>
|
|
105
|
+
<option value="advanced">
|
|
106
|
+
<label>Advanced</label>
|
|
107
|
+
<description>Complex algorithms, state (Game_of_Life, Mars_Rover, Mine_Sweeper...)</description>
|
|
108
|
+
</option>
|
|
109
|
+
<option value="skip">
|
|
110
|
+
<label>Just show me suggestions!</label>
|
|
111
|
+
<description>Skip questions and see kata recommendations</description>
|
|
112
|
+
</option>
|
|
113
|
+
</options>
|
|
114
|
+
</prompt>
|
|
115
|
+
<if value="skip">Jump to step_suggest</if>
|
|
116
|
+
<set_variable>$DIFFICULTY = selected value</set_variable>
|
|
117
|
+
</step_1>
|
|
118
|
+
|
|
119
|
+
<step_2>
|
|
120
|
+
<description>Ask about challenge type</description>
|
|
121
|
+
<prompt>
|
|
122
|
+
<message>What kind of challenge interests you?</message>
|
|
123
|
+
<options>
|
|
124
|
+
<option value="string_text">
|
|
125
|
+
<label>String/Text</label>
|
|
126
|
+
<description>Text manipulation, parsing, formatting</description>
|
|
127
|
+
</option>
|
|
128
|
+
<option value="math_numbers">
|
|
129
|
+
<label>Math & Numbers</label>
|
|
130
|
+
<description>Calculations, conversions, number theory</description>
|
|
131
|
+
</option>
|
|
132
|
+
<option value="data_structures">
|
|
133
|
+
<label>Data Structures</label>
|
|
134
|
+
<description>Lists, algorithms, transformations</description>
|
|
135
|
+
</option>
|
|
136
|
+
<option value="game_logic">
|
|
137
|
+
<label>Game Logic</label>
|
|
138
|
+
<description>Games, simulations, state machines</description>
|
|
139
|
+
</option>
|
|
140
|
+
<option value="skip">
|
|
141
|
+
<label>Show me suggestions now!</label>
|
|
142
|
+
<description>Skip remaining questions</description>
|
|
143
|
+
</option>
|
|
144
|
+
</options>
|
|
145
|
+
</prompt>
|
|
146
|
+
<if value="skip">Jump to step_suggest</if>
|
|
147
|
+
<set_variable>$TYPE = selected value</set_variable>
|
|
148
|
+
</step_2>
|
|
149
|
+
|
|
150
|
+
<step_suggest>
|
|
151
|
+
<description>Show kata suggestions based on filters</description>
|
|
152
|
+
<logic>
|
|
153
|
+
- Filter kata_categories by $DIFFICULTY (if set)
|
|
154
|
+
- Filter by $TYPE (if set)
|
|
155
|
+
- If no filters, pick 3 varied suggestions
|
|
156
|
+
- Select 3 katas that match criteria
|
|
157
|
+
- For each kata, fetch a preview or use the descriptions below
|
|
158
|
+
</logic>
|
|
159
|
+
<kata_descriptions>
|
|
160
|
+
<!-- Beginner -->
|
|
161
|
+
Fizz_Buzz: Print 1-100 replacing multiples of 3/5 with Fizz/Buzz
|
|
162
|
+
Leap_Years: Determine if a year is a leap year (divisibility rules)
|
|
163
|
+
Prime_Factors: Find prime factors of a number
|
|
164
|
+
Word_Wrap: Wrap text to fit within a column width
|
|
165
|
+
Closest_To_Zero: Find the number closest to zero from a list
|
|
166
|
+
Remove_Duplicates: Remove duplicate elements from a list
|
|
167
|
+
Array_Shuffle: Randomly shuffle array elements
|
|
168
|
+
Friday_13th: Count Friday the 13ths in a given year
|
|
169
|
+
Five_Weekends: Find months with 5 Fridays, Saturdays, and Sundays
|
|
170
|
+
Number_Names: Convert numbers to English words (one, two, three...)
|
|
171
|
+
Print_Diamond: Print a diamond shape of letters
|
|
172
|
+
LCD_Digits: Display numbers as LCD-style digits
|
|
173
|
+
Fisher_Yates_Shuffle: Implement the Fisher-Yates shuffle algorithm
|
|
174
|
+
|
|
175
|
+
<!-- Intermediate -->
|
|
176
|
+
Roman_Numerals: Convert Arabic numbers to Roman numerals
|
|
177
|
+
Reverse_Roman: Convert Roman numerals back to Arabic numbers
|
|
178
|
+
Bowling_Game: Score a 10-pin bowling game with spares/strikes
|
|
179
|
+
Tennis: Track tennis game score with deuce/advantage
|
|
180
|
+
Anagrams: Find all anagrams of a word from a dictionary
|
|
181
|
+
ISBN: Validate ISBN-10 check digits
|
|
182
|
+
Balanced_Parentheses: Check if brackets are properly balanced
|
|
183
|
+
Calc_Stats: Calculate min/max/count/average from numbers
|
|
184
|
+
Recently_Used_List: Implement a most-recently-used list
|
|
185
|
+
Phone_Numbers: Convert phone numbers to words using keypad letters
|
|
186
|
+
Combined_Number: Arrange numbers to form the largest combined number
|
|
187
|
+
Group_Neighbours: Group adjacent equal elements in a list
|
|
188
|
+
Longest_Common_Prefix: Find longest common prefix among strings
|
|
189
|
+
Yatzy: Score a Yatzy dice game (full version)
|
|
190
|
+
Yatzy_Cutdown: Simplified Yatzy scoring
|
|
191
|
+
Harry_Potter: Calculate discounts for Harry Potter book sets
|
|
192
|
+
Vending_Machine: Calculate change for vending machine purchases
|
|
193
|
+
Count_Coins: Count ways to make change with given coins
|
|
194
|
+
100_doors: Toggle 100 doors puzzle (open/close pattern)
|
|
195
|
+
Haiku_Review: Validate haiku syllable structure (5-7-5)
|
|
196
|
+
ABC_Problem: Spell words using lettered blocks
|
|
197
|
+
Align_Columns: Align text into formatted columns
|
|
198
|
+
Best_Shuffle: Shuffle string so no character stays in place
|
|
199
|
+
Filename_Range: Generate filename sequences (file001, file002...)
|
|
200
|
+
Unsplice: Reverse a string splice operation
|
|
201
|
+
12_Days_of_Xmas: Generate "12 Days of Christmas" lyrics
|
|
202
|
+
|
|
203
|
+
<!-- Advanced -->
|
|
204
|
+
Game_of_Life: Conway's cellular automaton simulation
|
|
205
|
+
Mars_Rover: Navigate a rover on a grid with commands (L/R/M)
|
|
206
|
+
Mine_Sweeper: Generate numbers for a minesweeper grid
|
|
207
|
+
Mine_Field: Place mines randomly on a grid
|
|
208
|
+
Eight_Queens: Place 8 queens on a chessboard without conflicts
|
|
209
|
+
Knights_Tour: Find a path visiting all squares on a chessboard
|
|
210
|
+
Reversi: Implement Reversi/Othello game logic
|
|
211
|
+
Poker_Hands: Compare and rank poker hands
|
|
212
|
+
Levenshtein_Distance: Calculate edit distance between strings
|
|
213
|
+
Magic_Square: Generate magic squares (rows/cols/diags sum equal)
|
|
214
|
+
Saddle_Points: Find saddle points in a matrix
|
|
215
|
+
Tiny_Maze: Solve a small maze pathfinding problem
|
|
216
|
+
Gray_Code: Generate Gray code sequences
|
|
217
|
+
Monty_Hall: Simulate the Monty Hall probability problem
|
|
218
|
+
Number_Chains: Find chains where numbers link by digits
|
|
219
|
+
Wonderland_Number: Find 6-digit number with multiplication property
|
|
220
|
+
Zeckendorf_Number: Represent as sum of non-consecutive Fibonacci numbers
|
|
221
|
+
Diff_Selector: Select differences between data sets
|
|
222
|
+
Diversion: Route around obstacles
|
|
223
|
+
Reordering: Reorder elements based on rules
|
|
224
|
+
Fizz_Buzz_Plus: Extended FizzBuzz with additional rules
|
|
225
|
+
</kata_descriptions>
|
|
226
|
+
<prompt>
|
|
227
|
+
<message>Here are 3 katas that match your criteria:</message>
|
|
228
|
+
<options>
|
|
229
|
+
<option value="kata_1">
|
|
230
|
+
<label>{Kata_Name_1}</label>
|
|
231
|
+
<description>{Description from kata_descriptions}</description>
|
|
232
|
+
</option>
|
|
233
|
+
<option value="kata_2">
|
|
234
|
+
<label>{Kata_Name_2}</label>
|
|
235
|
+
<description>{Description from kata_descriptions}</description>
|
|
236
|
+
</option>
|
|
237
|
+
<option value="kata_3">
|
|
238
|
+
<label>{Kata_Name_3}</label>
|
|
239
|
+
<description>{Description from kata_descriptions}</description>
|
|
240
|
+
</option>
|
|
241
|
+
<option value="more_suggestions">
|
|
242
|
+
<label>Show me 3 different ones</label>
|
|
243
|
+
<description>Same criteria, different suggestions</description>
|
|
244
|
+
</option>
|
|
245
|
+
<option value="more_questions">
|
|
246
|
+
<label>Ask me more questions...</label>
|
|
247
|
+
<description>Refine my preferences further</description>
|
|
248
|
+
</option>
|
|
249
|
+
</options>
|
|
250
|
+
</prompt>
|
|
251
|
+
<if value="more_suggestions">Pick 3 different katas matching same criteria, repeat step_suggest</if>
|
|
252
|
+
<if value="more_questions">
|
|
253
|
+
- If user skipped from step_1: Jump to step_1 (ask difficulty)
|
|
254
|
+
- If user answered step_1 but skipped step_2: Jump to step_2 (ask type)
|
|
255
|
+
- If user answered both: Jump to step_1 to reconsider from start
|
|
256
|
+
</if>
|
|
257
|
+
<set_variable>$SELECTED_KATA = selected kata name</set_variable>
|
|
258
|
+
</step_suggest>
|
|
259
|
+
|
|
260
|
+
<step_fetch>
|
|
261
|
+
<description>Fetch kata content from cyber-dojo</description>
|
|
262
|
+
<action>
|
|
263
|
+
Use WebFetch to get:
|
|
264
|
+
https://raw.githubusercontent.com/cyber-dojo/exercises-start-points/master/start-points/{$SELECTED_KATA}/readme.txt
|
|
265
|
+
</action>
|
|
266
|
+
<store>$KATA_CONTENT = fetched readme content</store>
|
|
267
|
+
</step_fetch>
|
|
268
|
+
|
|
269
|
+
<step_confirm>
|
|
270
|
+
<description>Show full kata details and ask for language</description>
|
|
271
|
+
<display>
|
|
272
|
+
Present the full kata content to the user:
|
|
273
|
+
|
|
274
|
+
## {$SELECTED_KATA}
|
|
275
|
+
|
|
276
|
+
**Difficulty:** {$DIFFICULTY_STARS based on category - ⭐ Beginner, ⭐⭐ Intermediate, ⭐⭐⭐ Advanced}
|
|
277
|
+
|
|
278
|
+
### Problem Description
|
|
279
|
+
{$KATA_CONTENT from readme.txt}
|
|
280
|
+
</display>
|
|
281
|
+
<prompt>
|
|
282
|
+
<message>What language will you use for this kata?</message>
|
|
283
|
+
<options>
|
|
284
|
+
<option value="typescript">
|
|
285
|
+
<label>TypeScript + Vitest</label>
|
|
286
|
+
<description>Modern test runner with great DX</description>
|
|
287
|
+
</option>
|
|
288
|
+
<option value="javascript">
|
|
289
|
+
<label>JavaScript + Vitest</label>
|
|
290
|
+
<description>Same great runner, no types</description>
|
|
291
|
+
</option>
|
|
292
|
+
<option value="python">
|
|
293
|
+
<label>Python + pytest</label>
|
|
294
|
+
<description>Simple and powerful testing</description>
|
|
295
|
+
</option>
|
|
296
|
+
<option value="back">
|
|
297
|
+
<label>Show me other katas</label>
|
|
298
|
+
<description>Go back to suggestions</description>
|
|
299
|
+
</option>
|
|
300
|
+
</options>
|
|
301
|
+
</prompt>
|
|
302
|
+
<note>User can also select "Other" to type a custom language/framework</note>
|
|
303
|
+
<if value="back">Jump back to step_suggest</if>
|
|
304
|
+
<set_variable>$LANGUAGE = selected value (or custom input)</set_variable>
|
|
305
|
+
</step_confirm>
|
|
306
|
+
|
|
307
|
+
<step_generate>
|
|
308
|
+
<description>Generate kata files based on language</description>
|
|
309
|
+
<action>Create the following files based on $LANGUAGE:</action>
|
|
310
|
+
|
|
311
|
+
<file name="CHALLENGE.md">
|
|
312
|
+
# Kata: {$SELECTED_KATA}
|
|
313
|
+
|
|
314
|
+
## Difficulty
|
|
315
|
+
|
|
316
|
+
{$DIFFICULTY_STARS based on category}
|
|
317
|
+
|
|
318
|
+
## Problem
|
|
319
|
+
|
|
320
|
+
{$KATA_CONTENT from readme.txt}
|
|
321
|
+
|
|
322
|
+
## TDD Approach
|
|
323
|
+
|
|
324
|
+
Work through this kata using the red-green-refactor cycle:
|
|
325
|
+
|
|
326
|
+
1. **Red**: Write a failing test for the simplest case
|
|
327
|
+
2. **Green**: Write minimal code to pass
|
|
328
|
+
3. **Refactor**: Clean up while keeping tests green
|
|
329
|
+
4. **Repeat**: Add the next test case
|
|
330
|
+
|
|
331
|
+
## Source
|
|
332
|
+
|
|
333
|
+
[cyber-dojo: {$SELECTED_KATA}](https://cyber-dojo.org)
|
|
334
|
+
</file>
|
|
335
|
+
|
|
336
|
+
<file name="kata.ts" condition="$LANGUAGE == typescript">
|
|
337
|
+
/**
|
|
338
|
+
* {$SELECTED_KATA}
|
|
339
|
+
* See CHALLENGE.md for requirements
|
|
340
|
+
*/
|
|
341
|
+
export function solve(input: unknown): unknown {
|
|
342
|
+
throw new Error("Not implemented - start with a failing test!");
|
|
343
|
+
}
|
|
344
|
+
</file>
|
|
345
|
+
|
|
346
|
+
<file name="kata.test.ts" condition="$LANGUAGE == typescript">
|
|
347
|
+
import { describe, it, expect } from "vitest";
|
|
348
|
+
import { solve } from "./kata";
|
|
349
|
+
|
|
350
|
+
describe("{$SELECTED_KATA}", () => {
|
|
351
|
+
it.todo("should handle the simplest case");
|
|
352
|
+
|
|
353
|
+
// Add your first real test here using the red-green-refactor cycle
|
|
354
|
+
});
|
|
355
|
+
</file>
|
|
356
|
+
|
|
357
|
+
<file name="kata.js" condition="$LANGUAGE == javascript">
|
|
358
|
+
/**
|
|
359
|
+
* {$SELECTED_KATA}
|
|
360
|
+
* See CHALLENGE.md for requirements
|
|
361
|
+
*/
|
|
362
|
+
export function solve(input) {
|
|
363
|
+
throw new Error("Not implemented - start with a failing test!");
|
|
364
|
+
}
|
|
365
|
+
</file>
|
|
366
|
+
|
|
367
|
+
<file name="kata.test.js" condition="$LANGUAGE == javascript">
|
|
368
|
+
import { describe, it, expect } from "vitest";
|
|
369
|
+
import { solve } from "./kata.js";
|
|
370
|
+
|
|
371
|
+
describe("{$SELECTED_KATA}", () => {
|
|
372
|
+
it.todo("should handle the simplest case");
|
|
373
|
+
|
|
374
|
+
// Add your first real test here using the red-green-refactor cycle
|
|
375
|
+
});
|
|
376
|
+
</file>
|
|
377
|
+
|
|
378
|
+
<file name="kata.py" condition="$LANGUAGE == python">
|
|
379
|
+
"""
|
|
380
|
+
{$SELECTED_KATA}
|
|
381
|
+
See CHALLENGE.md for requirements
|
|
382
|
+
"""
|
|
383
|
+
|
|
384
|
+
def solve(input):
|
|
385
|
+
raise NotImplementedError("Start with a failing test!")
|
|
386
|
+
</file>
|
|
387
|
+
|
|
388
|
+
<file name="test_kata.py" condition="$LANGUAGE == python">
|
|
389
|
+
import pytest
|
|
390
|
+
from kata import solve
|
|
391
|
+
|
|
392
|
+
class TestKata:
|
|
393
|
+
def test_placeholder(self):
|
|
394
|
+
"""Remove this and add your first real test"""
|
|
395
|
+
pytest.skip("Start with a failing test!")
|
|
396
|
+
|
|
397
|
+
# Add your first real test here using the red-green-refactor cycle
|
|
398
|
+
</file>
|
|
399
|
+
|
|
400
|
+
<custom_language condition="$LANGUAGE is custom input (user typed via 'Other')">
|
|
401
|
+
Generate appropriate boilerplate based on user's specified language:
|
|
402
|
+
- CHALLENGE.md (always)
|
|
403
|
+
- Implementation file with idiomatic naming and empty function
|
|
404
|
+
- Test file using common test framework for that language
|
|
405
|
+
|
|
406
|
+
Examples:
|
|
407
|
+
- "Go" → kata.go + kata_test.go (testing package)
|
|
408
|
+
- "Rust" → src/lib.rs + tests/kata_test.rs (cargo test)
|
|
409
|
+
- "Java" → Kata.java + KataTest.java (JUnit)
|
|
410
|
+
- "C#" → Kata.cs + KataTests.cs (xUnit/NUnit)
|
|
411
|
+
- "Ruby" → kata.rb + kata_spec.rb (RSpec)
|
|
412
|
+
- "Elixir" → kata.ex + kata_test.exs (ExUnit)
|
|
413
|
+
- "Haskell" → Kata.hs + KataSpec.hs (Hspec)
|
|
414
|
+
- "Clojure" → kata.clj + kata_test.clj (clojure.test)
|
|
415
|
+
|
|
416
|
+
Use your knowledge of the language's conventions and popular test frameworks.
|
|
417
|
+
Follow the same pattern: empty function that throws/raises "not implemented".
|
|
418
|
+
</custom_language>
|
|
419
|
+
|
|
420
|
+
<message>
|
|
421
|
+
Kata setup complete!
|
|
422
|
+
|
|
423
|
+
Created files:
|
|
424
|
+
- CHALLENGE.md (problem description)
|
|
425
|
+
{if $LANGUAGE != other}
|
|
426
|
+
- Implementation file with empty solve() function
|
|
427
|
+
- Test file with placeholder test
|
|
428
|
+
{endif}
|
|
429
|
+
|
|
430
|
+
Start practicing with `/red` to write your first failing test!
|
|
431
|
+
</message>
|
|
432
|
+
</step_generate>
|
|
433
|
+
|
|
434
|
+
</execution_steps>
|
|
435
|
+
|
|
436
|
+
## Notes
|
|
437
|
+
|
|
438
|
+
- Kata content is fetched at runtime from cyber-dojo's GitHub repository
|
|
439
|
+
- The cyber-dojo project has been maintained for 10+ years with stable URLs
|
|
440
|
+
- All exercises are designed for TDD practice
|
|
441
|
+
- User can always go back to refine their preferences
|
|
442
|
+
- Boilerplate uses `solve()` as the main function - rename as needed for clarity
|
|
@@ -210,8 +210,9 @@ Uncommitted changes: `git status --short`
|
|
|
210
210
|
<description>Create the worktree</description>
|
|
211
211
|
<option_a_new_branch>
|
|
212
212
|
<condition>Remote branch does NOT exist</condition>
|
|
213
|
-
<command>git worktree add ${parent_path}/${branch_name} -b ${branch_name} ${base_branch}</command>
|
|
214
|
-
<example>git worktree add ../fix/issue-123
|
|
213
|
+
<command>git worktree add ${parent_path}/${branch_name} -b ${branch_name} --no-track ${base_branch}</command>
|
|
214
|
+
<example>git worktree add ../fix/issue-123 -b fix/issue-123 --no-track origin/main</example>
|
|
215
|
+
<note>--no-track prevents git from setting upstream to base_branch (which would make git push target main!)</note>
|
|
215
216
|
</option_a_new_branch>
|
|
216
217
|
<option_b_existing_branch>
|
|
217
218
|
<condition>Remote branch EXISTS</condition>
|