@wbern/claude-instructions 1.8.0 → 1.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/bin/cli.js CHANGED
@@ -38,19 +38,48 @@ function truncatePathFromLeft(pathStr, maxLength) {
38
38
  return ELLIPSIS + truncated;
39
39
  }
40
40
  var VARIANT_OPTIONS = [
41
- { value: VARIANTS.WITH_BEADS, label: "With Beads", hint: "Includes Beads task tracking" },
42
- { value: VARIANTS.WITHOUT_BEADS, label: "Without Beads", hint: "Standard commands only" }
41
+ {
42
+ value: VARIANTS.WITH_BEADS,
43
+ label: "With Beads",
44
+ hint: "Includes Beads task tracking"
45
+ },
46
+ {
47
+ value: VARIANTS.WITHOUT_BEADS,
48
+ label: "Without Beads",
49
+ hint: "Standard commands only"
50
+ }
43
51
  ];
44
52
  function getScopeOptions(terminalWidth = 80) {
45
- const projectPath = path.join(process.cwd(), DIRECTORIES.CLAUDE, DIRECTORIES.COMMANDS);
46
- const userPath = path.join(os.homedir(), DIRECTORIES.CLAUDE, DIRECTORIES.COMMANDS);
53
+ const projectPath = path.join(
54
+ process.cwd(),
55
+ DIRECTORIES.CLAUDE,
56
+ DIRECTORIES.COMMANDS
57
+ );
58
+ const userPath = path.join(
59
+ os.homedir(),
60
+ DIRECTORIES.CLAUDE,
61
+ DIRECTORIES.COMMANDS
62
+ );
47
63
  return [
48
- { value: SCOPES.PROJECT, label: "Project/Repository", hint: truncatePathFromLeft(projectPath, terminalWidth) },
49
- { value: SCOPES.USER, label: "User (Global)", hint: truncatePathFromLeft(userPath, terminalWidth) }
64
+ {
65
+ value: SCOPES.PROJECT,
66
+ label: "Project/Repository",
67
+ hint: truncatePathFromLeft(projectPath, terminalWidth)
68
+ },
69
+ {
70
+ value: SCOPES.USER,
71
+ label: "User (Global)",
72
+ hint: truncatePathFromLeft(userPath, terminalWidth)
73
+ }
50
74
  ];
51
75
  }
52
76
  async function getCommandsGroupedByCategory(variant) {
53
- const sourcePath = path.join(__dirname, "..", DIRECTORIES.DOWNLOADS, variant || VARIANTS.WITH_BEADS);
77
+ const sourcePath = path.join(
78
+ __dirname,
79
+ "..",
80
+ DIRECTORIES.DOWNLOADS,
81
+ variant || VARIANTS.WITH_BEADS
82
+ );
54
83
  const metadataPath = path.join(sourcePath, "commands-metadata.json");
55
84
  const metadataContent = await fs.readFile(metadataPath, "utf-8");
56
85
  const metadata = JSON.parse(metadataContent);
@@ -87,21 +116,29 @@ function getDestinationPath(outputPath, scope) {
87
116
  return void 0;
88
117
  }
89
118
  function extractTemplateBlocks(content) {
90
- const matchWithCommands = content.match(/<claude-commands-template\s+commands="([^"]+)">([\s\S]*?)<\/claude-commands-template>/);
91
- if (matchWithCommands) {
92
- return {
93
- content: matchWithCommands[2].trim(),
94
- commands: matchWithCommands[1].split(",").map((c) => c.trim())
95
- };
119
+ const blocks = [];
120
+ const withCommandsRegex = /<claude-commands-template\s+commands="([^"]+)">([\s\S]*?)<\/claude-commands-template>/g;
121
+ for (const match of content.matchAll(withCommandsRegex)) {
122
+ blocks.push({
123
+ content: match[2].trim(),
124
+ commands: match[1].split(",").map((c) => c.trim())
125
+ });
96
126
  }
97
- const match = content.match(/<claude-commands-template>([\s\S]*?)<\/claude-commands-template>/);
98
- if (!match) {
99
- return null;
127
+ const withoutCommandsRegex = /<claude-commands-template>([\s\S]*?)<\/claude-commands-template>/g;
128
+ for (const match of content.matchAll(withoutCommandsRegex)) {
129
+ blocks.push({
130
+ content: match[1].trim()
131
+ });
100
132
  }
101
- return { content: match[1].trim() };
133
+ return blocks;
102
134
  }
