@wbern/claude-instructions 1.12.0 → 1.13.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.
Files changed (2) hide show
  1. package/bin/cli.js +53 -24
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -119,7 +119,6 @@ init_esm_shims();
119
119
  import {
120
120
  select,
121
121
  text,
122
- multiselect,
123
122
  groupMultiselect,
124
123
  isCancel,
125
124
  intro,
@@ -469,16 +468,39 @@ async function checkExistingFiles(outputPath, variant, scope, options) {
469
468
  if (!destinationPath) {
470
469
  return [];
471
470
  }
472
- const files = await fs.readdir(sourcePath);
471
+ const allFiles = await fs.readdir(sourcePath);
472
+ const files = options?.commands ? allFiles.filter((f) => options.commands.includes(f)) : allFiles;
473
473
  const existingFiles = [];
474
474
  const prefix = options?.commandPrefix || "";
475
+ let metadata = null;
476
+ let allowedToolsSet = null;
477
+ if (options?.allowedTools && options.allowedTools.length > 0) {
478
+ metadata = await loadCommandsMetadata(variant || VARIANTS.WITH_BEADS);
479
+ allowedToolsSet = new Set(options.allowedTools);
480
+ }
475
481
  for (const file of files) {
476
482
  const destFileName = prefix + file;
477
483
  const destFilePath = path2.join(destinationPath, destFileName);
478
484
  const sourceFilePath = path2.join(sourcePath, file);
479
485
  if (await fs.pathExists(destFilePath)) {
480
486
  const existingContent = await fs.readFile(destFilePath, "utf-8");
481
- const newContent = await fs.readFile(sourceFilePath, "utf-8");
487
+ let newContent = await fs.readFile(sourceFilePath, "utf-8");
488
+ if (metadata && allowedToolsSet) {
489
+ const commandMetadata = metadata[file];
490
+ const requestedTools = commandMetadata?.["_requested-tools"] || [];
491
+ const toolsForCommand = requestedTools.filter(
492
+ (tool) => allowedToolsSet.has(tool)
493
+ );
494
+ if (toolsForCommand.length > 0) {
495
+ const allowedToolsYaml = `allowed-tools: ${toolsForCommand.join(", ")}`;
496
+ newContent = newContent.replace(
497
+ /^---\n/,
498
+ `---
499
+ ${allowedToolsYaml}
500
+ `
501
+ );
502
+ }
503
+ }
482
504
  existingFiles.push({
483
505
  filename: destFileName,
484
506
  existingContent,
@@ -618,38 +640,42 @@ async function generateToDirectory(outputPath, variant, scope, options) {
618
640
  const allFiles = await fs.readdir(sourcePath);
619
641
  let files = options?.commands ? allFiles.filter((f) => options.commands.includes(f)) : allFiles;
620
642
  if (options?.skipFiles) {
621
- files = files.filter((f) => !options.skipFiles.includes(f));
643
+ const prefix2 = options?.commandPrefix || "";
644
+ files = files.filter((f) => !options.skipFiles.includes(prefix2 + f));
622
645
  }
623
- if (options?.commands || options?.skipFiles) {
646
+ const prefix = options?.commandPrefix || "";
647
+ if (options?.commands || options?.skipFiles || options?.commandPrefix) {
624
648
  await fs.ensureDir(destinationPath);
625
649
  for (const file of files) {
626
650
  await fs.copy(
627
651
  path2.join(sourcePath, file),
628
- path2.join(destinationPath, file)
652
+ path2.join(destinationPath, prefix + file)
629
653
  );
630
654
  }
631
655
  } else {
632
656
  await fs.copy(sourcePath, destinationPath, {});
633
657
  }
634
658
  if (options?.allowedTools && options.allowedTools.length > 0) {
659
+ const metadata = await loadCommandsMetadata(variant || VARIANTS.WITH_BEADS);
660
+ const allowedToolsSet = new Set(options.allowedTools);
635
661
  for (const file of files) {
636
- const filePath = path2.join(destinationPath, file);
637
- const content = await fs.readFile(filePath, "utf-8");
638
- const allowedToolsYaml = `allowed-tools: ${options.allowedTools.join(", ")}`;
639
- const modifiedContent = content.replace(
640
- /^---\n/,
641
- `---
662
+ const commandMetadata = metadata[file];
663
+ const requestedTools = commandMetadata?.["_requested-tools"] || [];
664
+ const toolsForCommand = requestedTools.filter(
665
+ (tool) => allowedToolsSet.has(tool)
666
+ );
667
+ if (toolsForCommand.length > 0) {
668
+ const filePath = path2.join(destinationPath, prefix + file);
669
+ const content = await fs.readFile(filePath, "utf-8");
670
+ const allowedToolsYaml = `allowed-tools: ${toolsForCommand.join(", ")}`;
671
+ const modifiedContent = content.replace(
672
+ /^---\n/,
673
+ `---
642
674
  ${allowedToolsYaml}
643
675
  `
644
- );
645
- await fs.writeFile(filePath, modifiedContent);
646
- }
647
- }
648
- if (options?.commandPrefix) {
649
- for (const file of files) {
650
- const oldPath = path2.join(destinationPath, file);
651
- const newPath = path2.join(destinationPath, options.commandPrefix + file);
652
- await fs.rename(oldPath, newPath);
676
+ );
677
+ await fs.writeFile(filePath, modifiedContent);
678
+ }
653
679
  }
654
680
  }
655
681
  let templateInjected = false;
@@ -904,9 +930,11 @@ async function main(args) {
904
930
  variant
905
931
  );
906
932
  if (requestedToolsOptions.length > 0) {
907
- selectedAllowedTools = await multiselect({
933
+ selectedAllowedTools = await groupMultiselect({
908
934
  message: "Select allowed tools for commands (optional)",
909
- options: requestedToolsOptions,
935
+ options: {
936
+ "All tools": requestedToolsOptions
937
+ },
910
938
  required: false
911
939
  });
912
940
  if (isCancel(selectedAllowedTools)) {
@@ -916,7 +944,8 @@ async function main(args) {
916
944
  }
917
945
  const existingFiles = cachedExistingFiles ?? await checkExistingFiles(void 0, variant, scope, {
918
946
  commandPrefix,
919
- commands: selectedCommands
947
+ commands: selectedCommands,
948
+ allowedTools: selectedAllowedTools
920
949
  });
921
950
  const skipFiles = [];
922
951
  if (!args?.overwrite && !args?.skipOnConflict) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wbern/claude-instructions",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "TDD workflow commands for Claude Code CLI",
5
5
  "type": "module",
6
6
  "bin": "./bin/cli.js",