src/main/resources/claude/skills/picocli-command/SKILL.md
Generates a Picocli @Command with subcommands, options, converters, and unit tests.
npx skillsauth add edercnj/claude-environment picocli-commandInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generates a complete Picocli CLI command (or subcommand) following the hexagonal architecture pattern. Produces:
@Command class implementing Callable<Integer>@Option and @Parameters declarations with type convertersCommandLine.execute() assertions/picocli-command <CommandName> [--subcommand] — generate a top-level or subcommand/picocli-command <CommandName> --root — generate root command with standard options/picocli-command <CommandName> --crud — generate subcommands for create/list/delete operations| Parameter | Required | Description |
|-----------|----------|-------------|
| CommandName | Yes | PascalCase command class name (e.g., GenerateCommand, ValidateCommand) |
| --subcommand | No | Generate as subcommand (registers with parent via subcommands =) |
| --root | No | Generate as root command with mixinStandardHelpOptions = true |
| --crud | No | Generate create/list/delete subcommands |
Read existing conventions:
knowledge/stack-patterns/picocli/index.md — Picocli patternsknowledge/layer-templates.md — Layer template patternssrc/main/java/**/adapter/inbound/cli/ for naming conventions// src/main/java/{package}/adapter/inbound/cli/{CommandName}.java
@Command(
name = "{command-name}",
description = "{description}",
mixinStandardHelpOptions = true
)
public class {CommandName} implements Callable<Integer> {
@Option(names = {"-c", "--config"}, required = true,
description = "Config file path.")
private Path configFile;
private final {Port} port;
public {CommandName}({Port} port) {
this.port = port;
}
@Override
public Integer call() {
try {
// Delegate to application port
var result = port.execute(...);
System.out.printf("Success: %s%n", result);
return ExitCode.OK;
} catch (DomainException e) {
System.err.println("Error: " + e.getMessage());
return ExitCode.ERROR;
}
}
}
// src/main/java/{package}/adapter/inbound/cli/ExitCode.java
public final class ExitCode {
public static final int OK = 0;
public static final int ERROR = 1;
public static final int USAGE = 2;
private ExitCode() {}
}
// src/test/java/{package}/adapter/inbound/cli/{CommandName}Test.java
class {CommandName}Test {
private final {Port} port = mock({Port}.class);
private final CommandLine cmd = new CommandLine(new {CommandName}(port));
@Test
void call_validInput_returnsZero() {
// Arrange
when(port.execute(any())).thenReturn(expectedResult);
// Act
int exitCode = cmd.execute("--config", "test.yaml");
// Assert
assertThat(exitCode).isEqualTo(ExitCode.OK);
}
@Test
void call_missingRequiredOption_returnsUsageError() {
int exitCode = cmd.execute();
assertThat(exitCode).isEqualTo(ExitCode.USAGE);
}
}
Callable<Integer> (not Runnable)ExitCode constants used (not magic numbers)System.err for errors, System.out for success outputmixinStandardHelpOptions = true on root commandCommandLine.execute() (not direct call())System.exit() inside command logicknowledge/stack-patterns/picocli/index.md — Picocli patternsknowledge/layer-templates.md — Layer template patternsknowledge/architecture-hexagonal.md — Hexagonal architecturetools
Documentation automation v2: stack-aware generation from documentation.targets.
development
Generates or updates CI/CD pipelines per project stack with actionlint validation.
tools
Generates ADRs from architecture-plan mini-ADRs with sequential numbering and index update.
development
Formats source code; first step of the pre-commit chain (format -> lint -> compile).