103
135
  async function generateToDirectory(outputPath, variant, scope, options) {
104
- const sourcePath = path.join(__dirname, "..", DIRECTORIES.DOWNLOADS, variant || VARIANTS.WITH_BEADS);
136
+ const sourcePath = path.join(
137
+ __dirname,
138
+ "..",
139
+ DIRECTORIES.DOWNLOADS,
140
+ variant || VARIANTS.WITH_BEADS
141
+ );
105
142
  const destinationPath = getDestinationPath(outputPath, scope);
106
143
  if (!destinationPath) {
107
144
  throw new Error("Either outputPath or scope must be provided");
@@ -111,7 +148,10 @@ async function generateToDirectory(outputPath, variant, scope, options) {
111
148
  if (options?.commands) {
112
149
  await fs.ensureDir(destinationPath);
113
150
  for (const file of files) {
114
- await fs.copy(path.join(sourcePath, file), path.join(destinationPath, file));
151
+ await fs.copy(
152
+ path.join(sourcePath, file),
153
+ path.join(destinationPath, file)
154
+ );
115
155
  }
116
156
  } else {
117
157
  await fs.copy(sourcePath, destinationPath, {});
@@ -135,17 +175,24 @@ async function generateToDirectory(outputPath, variant, scope, options) {
135
175
  }
136
176
  if (templateSourcePath) {
137
177
  const sourceContent = await fs.readFile(templateSourcePath, "utf-8");
138
- const template = extractTemplateBlocks(sourceContent);
139
- if (template) {
178
+ const templates = extractTemplateBlocks(sourceContent);
179
+ if (templates.length > 0) {
140
180
  for (const file of files) {
141
181
  const commandName = path.basename(file, ".md");
142
- if (template.commands && !template.commands.includes(commandName)) {
143
- continue;
144
- }
145
182
  const actualFileName = options?.commandPrefix ? options.commandPrefix + file : file;
146
183
  const filePath = path.join(destinationPath, actualFileName);
147
- const content = await fs.readFile(filePath, "utf-8");
148
- await fs.writeFile(filePath, content + "\n\n" + template.content);
184
+ let content = await fs.readFile(filePath, "utf-8");
185
+ let modified = false;
186
+ for (const template of templates) {
187
+ if (template.commands && !template.commands.includes(commandName)) {
188
+ continue;
189
+ }
190
+ content = content + "\n\n" + template.content;
191
+ modified = true;
192
+ }
193
+ if (modified) {
194
+ await fs.writeFile(filePath, content);
195
+ }
149
196
  }
150
197
  templateInjected = true;
151
198
  }
@@ -16,10 +16,7 @@ $ARGUMENTS
16
16
  - Write natural, descriptive code without meta-commentary about the development process
17
17
  - The code should speak for itself - TDD is the process, not the product
18
18
 
19
- (If there was no info above, fallback to:
20
-
21
- 1. Context of the conversation, if there's an immediate thing
22
- 2. `bd ready` to see what to work on next and start from there)
19
+ (If there was no info above, fallback to the context of the conversation)
23
20
 
24
21
  ## TDD Fundamentals
25
22
 
@@ -16,10 +16,7 @@ $ARGUMENTS
16
16
  - Write natural, descriptive code without meta-commentary about the development process
17
17
  - The code should speak for itself - TDD is the process, not the product
18
18
 
19
- (If there was no info above, fallback to:
20
-
21
- 1. Context of the conversation, if there's an immediate thing
22
- 2. `bd ready` to see what to work on next and start from there)
19
+ (If there was no info above, fallback to the context of the conversation)
23
20
 
24
21
  ## TDD Fundamentals
25
22
 
@@ -16,10 +16,7 @@ $ARGUMENTS
16
16
  - Write natural, descriptive code without meta-commentary about the development process
17
17
  - The code should speak for itself - TDD is the process, not the product
18
18
 
19
- (If there was no info above, fallback to:
20
-
21
- 1. Context of the conversation, if there's an immediate thing
22
- 2. `bd ready` to see what to work on next and start from there)
19
+ (If there was no info above, fallback to the context of the conversation)
23
20
 
24
21
  ## TDD Fundamentals
25
22
 
@@ -14,10 +14,7 @@ Apply this document (specifically the Refactor phase), to the info given by user
14
14
  - Write natural, descriptive code without meta-commentary about the development process
15
15
  - The code should speak for itself - TDD is the process, not the product
16
16
 
17
- (If there was no info above, fallback to:
18
-
19
- 1. Context of the conversation, if there's an immediate thing
20
- 2. `bd ready` to see what to work on next and start from there)
17
+ (If there was no info above, fallback to the context of the conversation)
21
18
 
22
19
  ## TDD Fundamentals
23
20
 
@@ -16,10 +16,7 @@ $ARGUMENTS
16
16
  - Write natural, descriptive code without meta-commentary about the development process
17
17
  - The code should speak for itself - TDD is the process, not the product
18
18
 
19
- (If there was no info above, fallback to:
20
-
21
- 1. Context of the conversation, if there's an immediate thing
22
- 2. `bd ready` to see what to work on next and start from there)
19
+ (If there was no info above, fallback to the context of the conversation)
23
20
 
24
21
  ## TDD Fundamentals
25
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wbern/claude-instructions",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "description": "TDD workflow commands for Claude Code CLI",
5
5
  "type": "module",
6
6
  "bin": "./bin/cli.js",