This is an automated email from the ASF dual-hosted git repository.

luigidemasi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-kit.git

commit fdb3a95c630a038d0394d1ad307cac4a203c5288
Author: Jinal Sarvaiya <[email protected]>
AuthorDate: Tue Oct 20 15:13:02 2026 +0100

    fix #243: address sourcery review
---
 .../camelkit/generator/ClaudeGenerator.java        | 17 ++++++++++
 .../camelkit/generator/SkillResourceInstaller.java |  4 +--
 .../camelkit/service/DoctorService.java            |  2 +-
 .../camelkit/generator/ClaudeGeneratorTest.java    | 37 ++++++++++++++++++----
 .../camelkit/service/DoctorServiceTest.java        | 15 +++++++++
 5 files changed, 66 insertions(+), 9 deletions(-)

diff --git 
a/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/generator/ClaudeGenerator.java
 
b/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/generator/ClaudeGenerator.java
index 4bea2c8f..22cdd921 100644
--- 
a/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/generator/ClaudeGenerator.java
+++ 
b/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/generator/ClaudeGenerator.java
@@ -1,5 +1,6 @@
 package io.github.luigidemasi.camelkit.generator;
 
+import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.HashMap;
@@ -13,14 +14,30 @@ public class ClaudeGenerator extends DefaultGenerator {
 
     private final QuteTemplateEngine templateEngine = new QuteTemplateEngine();
 
+    private static final String LEGACY_COMMAND_DIR = ".claude/commands";
+
     @Override
     public void generate(InitContext ctx) throws Exception {
         super.generate(ctx);
+        removeLegacyCommandStubs(ctx);
         generateClaudeMd(ctx);
         generateSettings(ctx);
         generateSubagents(ctx);
     }
 
+    private void removeLegacyCommandStubs(InitContext ctx) throws IOException {
+        Path legacyDir = ctx.projectDir().resolve(LEGACY_COMMAND_DIR);
+        if (!Files.isDirectory(legacyDir)) {
+            return;
+        }
+        try (var files = Files.list(legacyDir)) {
+            for (Path file : files.filter(f -> 
f.getFileName().toString().startsWith("camel-")
+                    && f.getFileName().toString().endsWith(".md")).toList()) {
+                GeneratedAssetCleaner.deleteRegularFile(ctx, file);
+            }
+        }
+    }
+
     /** Installs the registry-declared project subagents, currently the 
read-only Ship worker. */
     private void generateSubagents(InitContext ctx) throws Exception {
         int subagents = 0;
diff --git 
a/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/generator/SkillResourceInstaller.java
 
b/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/generator/SkillResourceInstaller.java
index 3832a8e1..a17b0b4b 100644
--- 
a/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/generator/SkillResourceInstaller.java
+++ 
b/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/generator/SkillResourceInstaller.java
@@ -158,8 +158,8 @@ class SkillResourceInstaller {
             if 
(AgentGeneratorStrategy.BOB2.descriptorValue().equals(ctx.agentName())
                     || 
AgentGeneratorStrategy.QWEN.descriptorValue().equals(ctx.agentName())
                     || 
AgentGeneratorStrategy.CLAUDE.descriptorValue().equals(ctx.agentName())) {
-                // Bob Shell's native skill picker hides false values; 
same-name command stubs cannot override them.
-                boolean exposeCommand = 
AgentGeneratorStrategy.BOB2.descriptorValue().equals(ctx.agentName())
+                boolean exposeCommand = 
(AgentGeneratorStrategy.BOB2.descriptorValue().equals(ctx.agentName())
+                        || 
AgentGeneratorStrategy.CLAUDE.descriptorValue().equals(ctx.agentName()))
                         && workflow.commands().stream().anyMatch(command -> 
command.userFacing()
                                 && command.skill().equals(skillName));
                 addHyphenatedUserInvocableMetadata(destination, exposeCommand);
diff --git 
a/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/service/DoctorService.java
 
b/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/service/DoctorService.java
index 6c30626c..a76807c0 100644
--- 
a/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/service/DoctorService.java
+++ 
b/camel-kit-core/src/main/java/io/github/luigidemasi/camelkit/service/DoctorService.java
@@ -141,7 +141,7 @@ public class DoctorService {
 
         AgentConfig agent = AgentRegistry.get(agentName);
         String folder = config.getProperty("agent.folder", "").trim();
-        if (agent.folder().equals(folder)) {
+        if (agent.folder().equals(folder) || 
agent.commandDirectory().equals(folder)) {
             findings.add(DoctorFinding.pass("config", 
".camel-kit/config.properties",
                     "Agent configuration selects " + agent.name(),
                     "No action required."));
diff --git 
a/camel-kit-core/src/test/java/io/github/luigidemasi/camelkit/generator/ClaudeGeneratorTest.java
 
b/camel-kit-core/src/test/java/io/github/luigidemasi/camelkit/generator/ClaudeGeneratorTest.java
index 054e4506..7a3a718d 100644
--- 
a/camel-kit-core/src/test/java/io/github/luigidemasi/camelkit/generator/ClaudeGeneratorTest.java
+++ 
b/camel-kit-core/src/test/java/io/github/luigidemasi/camelkit/generator/ClaudeGeneratorTest.java
@@ -135,13 +135,19 @@ class ClaudeGeneratorTest {
         InitContext ctx = createContext();
         new ClaudeGenerator().generate(ctx);
 
-        String start = 
Files.readString(ctx.skillsDir().resolve("camel-start/SKILL.md"));
-        assertTrue(start.contains("user-invocable: true"),
-                "camel-start must have hyphenated user-invocable for Claude 
Code discovery");
+        for (String userFacingSkill : Set.of("camel-start", 
"camel-brainstorm", "camel-migrate",
+                "camel-plan", "camel-execute", "camel-validate", "camel-ship",
+                "camel-knowledge", "camel-debug")) {
+            String skill = 
Files.readString(ctx.skillsDir().resolve(userFacingSkill + "/SKILL.md"));
+            assertTrue(skill.contains("user-invocable: true"),
+                    userFacingSkill + " must have user-invocable: true for 
Claude Code discovery");
+        }
 
-        String brainstorm = 
Files.readString(ctx.skillsDir().resolve("camel-brainstorm/SKILL.md"));
-        assertTrue(brainstorm.contains("user-invocable: false"),
-                "camel-brainstorm must have hyphenated user-invocable: false 
for Claude Code");
+        for (String internalSkill : INTERNAL_SKILLS) {
+            String skill = 
Files.readString(ctx.skillsDir().resolve(internalSkill + "/SKILL.md"));
+            assertTrue(skill.contains("user-invocable: false"),
+                    internalSkill + " must have user-invocable: false for 
Claude Code");
+        }
     }
 
     @Test
@@ -157,4 +163,23 @@ class ClaudeGeneratorTest {
                     skillName + " description must start with 'Use when' for 
Claude Code discovery");
         }
     }
+
+    @Test
+    void removesLegacyCommandStubsOnRegeneration() throws Exception {
+        InitContext ctx = createContext();
+        Path legacyDir = tempDir.resolve(".claude/commands");
+        Files.createDirectories(legacyDir);
+        Files.writeString(legacyDir.resolve("camel-start.md"), "legacy stub");
+        Files.writeString(legacyDir.resolve("camel-migrate.md"), "legacy 
stub");
+        Files.writeString(legacyDir.resolve("user-custom.md"), "user file");
+
+        new ClaudeGenerator().generate(ctx);
+
+        assertFalse(Files.exists(legacyDir.resolve("camel-start.md")),
+                "Legacy camel-start command stub must be removed");
+        assertFalse(Files.exists(legacyDir.resolve("camel-migrate.md")),
+                "Legacy camel-migrate command stub must be removed");
+        assertTrue(Files.exists(legacyDir.resolve("user-custom.md")),
+                "Non-camel user files must be preserved");
+    }
 }
diff --git 
a/camel-kit-core/src/test/java/io/github/luigidemasi/camelkit/service/DoctorServiceTest.java
 
b/camel-kit-core/src/test/java/io/github/luigidemasi/camelkit/service/DoctorServiceTest.java
index 08a1224e..d6964d7a 100644
--- 
a/camel-kit-core/src/test/java/io/github/luigidemasi/camelkit/service/DoctorServiceTest.java
+++ 
b/camel-kit-core/src/test/java/io/github/luigidemasi/camelkit/service/DoctorServiceTest.java
@@ -1732,6 +1732,21 @@ class DoctorServiceTest {
         return hasFinding(result, status, category, null, null);
     }
 
+    @Test
+    void claudeDoctorAcceptsLegacyCommandDirectoryFolder() throws Exception {
+        Path root = tempDir.resolve("legacy-claude");
+        createHealthyWorkspace(root, CLAUDE);
+        Path config = root.resolve(".camel-kit/config.properties");
+        String content = Files.readString(config);
+        Files.writeString(config, content.replace(
+                "agent.folder=" + AgentRegistry.get(CLAUDE).folder(),
+                "agent.folder=.claude/commands"));
+
+        DoctorResult result = new DoctorService().inspect(new 
DoctorRequest(root));
+        assertTrue(hasFinding(result, DoctorFinding.Status.PASS, "config", 
"Agent configuration selects", null),
+                "Doctor must accept legacy .claude/commands folder for 
Claude");
+    }
+
     private boolean hasFinding(
             DoctorResult result,
             DoctorFinding.Status status,

Reply via email to