Feature: Skill CLI branch coverage round 2 Cover partial branches in src/cleveragents/cli/commands/skill.py Lines 74, 109, 112, 121, 155, 164, 169, and related conditionals. All lines are hit but many conditional branches are only tested in one direction. Background: Given r2skill- a reset skill CLI service # ------------------------------------------------------------------- # _get_skill_service singleton (line 74 false branch) # ------------------------------------------------------------------- Scenario: Service singleton returns existing instance on second call When r2skill- I call _get_skill_service twice without resetting Then r2skill- both calls return the same SkillService object # ------------------------------------------------------------------- # _skill_spec_dict — missing timestamps (lines 109, 112 false) # ------------------------------------------------------------------- Scenario: Show skill with JSON format when timestamps are absent Given r2skill- a registered skill "local/no-timestamps" with tool_refs And r2skill- the timestamps for "local/no-timestamps" are removed When r2skill- I invoke show "local/no-timestamps" with format "json" Then r2skill- the output should be valid JSON And r2skill- the JSON output should not contain key "created" And r2skill- the JSON output should not contain key "updated" # ------------------------------------------------------------------- # _tool_count — MCP with no tools (line 121-122 false branch) # ------------------------------------------------------------------- Scenario: Tool count for skill with MCP server having no tools Given r2skill- a registered skill "local/mcp-no-tools" with MCP server but no tool list When r2skill- I invoke show "local/mcp-no-tools" with format "rich" Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "OK" # ------------------------------------------------------------------- # _print_skill_registered — no includes (line 155 false) # ------------------------------------------------------------------- Scenario: Add skill with no includes shows no Includes panel Given r2skill- a temp YAML config for "local/no-includes" with only tool_refs When r2skill- I invoke add with the temp config in rich format Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "Skill Registered" And r2skill- the output should not contain "Includes" # ------------------------------------------------------------------- # _print_skill_registered — empty sources (line 164 false) # ------------------------------------------------------------------- Scenario: Add skill with no tool sources shows no Tool Sources panel Given r2skill- a temp YAML config for "local/empty-skill" with no tools When r2skill- I invoke add with the temp config in rich format Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "Skill Registered" And r2skill- the output should not contain "Tool Sources" # ------------------------------------------------------------------- # _print_skill_registered — source type branches (lines 169, 173, 177, 181) # ------------------------------------------------------------------- Scenario: Add skill with only MCP sources excludes builtin from sources Given r2skill- a temp YAML config for "local/mcp-only" with MCP and tools When r2skill- I invoke add with the temp config in rich format Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "mcp" Scenario: Add skill with only custom inline tools Given r2skill- a temp YAML config for "local/custom-only" with inline tools When r2skill- I invoke add with the temp config in rich format Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "custom" # ------------------------------------------------------------------- # add command — non-rich format (line 483 true branch) # ------------------------------------------------------------------- Scenario: Add skill with JSON format returns JSON output Given r2skill- a temp YAML config for "local/json-add" with only tool_refs When r2skill- I invoke add with the temp config in format "json" Then r2skill- the CLI exit code should be 0 And r2skill- the output should be valid JSON And r2skill- the JSON output should contain key "name" # ------------------------------------------------------------------- # add command — update existing skill (lines 474, 491) # ------------------------------------------------------------------- Scenario: Update existing skill via add --update shows Changes panel Given r2skill- a temp YAML config for "local/updatable" with only tool_refs And r2skill- the skill "local/updatable" is already registered via add And r2skill- a second temp YAML config for "local/updatable" with different tools When r2skill- I invoke add with the second config and --update in rich format Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "Skill Updated" And r2skill- the output should contain "Changes" # ------------------------------------------------------------------- # add command — duplicate without --update (line 500-510) # ------------------------------------------------------------------- Scenario: Add duplicate skill without update raises already-registered error Given r2skill- a temp YAML config for "local/duplicate" with only tool_refs And r2skill- the skill "local/duplicate" is already registered via add And r2skill- a duplicate temp YAML config for "local/duplicate" When r2skill- I invoke add with the duplicate config without update Then r2skill- the CLI exit code should not be 0 And r2skill- the output should contain "already registered" And r2skill- the output should contain "--update" # ------------------------------------------------------------------- # list — empty registry (line 646 true) # ------------------------------------------------------------------- Scenario: List skills when registry is empty shows message When r2skill- I invoke list in rich format Then r2skill- the output should contain "No skills found" # ------------------------------------------------------------------- # list — non-rich format (line 651 true) # ------------------------------------------------------------------- Scenario: List skills with JSON format Given r2skill- a registered skill "local/for-json-list" with tool_refs When r2skill- I invoke list in format "json" Then r2skill- the CLI exit code should be 0 And r2skill- the output should be valid JSON # ------------------------------------------------------------------- # list — non-local namespace (line 671 else branch) # ------------------------------------------------------------------- Scenario: List skills with non-local namespace counts server skills Given r2skill- a registered skill "server/remote-skill" with tool_refs When r2skill- I invoke list in rich format Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "server/remote-skill" # ------------------------------------------------------------------- # show — non-rich format (line 724 true) # ------------------------------------------------------------------- Scenario: Show skill with JSON format returns structured data Given r2skill- a registered skill "local/for-json-show" with tool_refs When r2skill- I invoke show "local/for-json-show" with format "json" Then r2skill- the CLI exit code should be 0 And r2skill- the output should be valid JSON And r2skill- the JSON output should contain key "name" # ------------------------------------------------------------------- # show — KeyError path (line 731-733) # ------------------------------------------------------------------- Scenario: Show nonexistent skill raises not-found error When r2skill- I invoke show "local/nonexistent" with format "rich" Then r2skill- the CLI exit code should not be 0 And r2skill- the output should contain "Skill not found" # ------------------------------------------------------------------- # remove — rich format output (line 564 false, full rich path) # ------------------------------------------------------------------- Scenario: Remove skill with rich format shows removal panel Given r2skill- a registered skill "local/to-remove" with tool_refs When r2skill- I invoke remove "local/to-remove" with --yes in rich format Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "Skill Removed" And r2skill- the output should contain "OK" # ------------------------------------------------------------------- # remove — non-rich format (line 564 true) # ------------------------------------------------------------------- Scenario: Remove skill with JSON format returns structured output Given r2skill- a registered skill "local/to-remove-json" with tool_refs When r2skill- I invoke remove "local/to-remove-json" with --yes in format "json" Then r2skill- the CLI exit code should be 0 And r2skill- the output should be valid JSON # ------------------------------------------------------------------- # remove — dependent skills (lines 577-587) # ------------------------------------------------------------------- Scenario: Remove skill that is included by another skill shows dependency warning Given r2skill- a registered skill "local/base-dep" with tool_refs And r2skill- a registered skill "local/parent-dep" that includes "local/base-dep" When r2skill- I invoke remove "local/base-dep" with --yes in rich format Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "skill(s) include this skill" # ------------------------------------------------------------------- # remove — KeyError path (line 601-603) # ------------------------------------------------------------------- Scenario: Remove nonexistent skill raises not-found error When r2skill- I invoke remove "local/nonexistent" with --yes in rich format Then r2skill- the CLI exit code should not be 0 And r2skill- the output should contain "Skill not found" # ------------------------------------------------------------------- # tools — non-rich format (line 801 true) # ------------------------------------------------------------------- Scenario: Tools command with JSON format returns structured tool data Given r2skill- a registered skill "local/for-json-tools" with tool_refs When r2skill- I invoke tools "local/for-json-tools" with format "json" Then r2skill- the CLI exit code should be 0 And r2skill- the output should be valid JSON # ------------------------------------------------------------------- # tools — inline entries in non-rich output (lines 806-811) # ------------------------------------------------------------------- Scenario: Tools command with inline tools in JSON format shows custom source Given r2skill- a registered skill "local/inline-tools" with anonymous inline tools When r2skill- I invoke tools "local/inline-tools" with format "json" Then r2skill- the CLI exit code should be 0 And r2skill- the output should be valid JSON And r2skill- the JSON tool list should contain source "custom" # ------------------------------------------------------------------- # tools — KeyError path (line 827-829) # ------------------------------------------------------------------- Scenario: Tools for nonexistent skill raises not-found error When r2skill- I invoke tools "local/nonexistent" with format "rich" Then r2skill- the CLI exit code should not be 0 And r2skill- the output should contain "Skill not found" # ------------------------------------------------------------------- # _print_skill_registered — MCP servers panel (line 189) # ------------------------------------------------------------------- Scenario: Add skill with MCP servers shows MCP Servers panel Given r2skill- a temp YAML config for "local/with-mcp-panel" with MCP servers When r2skill- I invoke add with the temp config in rich format Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "MCP Servers" # ------------------------------------------------------------------- # _print_skill_detail — no direct tools (line 302 false) # ------------------------------------------------------------------- Scenario: Show skill with no direct tools omits direct tools table Given r2skill- a registered skill "local/no-direct-tools" with no tools at all When r2skill- I invoke show "local/no-direct-tools" with format "rich" Then r2skill- the CLI exit code should be 0 And r2skill- the output should not contain "Direct Tools" # ------------------------------------------------------------------- # _print_skill_detail — MCP tools in show (line 287 true/false) # ------------------------------------------------------------------- Scenario: Show skill with MCP servers displays MCP panel Given r2skill- a registered skill "local/show-mcp" with MCP server and explicit tools When r2skill- I invoke show "local/show-mcp" with format "rich" Then r2skill- the CLI exit code should be 0 And r2skill- the output should contain "MCP Servers" # ------------------------------------------------------------------- # tools — MCP entry in non-rich format (line 806 true) # ------------------------------------------------------------------- Scenario: Tools command with MCP entries in JSON format Given r2skill- a registered skill "local/mcp-tools-json" with MCP server and explicit tools When r2skill- I invoke tools "local/mcp-tools-json" with format "json" Then r2skill- the CLI exit code should be 0 And r2skill- the output should be valid JSON And r2skill- the JSON tool list should contain source "mcp"