The Standalone platform lets you use CraftCommand in any Java application that has no Minecraft dependency. This is ideal for CLI tools, Discord bots, test harnesses, or any other program that needs a structured command dispatch system. Because the platform is Minecraft-agnostic, the sender type is plainDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ProjectUnified/CraftCommand/llms.txt
Use this file to discover all available pages before exploring further.
Object — any value can be passed as the caller, including a String, a custom user object, or a mock in tests.
The Standalone platform uses
Object as the sender type. You can pass any value — a String like "Console", a custom user object, or even null — as the sender when calling execute or tabComplete. This makes it easy to embed CraftCommand in any kind of host application.Maven Setup
Add the runtime and annotations dependencies
The
craftcommand-annotations artifact provides @Command, @Subcommand, @Default, @Optional, @Suggest, and the other compile-time annotations. The craftcommand-standalone-runtime artifact provides StandaloneCommandManager and StandaloneCommand, and must be included in your final JAR.Writing a Command
Annotate your command class with@Command and define sub-operations with @Subcommand. Use @Default to handle the bare command invocation (no sub-label). The sender is always Object on the Standalone platform.
The example below is the real CalculatorCommand from the CraftCommand standalone example module:
@Default
Handles bare invocation —
calc 5 3 — when no sub-label is provided.@Subcommand
Routes
calc add 5 3 to the add method. Supports aliases and nesting via inner classes.@Optional
Makes a parameter optional with a default value:
@Optional("Result:").@Suggest
Sources tab-completion suggestions from a public field or method on the same class.
Registering and Executing
The realCLIApp from the example module shows the full lifecycle — creating the manager, registering a dynamic provider, registering the command class, dispatching execution, and requesting tab-completion suggestions:
StandaloneCommandManager API
StandaloneCommandManager extends CommandManager<Object> and manages the full lifecycle of command registration and lookup.
register(Object commandInstance)
Scans for a generated
ClassName_Standalone wrapper class (produced by the annotation processor at compile time) and registers it along with all its aliases. Throws IllegalArgumentException if no wrapper is found.registerCommand(StandaloneCommand command)
Registers a pre-built
StandaloneCommand wrapper directly — useful when you construct the wrapper yourself or in tests.getCommand(String label)
Looks up a registered command by its primary name or any alias. The lookup is case-insensitive. Returns
null if no match is found.getCommands()
Returns the full
Map<String, StandaloneCommand> of every registered label (including aliases) to its command wrapper.StandaloneCommand Interface
StandaloneCommand is the interface that every generated ClassName_Standalone wrapper implements. You can also implement it directly to integrate hand-written commands into the same manager.
| Method | Return type | Description |
|---|---|---|
getName() | String | The primary command name declared in @Command(value = …). |
getAliases() | List<String> | The list of aliases declared in @Command(aliases = …). |
getDescription() | String | The description string declared in @Command(description = …). |
execute(Object sender, String[] args) | boolean | Dispatches the command. Returns true on success. The first element of args is interpreted as the sub-label (or the first argument for @Default). |
tabComplete(Object sender, String[] args) | List<String> | Returns completion suggestions based on the current argument tokens. Uses @Suggest field/method sources and enum constants automatically. |
Error Handling
By default,StandaloneCommandManager rethrows any exception thrown during command execution as a RuntimeException:
ErrorHandler<Object> to the constructor to change this behaviour — for example, logging to stderr and continuing instead of crashing:
ErrorHandler receives the sender object that was passed to execute or tabComplete, so you can tailor the error message to whatever your application uses as a “user” representation.