@wbern/claude-instructions 1.2.0 → 1.3.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
@@ -19,85 +19,13 @@ TDD workflow commands for Claude Code CLI.
19
19
 
20
20
  ## Installation
21
21
 
22
- ### Quick Install (Recommended)
23
-
24
22
  ```bash
25
23
  npx @wbern/claude-instructions
26
24
  ```
27
25
 
28
- This interactive installer lets you choose your variant and installation scope.
29
-
30
- ### Manual Installation
31
-
32
- #### Without Beads Integration (Recommended for Beginners)
33
-
34
- Standalone TDD workflow commands without dependencies.
35
-
36
- **User-level (global - available in all projects):**
37
- ```bash
38
- # Clone the repository
39
- git clone https://github.com/wbern/claude-instructions.git /tmp/claude-instructions
40
-
41
- # Copy commands to your user directory
42
- cp /tmp/claude-instructions/downloads/without-beads/*.md ~/.claude/commands/
43
-
44
- # Clean up
45
- rm -rf /tmp/claude-instructions
46
- ```
47
-
48
- **Project-level (current repository only):**
49
- ```bash
50
- # Clone the repository
51
- git clone https://github.com/wbern/claude-instructions.git /tmp/claude-instructions
52
-
53
- # Create commands directory and copy files
54
- mkdir -p .claude/commands
55
- cp /tmp/claude-instructions/downloads/without-beads/*.md .claude/commands/
56
-
57
- # Clean up
58
- rm -rf /tmp/claude-instructions
59
- ```
60
-
61
- #### With Beads Integration
62
-
63
- Supports [Beads MCP](https://github.com/steveyegge/beads) integration for issue tracking and workflow management, installed separately.
64
-
65
- **Choose this if you:**
66
- - Are comfortable with TDD workflows
67
- - Need issue tracking and workflow management
68
- - Work in a team environment
69
- - Want integrated project planning with `/plan`
70
-
71
- **User-level (global - available in all projects):**
72
- ```bash
73
- # Clone the repository
74
- git clone https://github.com/wbern/claude-instructions.git /tmp/claude-instructions
75
-
76
- # Copy commands to your user directory
77
- cp /tmp/claude-instructions/downloads/with-beads/*.md ~/.claude/commands/
78
-
79
- # Clean up
80
- rm -rf /tmp/claude-instructions
81
- ```
82
-
83
- **Project-level (current repository only):**
84
- ```bash
85
- # Clone the repository
86
- git clone https://github.com/wbern/claude-instructions.git /tmp/claude-instructions
87
-
88
- # Create commands directory and copy files
89
- mkdir -p .claude/commands
90
- cp /tmp/claude-instructions/downloads/with-beads/*.md .claude/commands/
91
-
92
- # Clean up
93
- rm -rf /tmp/claude-instructions
94
- ```
95
-
96
- **Requirements:**
97
- - Install [Beads MCP](https://github.com/steveyegge/beads) for full functionality
98
- - Configure Beads in your project with `bd init`
99
-
100
- **Note:** User-level installation makes commands available globally in all your projects. Project-level installation only makes them available in the current repository.
26
+ The interactive installer lets you choose:
27
+ - **Variant**: With or without [Beads MCP](https://github.com/steveyegge/beads) integration
28
+ - **Scope**: User-level (global) or project-level installation
101
29
 
102
30
  After installation, restart Claude Code if it's currently running.
103
31
 
package/bin/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // scripts/cli.ts
4
- import { select, isCancel, intro, outro } from "@clack/prompts";
4
+ import { select, text, groupMultiselect, isCancel, intro, outro } from "@clack/prompts";
5
5
 
6
6
  // scripts/cli-generator.ts
7
7
  import fs from "fs-extra";
@@ -32,6 +32,31 @@ var SCOPE_OPTIONS = [
32
32
  { value: SCOPES.PROJECT, label: "Project/Repository" },
33
33
  { value: SCOPES.USER, label: "User (Global)" }
34
34
  ];
35
+ async function getCommandsGroupedByCategory(variant) {
36
+ const sourcePath = path.join(__dirname, "..", DIRECTORIES.DOWNLOADS, variant || VARIANTS.WITH_BEADS);
37
+ const metadataPath = path.join(sourcePath, "commands-metadata.json");
38
+ const metadataContent = await fs.readFile(metadataPath, "utf-8");
39
+ const metadata = JSON.parse(metadataContent);
40
+ const grouped = {};
41
+ for (const [filename, data] of Object.entries(metadata)) {
42
+ const category = data.category;
43
+ if (!grouped[category]) {
44
+ grouped[category] = [];
45
+ }
46
+ grouped[category].push({
47
+ value: filename,
48
+ label: filename
49
+ });
50
+ }
51
+ for (const category of Object.keys(grouped)) {
52
+ grouped[category].sort((a, b) => {
53
+ const orderA = metadata[a.value].order;
54
+ const orderB = metadata[b.value].order;
55
+ return orderA - orderB;
56
+ });
57
+ }
58
+ return grouped;
59
+ }
35
60
  function getDestinationPath(outputPath, scope) {
36
61
  if (outputPath) {
37
62
  return outputPath;
@@ -64,8 +89,23 @@ async function generateToDirectory(outputPath, variant, scope, options) {
64
89
  if (!destinationPath) {
65
90
  throw new Error("Either outputPath or scope must be provided");
66
91
  }
67
- const files = await fs.readdir(sourcePath);
68
- await fs.copy(sourcePath, destinationPath, {});
92
+ const allFiles = await fs.readdir(sourcePath);
93
+ const files = options?.commands ? allFiles.filter((f) => options.commands.includes(f)) : allFiles;
94
+ if (options?.commands) {
95
+ await fs.ensureDir(destinationPath);
96
+ for (const file of files) {
97
+ await fs.copy(path.join(sourcePath, file), path.join(destinationPath, file));
98
+ }
99
+ } else {
100
+ await fs.copy(sourcePath, destinationPath, {});
101
+ }
102
+ if (options?.commandPrefix) {
103
+ for (const file of files) {
104
+ const oldPath = path.join(destinationPath, file);
105
+ const newPath = path.join(destinationPath, options.commandPrefix + file);
106
+ await fs.rename(oldPath, newPath);
107
+ }
108
+ }
69
109
  let templateInjected = false;
70
110
  if (!options?.skipTemplateInjection) {
71
111
  let templateSourcePath = null;
@@ -85,7 +125,8 @@ async function generateToDirectory(outputPath, variant, scope, options) {
85
125
  if (template.commands && !template.commands.includes(commandName)) {
86
126
  continue;
87
127
  }
88
- const filePath = path.join(destinationPath, file);
128
+ const actualFileName = options?.commandPrefix ? options.commandPrefix + file : file;
129
+ const filePath = path.join(destinationPath, actualFileName);
89
130
  const content = await fs.readFile(filePath, "utf-8");
90
131
  await fs.writeFile(filePath, content + "\n\n" + template.content);
91
132
  }
@@ -119,25 +160,89 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
119
160
 
120
161
  @wbern/claude-instructions
121
162
  `;
122
- async function main() {
163
+ async function main(args) {
123
164
  intro(BATMAN_LOGO);
124
- const variant = await select({
125
- message: "Select variant",
126
- options: [...VARIANT_OPTIONS]
127
- });
128
- if (isCancel(variant)) {
129
- return;
130
- }
131
- const scope = await select({
132
- message: "Select installation scope",
133
- options: [...SCOPE_OPTIONS]
134
- });
135
- if (isCancel(scope)) {
136
- return;
165
+ let variant;
166
+ let scope;
167
+ let commandPrefix;
168
+ let selectedCommands;
169
+ if (args?.variant && args?.scope && args?.prefix !== void 0) {
170
+ variant = args.variant;
171
+ scope = args.scope;
172
+ commandPrefix = args.prefix;
173
+ selectedCommands = args.commands;
174
+ } else {
175
+ variant = await select({
176
+ message: "Select variant",
177
+ options: [...VARIANT_OPTIONS]
178
+ });
179
+ if (isCancel(variant)) {
180
+ return;
181
+ }
182
+ scope = await select({
183
+ message: "Select installation scope",
184
+ options: [...SCOPE_OPTIONS]
185
+ });
186
+ if (isCancel(scope)) {
187
+ return;
188
+ }
189
+ commandPrefix = await text({
190
+ message: "Command prefix (optional)",
191
+ placeholder: "e.g. my-"
192
+ });
193
+ if (isCancel(commandPrefix)) {
194
+ return;
195
+ }
196
+ const groupedCommands = await getCommandsGroupedByCategory(variant);
197
+ const allCommandValues = Object.values(groupedCommands).flat().map((cmd) => cmd.value);
198
+ selectedCommands = await groupMultiselect({
199
+ message: "Select commands to install (Enter to accept all)",
200
+ options: groupedCommands,
201
+ initialValues: allCommandValues
202
+ });
203
+ if (isCancel(selectedCommands)) {
204
+ return;
205
+ }
137
206
  }
138
- const result = await generateToDirectory(void 0, variant, scope);
207
+ const result = await generateToDirectory(void 0, variant, scope, { commandPrefix, skipTemplateInjection: args?.skipTemplateInjection, commands: selectedCommands });
139
208
  outro(`Installed ${result.filesGenerated} commands to .claude/commands`);
140
209
  }
141
210
 
142
211
  // scripts/bin.ts
143
- main().catch(console.error);
212
+ var STRING_ARGS = ["variant", "scope", "prefix"];
213
+ var ARRAY_ARGS = ["commands"];
214
+ var BOOLEAN_FLAGS = [
215
+ { flag: "--skip-template-injection", key: "skipTemplateInjection" }
216
+ ];
217
+ function parseArgs(argv) {
218
+ const args = {};
219
+ for (const arg of argv) {
220
+ for (const { flag, key } of BOOLEAN_FLAGS) {
221
+ if (arg === flag) {
222
+ args[key] = true;
223
+ }
224
+ }
225
+ for (const key of STRING_ARGS) {
226
+ const prefix = `--${key}=`;
227
+ if (arg.startsWith(prefix)) {
228
+ args[key] = arg.slice(prefix.length);
229
+ }
230
+ }
231
+ for (const key of ARRAY_ARGS) {
232
+ const prefix = `--${key}=`;
233
+ if (arg.startsWith(prefix)) {
234
+ args[key] = arg.slice(prefix.length).split(",");
235
+ }
236
+ }
237
+ }
238
+ return args;
239
+ }
240
+ async function run(argv) {
241
+ const args = parseArgs(argv);
242
+ await main(args);
243
+ }
244
+ run(process.argv.slice(2)).catch(console.error);
245
+ export {
246
+ parseArgs,
247
+ run
248
+ };
@@ -0,0 +1,92 @@
1
+ {
2
+ "add-command.md": {
3
+ "description": "Guide for creating new slash commands",
4
+ "category": "Utilities",
5
+ "order": 3
6
+ },
7
+ "ask.md": {
8
+ "description": "Request team review and approval - for complex changes needing discussion (OK fine, traditional PRs still have their place - Cursor)",
9
+ "category": "Workflow",
10
+ "order": 4
11
+ },
12
+ "beepboop.md": {
13
+ "description": "Communicate AI-generated content with transparent attribution",
14
+ "category": "Utilities",
15
+ "order": 2
16
+ },
17
+ "commit.md": {
18
+ "description": "Create a git commit following project standards",
19
+ "category": "Workflow",
20
+ "order": 1
21
+ },
22
+ "cycle.md": {
23
+ "description": "Execute complete TDD cycle - Red, Green, and Refactor phases in sequence",
24
+ "category": "TDD Cycle",
25
+ "order": 5
26
+ },
27
+ "gap.md": {
28
+ "description": "Analyze conversation context for unaddressed items and gaps",
29
+ "category": "Workflow",
30
+ "order": 11
31
+ },
32
+ "green.md": {
33
+ "description": "Execute TDD Green Phase - write minimal implementation to pass the failing test",
34
+ "category": "TDD Cycle",
35
+ "order": 3
36
+ },
37
+ "issue.md": {
38
+ "description": "Analyze GitHub issue and create TDD implementation plan",
39
+ "category": "Planning",
40
+ "order": 1
41
+ },
42
+ "plan.md": {
43
+ "description": "Create implementation plan from feature/requirement with PRD-style discovery and TDD acceptance criteria",
44
+ "category": "Planning",
45
+ "order": 2
46
+ },
47
+ "red.md": {
48
+ "description": "Execute TDD Red Phase - write ONE failing test",
49
+ "category": "TDD Cycle",
50
+ "order": 2
51
+ },
52
+ "refactor.md": {
53
+ "description": "Execute TDD Refactor Phase - improve code structure while keeping tests green",
54
+ "category": "TDD Cycle",
55
+ "order": 4
56
+ },
57
+ "ship.md": {
58
+ "description": "Ship code directly to main - for small, obvious changes that don't need review (Cursor's modern alternative to PRs)",
59
+ "category": "Workflow",
60
+ "order": 2
61
+ },
62
+ "show.md": {
63
+ "description": "Show code to team with auto-merge - for changes that should be visible but don't need approval (Cursor's modern workflow)",
64
+ "category": "Workflow",
65
+ "order": 3
66
+ },
67
+ "spike.md": {
68
+ "description": "Execute TDD Spike Phase - exploratory coding to understand problem space before TDD",
69
+ "category": "TDD Cycle",
70
+ "order": 1
71
+ },
72
+ "summarize.md": {
73
+ "description": "Summarize conversation progress and next steps",
74
+ "category": "Workflow",
75
+ "order": 10
76
+ },
77
+ "tdd.md": {
78
+ "description": "Remind agent about TDD approach and continue conversation",
79
+ "category": "Utilities",
80
+ "order": 1
81
+ },
82
+ "worktree-add.md": {
83
+ "description": "Add a new git worktree from branch name or GitHub issue URL, copy settings, install deps, and open in current IDE",
84
+ "category": "Worktree Management",
85
+ "order": 1
86
+ },
87
+ "worktree-cleanup.md": {
88
+ "description": "Clean up merged worktrees by verifying PR/issue status, consolidating settings, and removing stale worktrees",
89
+ "category": "Worktree Management",
90
+ "order": 2
91
+ }
92
+ }
@@ -0,0 +1,22 @@
1
+ ---
2
+ allowed-tools: mcp__beads__list, mcp__beads__ready
3
+ description: Analyze conversation context for unaddressed items and gaps
4
+ ---
5
+
6
+ Analyze the current conversation context and identify things that have not yet been addressed. Look for:
7
+
8
+ 1. **Incomplete implementations** - Code that was started but not finished
9
+ 2. **Unused variables/results** - Values that were captured but never used
10
+ 3. **Missing tests** - Functionality without test coverage
11
+ 4. **Open issues** - Beads issues that are still open or in progress
12
+ 5. **User requests** - Things the user asked for that weren't fully completed
13
+ 6. **TODO comments** - Any TODOs mentioned in conversation
14
+ 7. **Error handling gaps** - Missing error cases or edge cases
15
+ 8. **Documentation gaps** - Undocumented APIs or features
16
+
17
+ Present findings as a prioritized list with:
18
+ - What the gap is
19
+ - Why it matters
20
+ - Suggested next action
21
+
22
+ If there are no gaps, confirm that everything discussed has been addressed.
@@ -0,0 +1,92 @@
1
+ {
2
+ "add-command.md": {
3
+ "description": "Guide for creating new slash commands",
4
+ "category": "Utilities",
5
+ "order": 3
6
+ },
7
+ "ask.md": {
8
+ "description": "Request team review and approval - for complex changes needing discussion (OK fine, traditional PRs still have their place - Cursor)",
9
+ "category": "Workflow",
10
+ "order": 4
11
+ },
12
+ "beepboop.md": {
13
+ "description": "Communicate AI-generated content with transparent attribution",
14
+ "category": "Utilities",
15
+ "order": 2
16
+ },
17
+ "commit.md": {
18
+ "description": "Create a git commit following project standards",
19
+ "category": "Workflow",
20
+ "order": 1
21
+ },
22
+ "cycle.md": {
23
+ "description": "Execute complete TDD cycle - Red, Green, and Refactor phases in sequence",
24
+ "category": "TDD Cycle",
25
+ "order": 5
26
+ },
27
+ "gap.md": {
28
+ "description": "Analyze conversation context for unaddressed items and gaps",
29
+ "category": "Workflow",
30
+ "order": 11
31
+ },
32
+ "green.md": {
33
+ "description": "Execute TDD Green Phase - write minimal implementation to pass the failing test",
34
+ "category": "TDD Cycle",
35
+ "order": 3
36
+ },
37
+ "issue.md": {
38
+ "description": "Analyze GitHub issue and create TDD implementation plan",
39
+ "category": "Planning",
40
+ "order": 1
41
+ },
42
+ "plan.md": {
43
+ "description": "Create implementation plan from feature/requirement with PRD-style discovery and TDD acceptance criteria",
44
+ "category": "Planning",
45
+ "order": 2
46
+ },
47
+ "red.md": {
48
+ "description": "Execute TDD Red Phase - write ONE failing test",
49
+ "category": "TDD Cycle",
50
+ "order": 2
51
+ },
52
+ "refactor.md": {
53
+ "description": "Execute TDD Refactor Phase - improve code structure while keeping tests green",
54
+ "category": "TDD Cycle",
55
+ "order": 4
56
+ },
57
+ "ship.md": {
58
+ "description": "Ship code directly to main - for small, obvious changes that don't need review (Cursor's modern alternative to PRs)",
59
+ "category": "Workflow",
60
+ "order": 2
61
+ },
62
+ "show.md": {
63
+ "description": "Show code to team with auto-merge - for changes that should be visible but don't need approval (Cursor's modern workflow)",
64
+ "category": "Workflow",
65
+ "order": 3
66
+ },
67
+ "spike.md": {
68
+ "description": "Execute TDD Spike Phase - exploratory coding to understand problem space before TDD",
69
+ "category": "TDD Cycle",
70
+ "order": 1
71
+ },
72
+ "summarize.md": {
73
+ "description": "Summarize conversation progress and next steps",
74
+ "category": "Workflow",
75
+ "order": 10
76
+ },
77
+ "tdd.md": {
78
+ "description": "Remind agent about TDD approach and continue conversation",
79
+ "category": "Utilities",
80
+ "order": 1
81
+ },
82
+ "worktree-add.md": {
83
+ "description": "Add a new git worktree from branch name or GitHub issue URL, copy settings, install deps, and open in current IDE",
84
+ "category": "Worktree Management",
85
+ "order": 1
86
+ },
87
+ "worktree-cleanup.md": {
88
+ "description": "Clean up merged worktrees by verifying PR/issue status, consolidating settings, and removing stale worktrees",
89
+ "category": "Worktree Management",
90
+ "order": 2
91
+ }
92
+ }
@@ -0,0 +1,21 @@
1
+ ---
2
+ allowed-tools: mcp__beads__list, mcp__beads__ready
3
+ description: Analyze conversation context for unaddressed items and gaps
4
+ ---
5
+
6
+ Analyze the current conversation context and identify things that have not yet been addressed. Look for:
7
+
8
+ 1. **Incomplete implementations** - Code that was started but not finished
9
+ 2. **Unused variables/results** - Values that were captured but never used
10
+ 3. **Missing tests** - Functionality without test coverage
11
+ 5. **User requests** - Things the user asked for that weren't fully completed
12
+ 6. **TODO comments** - Any TODOs mentioned in conversation
13
+ 7. **Error handling gaps** - Missing error cases or edge cases
14
+ 8. **Documentation gaps** - Undocumented APIs or features
15
+
16
+ Present findings as a prioritized list with:
17
+ - What the gap is
18
+ - Why it matters
19
+ - Suggested next action
20
+
21
+ If there are no gaps, confirm that everything discussed has been addressed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wbern/claude-instructions",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "TDD workflow commands for Claude Code CLI",
5
5
  "type": "module",
6
6
  "bin": "./bin/cli.js",
@@ -32,6 +32,7 @@
32
32
  "build": "bash scripts/build.sh",
33
33
  "build:dev": "bash scripts/build-dev.sh",
34
34
  "build:cli": "tsup",
35
+ "test:manual": "pnpm build:cli && TMPDIR=$(mktemp -d) && pnpm pack --pack-destination $TMPDIR && cd $TMPDIR && tar -xzf *.tgz && cd package && pnpm i && node bin/cli.js",
35
36
  "generate": "tsx scripts/cli-generator.ts",
36
37
  "test": "vitest run",
37
38
  "test:watch": "vitest",