diff --git a/src/specify_cli/agents.py b/src/specify_cli/agents.py index 4f6714ed8..bb25b3fc1 100644 --- a/src/specify_cli/agents.py +++ b/src/specify_cli/agents.py @@ -275,7 +275,9 @@ class CommandRegistrar: }, } if agent_name == "claude": - # Claude skills should only run when explicitly invoked. + # Claude skills should be user-invocable (accessible via /command) + # and only run when explicitly invoked (not auto-triggered by the model). + skill_frontmatter["user-invocable"] = True skill_frontmatter["disable-model-invocation"] = True return skill_frontmatter diff --git a/tests/integrations/test_integration_claude.py b/tests/integrations/test_integration_claude.py index fe50eecc7..7fd69df17 100644 --- a/tests/integrations/test_integration_claude.py +++ b/tests/integrations/test_integration_claude.py @@ -58,6 +58,7 @@ class TestClaudeIntegration: parts = content.split("---", 2) parsed = yaml.safe_load(parts[1]) assert parsed["name"] == "speckit-plan" + assert parsed["user-invocable"] is True assert parsed["disable-model-invocation"] is True assert parsed["metadata"]["source"] == "templates/commands/plan.md" @@ -176,7 +177,9 @@ class TestClaudeIntegration: skill_file = project / ".claude" / "skills" / "speckit-plan" / "SKILL.md" assert skill_file.exists() - assert "disable-model-invocation: true" in skill_file.read_text(encoding="utf-8") + skill_content = skill_file.read_text(encoding="utf-8") + assert "user-invocable: true" in skill_content + assert "disable-model-invocation: true" in skill_content init_options = json.loads( (project / ".specify" / "init-options.json").read_text(encoding="utf-8") @@ -276,6 +279,7 @@ class TestClaudeIntegration: content = skill_file.read_text(encoding="utf-8") assert "preset:claude-skill-command" in content assert "name: speckit-research" in content + assert "user-invocable: true" in content assert "disable-model-invocation: true" in content metadata = manager.registry.get("claude-skill-command")