ADR 2025007: CLI Plugin API Implementation¶
Status¶
Accepted – Implementation in Progress
Context¶
Following the successful modernization of OmegaT’s CLI with PicoCLI (ADR-2024001), the current system still lacks plugin integration capabilities. Historically, this created architectural problems where core CLI functionality depended on plugin modules, requiring “reflection hacks” and tight coupling.
The Aligner module exemplified this limitation: it was a bundled subproject with its own entry points, but the core CLI would have needed reflection to call it, violating separation of concerns.
Current State¶
Modern CLI structure with
org.omegat.clipackage.BaseSubCommandArchitecture: A lightweight bridge has been implemented to allow subcommands to be registered by modules and plugins at runtime.Consolidation: This ADR now consolidates the proposed Plugin API with the implemented
BaseSubCommandarchitecture.Registry:
SubCommandsclass manages the mapping between command names andBaseSubCommandimplementations.CLIParameters: The parser has been extended to support subcommands and raw arguments, allowing for commands likeOmegaT team initorOmegaT align.PicoCLI Status: PicoCLI is the long-term goal for full CLI modernization, but the current implementation uses a manual bridge to provide immediate plugin extensibility.
Decision¶
We will implement a CLI Plugin API that supports two distinct integration patterns: Command Contribution (already partially implemented via BaseSubCommand) and Event Hook Integration (planned), eliminating architectural debt and maintaining proper separation of concerns.
Core Components¶
1. Command Contribution API¶
Plugins and modules contribute CLI functionality by extending BaseSubCommand and registering it with the Core registry.
BaseSubCommand: Abstract base class implementingCallable<Integer>.Registration: Plugins call
Core.registerConsoleCommand(String name, Class<? extends BaseSubCommand> clazz)during initialization.Execution:
Main.javautilizes theSubCommandsregistry to instantiate and execute the command.
2. Command Implementation Pattern¶
Plugin modules provide their own command classes extending the base:
// In Aligner plugin module
public class AlignCommand extends BaseSubCommand {
@Override
public Integer call() throws Exception {
// Direct call to Aligner functionality
// Access parameters via the 'params' field inherited from BaseSubCommand
String alignDir = params.get(CLIParameters.ALIGNDIR);
// ... implementation ...
return 0;
}
}
3. Extend CLIParameters parser to accept subcommand (Phase 2)¶
The CLIParameters parser has been extended to accept subcommands and raw arguments, allowing the Main class to parse the command line arguments and identify the intended execution mode.
Main.main() currently uses a switch statement that dispatches to the appropriate runMode based on the --mode argument or the identified subcommand.
We will eventually replace this with a lookup in the SubCommands registry.
4. Migrate team init feature to use subcommands (Phase 3)¶
The TeamTool class will be refactored to use the new BaseSubCommand architecture.
5. Future PicoCLI Migration (Phase 4)¶
As we transition to PicoCLI (ADR-2024001), the BaseSubCommand architecture will be adapted:
BaseSubCommandimplementations will be decorated with PicoCLI@Commandand@Optionannotations.The registry will be integrated with the PicoCLI
CommandLineinstance for dynamic subcommand discovery.
Implementation Roadmap¶
Phase 1: Modular SubCommands (Completed)¶
Implement
BaseSubCommandandSubCommandsregistry.Add
Core.registerConsoleCommandAPI.Refactor
AlignCommandto use this architecture, removing reflection hacks.
Phase 2: Extend CLIParameters parser to accept subcommand (In Progress)¶
Extend
CLIParametersparser to accept subcommands.Migrate GUI/CLI dispatch from runMode switch to subcommand registry lookup in
Mainclass.
Phase 3: Migrate team init feature to use subcommands (Planned)¶
Migrate
TeamTool.mainto use subcommand architecture.Deprecate
--mode=<runMode>CLI argument and remove in favor of subcommand dispatch.
Phase 4: Full PicoCLI Integration (Planned)¶
Integrate
SubCommandsregistry with PicoCLI.Migrate
Mainargument parsing to PicoCLI.
Consequences¶
Positive¶
Decoupling: Core CLI remains independent of plugin implementations.
Extensibility: Plugins can contribute first-class CLI commands.
Bridge to Future: Provides an immediate solution while maintaining a path to full PicoCLI modernization.
Negative¶
Hybrid State: The coexistence of manual parsing and a subcommand registry adds temporary complexity.