Askimo CLI Architecture Guide
Overview
Section titled “Overview”The Askimo CLI is a command-line interface application that provides interactive and non-interactive modes for AI-powered assistance. It supports piped input, recipe execution, and rich terminal interactions with command history and auto-completion.
Key Technologies
Section titled “Key Technologies”- Language: Kotlin
- Terminal Framework: JLine 3
- Architecture Pattern: Command Pattern + Session Management
- Concurrency: Kotlin Coroutines
- Persistence: Shared with Desktop module (SQLite via Exposed)
Architecture Overview
Section titled “Architecture Overview”The CLI application follows a command-driven architecture with clear separation between interactive and non-interactive modes:
graph TD
A[Terminal Layer
JLine Terminal & Input Processing]
B[Command Layer
Command Handlers & Parsers]
C[Session Layer
Session Management & Chat Service]
D[Core Layer
Shared Module: Providers, Repository, Recipes]
A --> B
B --> C
C --> D
style A fill:#e1f5ff,stroke:#0288d1,stroke-width:2px
style B fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style C fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
style D fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
Design Principles
Section titled “Design Principles”- Mode Separation: Clear distinction between interactive and non-interactive modes
- Command Pattern: Each operation is encapsulated as a command handler
- Session-Centric: All operations revolve around a chat session
- Stream-Friendly: First-class support for piped input/output
- Extensibility: Easy to add new commands and recipes
Module Organization
Section titled “Module Organization”The CLI module is organized into the following key packages:
cli/├── ChatCli.kt # Application entry point and main loop├── commands/ # Command handlers│ ├── HelpCommandHandler.kt│ ├── ConfigCommandHandler.kt│ ├── SessionCommandHandlers.kt│ └── ...├── recipes/ # Recipe system│ ├── RecipeExecutor.kt│ ├── RecipeRegistry.kt│ ├── ToolRegistry.kt│ └── DefaultRecipeInitializer.kt├── util/ # Utilities│ ├── CompositeCommandExecutor.kt│ ├── NonInteractiveCommandParser.kt│ └── ...├── autocompleter/ # Terminal auto-completion│ └── CliCommandCompleter.kt├── LoadingIndicator.kt # Terminal UI feedback├── MarkdownJLineRenderer.kt # Markdown rendering in terminal└── MarkdownStreamingSink.kt # Streaming output handlerPackage Responsibilities
Section titled “Package Responsibilities”| Package | Purpose |
|---|---|
commands/ | Command handlers for both interactive and non-interactive modes |
recipes/ | YAML-based automation recipes and execution engine |
util/ | Command parsing, execution, and utility functions |
autocompleter/ | JLine auto-completion for commands |
| Root package | Main entry point, rendering, and terminal interaction |
Architectural Layers
Section titled “Architectural Layers”1. Terminal Layer (JLine)
Section titled “1. Terminal Layer (JLine)”Handles all terminal I/O, user input, and rendering. Provides rich terminal features like history, auto-completion, and multi-line input.
Key Components:
- Terminal: Low-level terminal control
- LineReader: Interactive line reading with history
- Parser: Multi-line input parsing with continuation support
- Completer: Command and argument auto-completion
Features:
- Command history with search (Ctrl+R)
- Tab completion for commands
- Multi-line input with backslash continuation
- Markdown rendering in terminal
- Loading indicators and progress feedback
2. Command Layer
Section titled “2. Command Layer”Implements the Command Pattern for handling user actions. Each command is a self-contained handler.
Command Types:
Shared Commands (available in both modes):
- Help, Config, Providers, Models, Parameters, Tools, Version
Interactive-Only Commands:
- Copy, Clear Memory, Project Management, Session Management
Non-Interactive-Only Commands:
- Recipe Management (Create, List, Delete)
Command Handler Interface:
Command Handler├── keyword: String (e.g., ":help", ":config")├── handle(ParsedLine): Unit└── getDescription(): String3. Session Layer
Section titled “3. Session Layer”Manages the chat session lifecycle and coordinates with the Core layer.
Key Components:
- Session: Maintains conversation state and context
- ChatService: Coordinates message sending and streaming
- SessionMode: Differentiates between CLI_INTERACTIVE and CLI_PROMPT modes
Responsibilities:
- Maintain conversation history
- Manage provider and model configuration
- Handle context preparation
- Coordinate streaming responses
4. Core Layer (Shared Module)
Section titled “4. Core Layer (Shared Module)”Shared functionality used by both CLI and Desktop applications.
Components:
- Providers: AI provider integrations (OpenAI, Anthropic, etc.)
- Repository: Data persistence layer
- Session: Core session management
- Recipes: YAML-based automation definitions
Execution Modes
Section titled “Execution Modes”The CLI supports three distinct execution modes:
1. Interactive Mode (Default)
Section titled “1. Interactive Mode (Default)”Launched when no arguments are provided. Provides a REPL-style interface.
askimo> [user input]Features:
- Command history and search
- Tab completion
- Multi-line input with
\continuation - Session management
- Real-time streaming responses
2. Prompt Mode
Section titled “2. Prompt Mode”Single prompt execution with optional piped input.
askimo -p "your prompt" < input.txt
askimo -p "direct prompt"
echo "data" | askimo -p "analyze this"Features:
- One-shot execution
- Stdin piping support
- Automatic context building from piped input
3. Recipe Mode
Section titled “3. Recipe Mode”Execute YAML-defined automation recipes.
askimo -r recipe-name --set key=valueFeatures:
- Multi-step automation
- Variable substitution
- External tool integration
- Retry logic with exponential backoff
Data Flow
Section titled “Data Flow”The application follows different flows depending on the execution mode:
Interactive Chat Flow
Section titled “Interactive Chat Flow”graph TD
A[User Input
JLine LineReader] --> B[Parser
Parse command or chat message]
B -->|Command| C[CommandHandler]
B -->|Chat Message| D[Session]
C --> E[Execute]
D --> F[Provider]
F --> G[Stream Response]
G --> H[Terminal Output]
style A fill:#e1f5ff,stroke:#0288d1,stroke-width:2px
style B fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
style C fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style D fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style E fill:#fce4ec,stroke:#c2185b,stroke-width:2px
style F fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style G fill:#fff9c4,stroke:#f57f17,stroke-width:2px
style H fill:#e1f5ff,stroke:#0288d1,stroke-width:2px
Recipe Execution Flow
Section titled “Recipe Execution Flow”graph TD
A[Recipe Name] --> B[Registry]
B --> C[Executor]
C --> D[Steps]
D --> E[Prompt Step]
D --> F[Tool Step]
D --> G[Loop Step]
D --> H[Parallel Step]
E --> I[Output/Result]
F --> I
G --> I
H --> I
style A fill:#e1f5ff,stroke:#0288d1,stroke-width:2px
style B fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style C fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
style D fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style E fill:#fce4ec,stroke:#c2185b,stroke-width:2px
style F fill:#fce4ec,stroke:#c2185b,stroke-width:2px
style G fill:#fce4ec,stroke:#c2185b,stroke-width:2px
style H fill:#fce4ec,stroke:#c2185b,stroke-width:2px
style I fill:#fff9c4,stroke:#f57f17,stroke-width:2px
Key Design Patterns
Section titled “Key Design Patterns”1. Command Pattern
Section titled “1. Command Pattern”Each user action is encapsulated as a command handler with a consistent interface:
- Keyword-based routing
- Unified handling mechanism
- Easy to add new commands
2. Mode-Based Architecture
Section titled “2. Mode-Based Architecture”The CLI adapts its behavior based on execution mode:
- Interactive: Full REPL with terminal features
- Prompt: One-shot execution with piping support
- Recipe: Multi-step automation with tool integration
3. Streaming Response Handling
Section titled “3. Streaming Response Handling”AI responses are streamed in real-time:
- Token-by-token rendering
- Markdown formatting on-the-fly
- Loading indicators with elapsed time
- Non-blocking terminal updates
4. Recipe System
Section titled “4. Recipe System”YAML-based declarative automation:
- Step-by-step execution
- Variable substitution and overrides
- Tool allowlisting for security
- Retry logic for transient failures
Recipe System
Section titled “Recipe System”The recipe system provides YAML-based automation for complex multi-step tasks.
Recipe Structure
Section titled “Recipe Structure”name: example
description: Example recipe
steps:
- type: prompt
prompt: "Step 1 prompt"
- type: tool
tool: read_file
args:
path: "file.txt"Step Types
Section titled “Step Types”- prompt: Send a prompt to AI
- tool: Execute a tool (file operations, code execution, etc.)
- loop: Iterate over items
- parallel: Execute steps concurrently
Tool Registry
Section titled “Tool Registry”Manages available tools and enforces security:
- Default tools (file operations, search, etc.)
- Tool allowlisting per recipe
- Safe execution environment
Platform Support
Section titled “Platform Support”The CLI runs on multiple platforms with terminal-specific adaptations:
Supported Platforms
Section titled “Supported Platforms”- macOS: Full terminal support with native features
- Windows: PowerShell and CMD support
- Linux: Bash, Zsh, and other shell support
Terminal Features
Section titled “Terminal Features”Input Handling:
- Stdin piping for data processing
- Multi-line input with continuation
- Command history persistence
- Auto-completion
Output Rendering:
- ANSI color support
- Markdown rendering with syntax highlighting
- Loading indicators
- Streaming output
Development Guidelines
Section titled “Development Guidelines”Adding New Commands
Section titled “Adding New Commands”- Create a new command handler implementing
CommandHandler - Define keyword (e.g.,
:mycommand) - Implement
handle(ParsedLine)method - Add to appropriate command list (shared/interactive/non-interactive)
- Update help text
Creating Recipes
Section titled “Creating Recipes”- Define recipe in YAML format
- Place in recipes directory or user config
- Use variable substitution with
${var}syntax - Test with
--setoverrides - Document in recipe list
Terminal Rendering
Section titled “Terminal Rendering”- Use
MarkdownJLineRendererfor formatted output - Show loading indicators for long operations
- Stream responses token-by-token for better UX
- Handle terminal width and scrolling gracefully
External Resources
Section titled “External Resources”Contributing
Section titled “Contributing”When contributing to the CLI module, please:
- Follow the Command Pattern for new features
- Support both interactive and non-interactive modes where applicable
- Write tests for command handlers
- Update help text and documentation
- Follow Kotlin coding conventions