ADR-002: CLI Plugin Architecture

Status: Partially Implemented Date: 2024-11-29 (Updated: 2025-12-16) Context: Extend CLI with pluggable features for AI agents, generators, and integrations

Implementation Status (v1.1.0+)

Component Status Evidence
PluginCommand ✅ Implemented commands/PluginCommand.java
Plugin SPI ✅ Implemented plugin/spi/ package
AI Service Abstraction ⚠️ Planned Future work
Complete Plugin Loader ⚠️ In Progress Partial implementation

Current Capabilities:

Remaining Work:

Context

The iDempiere CLI has two distinct use cases:

  1. Core Development - System tenant functionality for iDempiere plugin development
  2. Custom Tools - Specialized generators, AI integrations, and external tool connections

A plugin architecture would allow:

Decision

Implement a plugin system with the following architecture:


Architecture Overview

┌─────────────────────────────────────────────────────────────────┐
│                       idempiere-cli                             │
├─────────────────────────────────────────────────────────────────┤
│  CORE                          │  PLUGIN API                    │
│  ──────────────────────        │  ──────────────────────        │
│  Commands:                     │  Extension Points:              │
│  • doctor                      │  • CommandProvider              │
│  • init                        │  • GeneratorProvider            │
│  • config                      │  • AnalyzerProvider             │
│  • add (column/table/ext)      │  • IntegrationProvider          │
│  • export                      │                                 │
│                                │  Services:                      │
│  Services:                     │  • AIService (Claude, OpenAI)   │
│  • TemplateService             │  • MCPService                   │
│  • IdempiereClient             │  • ExternalAPIService           │
│  • PluginGenerator             │                                 │
└─────────────────────────────────────────────────────────────────┘
                                 │
                    ┌────────────┴────────────┐
                    │      Plugin Loader      │
                    └────────────┬────────────┘
                                 │
        ┌────────────────────────┼────────────────────────┐
        │                        │                        │
   ┌────┴────┐              ┌────┴────┐              ┌────┴────┐
   │ ai-gen  │              │ integr  │              │ custom  │
   │ plugin  │              │ plugin  │              │ plugin  │
   └─────────┘              └─────────┘              └─────────┘

Plugin Types

1. Generator Plugins

Create Application Dictionary elements using AI or templates.

public interface GeneratorProvider {
    String getName();
    String getDescription();

    // Generate AD elements based on natural language or config
    GenerationResult generate(GenerationRequest request);
}

Examples:

2. Integration Plugins

Connect CLI to external systems.

public interface IntegrationProvider {
    String getName();
    void initialize(IntegrationConfig config);

    // Sync data between iDempiere and external system
    SyncResult sync(SyncRequest request);

    // Notify external system of events
    void notify(NotificationEvent event);
}

Examples:

3. Analyzer Plugins

AI-powered analysis and recommendations.

public interface AnalyzerProvider {
    String getName();

    // Analyze code/config and provide recommendations
    AnalysisResult analyze(AnalysisRequest request);
}

Examples:

4. Command Plugins

Add new CLI commands.

public interface CommandProvider {
    // Return Picocli command classes to register
    List<Class<?>> getCommands();
}

Examples:


Plugin Discovery

~/.idempiere-cli/
├── config.yaml           # Global configuration
├── plugins/              # Plugin JARs
│   ├── ai-generator-1.0.0.jar
│   ├── slack-integration-1.0.0.jar
│   └── custom-analyzer-1.0.0.jar
└── cache/                # Plugin cache

Option B: Maven Dependencies

<!-- In project pom.xml or global settings -->
<dependency>
    <groupId>org.idempiere.cli.plugins</groupId>
    <artifactId>ai-generator</artifactId>
    <version>1.0.0</version>
</dependency>

Option C: Git Repositories

# ~/.idempiere-cli/config.yaml
plugins:
  - git: https://github.com/org/idempiere-cli-ai-plugin.git
    version: v1.0.0
  - git: https://github.com/org/custom-generator.git
    branch: main

Configuration

Global Configuration

# ~/.idempiere-cli/config.yaml
plugins:
  enabled:
    - ai-generator
    - slack-integration
  disabled:
    - deprecated-plugin

ai:
  provider: claude  # claude, openai, local
  apiKey: ${CLAUDE_API_KEY}
  model: claude-sonnet-4-20250514

integrations:
  slack:
    webhook: ${SLACK_WEBHOOK_URL}
    channel: "#idempiere-dev"

  github:
    token: ${GITHUB_TOKEN}
    repo: org/idempiere-plugins

Per-Project Configuration

# .idempiere-cli.yaml (in project root)
plugins:
  ai-generator:
    enabled: true
    defaultModel: claude-sonnet-4-20250514
    templates:
      printFormat: custom-template.yaml

AI Integration

AI Service Interface

public interface AIService {
    String getName();

    // Generate content based on prompt
    AIResponse generate(AIRequest request);

    // Analyze content
    AIAnalysis analyze(String content, AnalysisType type);

    // Available models
    List<AIModel> getAvailableModels();
}

Supported Providers

Provider Models Use Case
Claude claude-sonnet-4-20250514, opus Complex generation, analysis
OpenAI gpt-4, gpt-3.5 Quick generation
Local llama, mistral Offline/private use
MCP Any MCP server Custom integrations

MCP Integration

# ~/.idempiere-cli/config.yaml
mcp:
  servers:
    - name: idempiere-mcp
      command: npx
      args: ["idempiere-mcp-server"]
    - name: custom-generator
      command: python
      args: ["-m", "custom_mcp_server"]

Example Plugin: AI Print Format Generator

Plugin Structure

ai-print-format-plugin/
├── pom.xml
├── src/main/java/
│   └── org/idempiere/cli/plugins/aiprintformat/
│       ├── AIPrintFormatPlugin.java
│       ├── PrintFormatGenerator.java
│       └── commands/
│           └── GeneratePrintFormatCommand.java
└── src/main/resources/
    ├── META-INF/services/
    │   └── org.idempiere.cli.spi.PluginProvider
    └── templates/
        └── print-format-prompt.txt

Usage

# Generate print format from description
idempiere-cli ai generate print-format \
  --description "Invoice with header, line items, and totals" \
  --table C_Invoice \
  --output invoice-format.xml

# Generate with specific AI model
idempiere-cli ai generate print-format \
  --description "Customer statement" \
  --model claude-sonnet-4-20250514 \
  --table C_BPartner

Implementation Phases

Phase 1: Plugin Infrastructure

Phase 2: Core Plugins

Phase 3: Community Plugins


Consequences

Positive

Negative

Risks


Alternatives Considered

1. Monolithic CLI with Feature Flags

2. Separate CLI Tools

3. External Scripts


References

Path: /docs/developers/architecture/idempiere-hub/002-cli-plugin-architecture