# Musoq CLI [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Puchaczov/Musoq.CLI/blob/main/LICENSE) Musoq.CLI is a powerful command-line interface that brings the magic of [Musoq](https://github.com/Puchaczov/Musoq) to your fingertips. Query various data sources with ease, wherever they reside! ## 🌟 Features - πŸ–₯️ Spin up a Musoq server - πŸ” Query diverse data sources - πŸ”„ Seamless server-client interaction - πŸ“Š Multiple output formats (Raw, CSV, JSON, Interpreted JSON, Yaml, Interpreted Yaml) - 🚫 No additional dependencies required ## πŸš€ Easy Install / Update / Remove ### Install / Update Powershell: ```powershell irm https://raw.githubusercontent.com/Puchaczov/Musoq.CLI/refs/heads/main/scripts/powershell/install.ps1 | iex ``` Shell using curl: ```shell curl -fsSL https://raw.githubusercontent.com/Puchaczov/Musoq.CLI/refs/heads/main/scripts/bash/install.sh | sudo bash ``` Shell using wget: ```shell wget -qO- https://raw.githubusercontent.com/Puchaczov/Musoq.CLI/refs/heads/main/scripts/bash/install.sh | sudo bash ``` ### Remove Powershell: ```powershell irm https://raw.githubusercontent.com/Puchaczov/Musoq.CLI/refs/heads/main/scripts/powershell/remove.ps1 | iex ``` Shell using curl: ```shell curl -fsSL https://raw.githubusercontent.com/Puchaczov/Musoq.CLI/refs/heads/main/scripts/bash/remove.sh | sudo bash ``` Shell using wget: ```shell wget -qO- https://raw.githubusercontent.com/Puchaczov/Musoq.CLI/refs/heads/main/scripts/bash/remove.sh | sudo sh ``` ## πŸƒ Quick Start ### With Server In Background 1. πŸ“₯ Install Musoq.CLI using the easy installation script above 2. πŸ–₯️ Open any terminal 3. πŸƒβ€β™‚οΈ Run the server in background: - Windows & Linux: `Musoq serve` 4. πŸ” Run queries as needed 5. πŸ›‘ To quit the server: `Musoq quit` ### With Server In Foreground 1. πŸ“₯ Install Musoq.CLI using the easy installation script above 2. πŸ–₯️ Open one terminal and run the server: - Windows & Linux: `Musoq serve --wait-until-exit` 3. πŸ–₯️ Open another terminal 4. πŸ” Run a query: - Windows & Linux: `Musoq run query "select 1 from #system.dual()"` 5. πŸ›‘ To quit the server: `Musoq quit` # Musoq Server & CLI Specification --- ## Table of Contents 1. [Introduction](#1-introduction) 2. [Architecture Overview](#2-architecture-overview) 3. [Installation & Environment](#3-installation--environment) 4. [Server Commands](#4-server-commands) 5. [Query Execution](#5-query-execution) 6. [Data Source Management](#6-data-source-management) 7. [Python Plugin Development](#7-python-plugin-development) 8. [Tool Management](#8-tool-management) 9. [Scripts Management](#9-scripts-management) 10. [Registry Management](#10-registry-management) 11. [Configuration Management](#11-configuration-management) 12. [Bucket Management](#12-bucket-management) 13. [Utility Commands](#13-utility-commands) 14. [API Reference](#14-api-reference) 15. [Exit Codes & Error Handling](#15-exit-codes--error-handling) 16. [Configuration Files](#16-configuration-files) 17. [Security Considerations](#17-security-considerations) --- ## 1. Introduction ### 1.1 Purpose This specification defines the Musoq server and command-line interface (CLI). The server provides a local execution environment for Musoq SQL queries, enabling developers to query diverse data sources through a unified interface. ### 1.2 Scope This specification covers: - CLI command structure and syntax - Server lifecycle management - Data source plugin management (both .NET and Python) - Python plugin development contract - Tool definition and execution - SQL script management - Plugin registry configuration - Configuration and environment variables - REST API endpoints for programmatic access - Error handling and exit codes - Configuration file formats - Security considerations ### 1.3 Design Philosophy The Musoq CLI follows these principles: - **Discoverability**: Commands are organized hierarchically with consistent patterns - **Composability**: Output formats support piping and scripting - **Offline-First**: By default, it doesn't connect anywhere, doesn't send any telemetry, can work fully offline - **Extensibility**: Plugin architecture for data sources and tools ### 1.4 Command Structure All CLI commands follow this general pattern: ``` musoq [subcommand] [arguments] [options] ``` Commands are case-insensitive. Options use the standard `--option` or `-o` format. ### 1.5 Terminology | Term | Definition | |------|------------| | **Server** | The local server that executes queries and manages plugins | | **Data Source** | A plugin that provides access to a specific type of data | | **Schema** | The named interface exposed by a data source for SQL queries | | **Tool** | A predefined SQL query template with parameters | | **Script** | A saved SQL query file | | **Registry** | A remote source for discovering and downloading plugins | | **Bucket** | An isolated context for query execution with preloaded data | --- ## 2. Architecture Overview ### 2.1 Component Architecture ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ CLI (musoq) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚ Commands: serve, run, datasource, tool, scripts, registry β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ HTTP / Named Pipes β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ API Server β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Controllers β”‚ β”‚ CQRS Handlersβ”‚ β”‚ Query Execution Engine β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Data Source Plugins β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ .NET β”‚ β”‚ Python β”‚ β”‚ Built-in β”‚ β”‚ External (.zip) β”‚ β”‚ β”‚ β”‚ Plugins β”‚ β”‚ Plugins β”‚ β”‚ Sources β”‚ β”‚ Packages β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 2.2 Communication Model The CLI communicates with the API server through: 1. **HTTP REST API**: For management operations 2. **Named Pipes**: For pipe feeding data into queries ### 2.3 Server Lifecycle The server operates in two modes: | Mode | Command | Behavior | |------|---------|----------| | Background | `musoq serve` | Starts as detached process, returns immediately | | Foreground | `musoq serve --wait-until-exit` | Blocks until explicitly stopped | --- ## 3. Installation & Environment ### 3.1 Prerequisites | Requirement | Version | Purpose | |-------------|---------|---------| | Python (optional) | 3.12 | Python plugin support via Python.NET | --- ## 4. Server Commands ### 4.1 serve - Start Server Start the local server. ``` musoq serve [options] ``` **Options:** | Option | Description | Default | |--------|-------------|---------| | `--wait-until-exit` | Run in foreground, block until stopped | false | | `--auto-shutdown` | Enable auto-shutdown after idle period | false | | `--is-independent-process` | Internal flag for subprocess mode | false | **Examples:** ```bash # Start server in background (returns immediately) musoq serve # Start server in foreground (blocks) musoq serve --wait-until-exit # Start with auto-shutdown enabled (shuts down after 10 minutes of inactivity) musoq serve --wait-until-exit --auto-shutdown ``` **Output on Success:** ``` β–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–„β–„ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–€β–€ Server is up and running ``` ### 4.2 quit - Stop Server Stop the running Musoq server. ``` musoq quit ``` **Exit Codes:** - `0`: Server stopped successfully - `2`: Server was not running or communication failed --- ## 5. Query Execution ### 5.1 run - Execute Queries Execute SQL queries from strings, script names, or files. ``` musoq run [options] ``` **Arguments:** | Argument | Description | |----------|-------------| | `` | SQL query string, script name, or file path (with `--from-file`) | **Options:** | Option | Description | Default | |--------|-------------|---------| | `--bucket ` | Bucket name for query context | None | | `--format ` | Output format (see table below) | `table` | | `--execute ` | Expression to execute on results | None | | `--debug` | Show transformed query before execution | false | | `--unquoted` | Disable quoting in CSV output | false | | `--no-header` | Skip header row in output | false | | `--stacktrace` | Include stack trace in error output | false | | `--execution-details` | Show execution phase and progress details | false | | `--from-file` | Treat input as file path | false | **Examples:** ```bash # Execute inline query musoq run "SELECT 1 FROM #system.dual()" # Execute with JSON output musoq run "SELECT * FROM #os.files('.')" --format json # Execute script by name (looks up in ~/.musoq/Scripts/) musoq run my_script # Execute from file musoq run ./queries/analysis.sql --from-file # Debug mode - shows the actual query sent to the server musoq run "SELECT * FROM #os.files('.')" --debug # Pipe-friendly CSV output without headers musoq run "SELECT Name, Size FROM #os.files('.')" --format csv --no-header # Show execution progress for long-running queries musoq run "SELECT * FROM #os.files('/', true)" --execution-details ``` ### 5.2 Standard Input Piping Queries can reference piped data using the `#stdin` schema: ```bash # Pipe CSV data cat data.csv | musoq run "SELECT * FROM #stdin.csv(true, 0)" # Pipe JSON data cat data.json | musoq run "SELECT * FROM #stdin.json()" # Chain with other tools curl https://api.example.com/data | musoq run "SELECT id, name FROM #stdin.json() WHERE active = true" ``` ### 5.3 Output Formats | Format | Response Format | Description | Use Case | |--------|-----------------|-------------|----------| | `table` | raw | ASCII table (default) | Human-readable terminal output | | `json` | json | JSON array of objects | API integration, jq processing | | `csv` | csv | Comma-separated values | Spreadsheet import, further processing | | `yaml` | yaml | YAML format | Configuration files, readability | | `raw` | raw | Raw values, newline-separated | Simple scripting | | `interpreted_json` | json | Interpreted JSON (preserves structure) | Structured data extraction | | `reconstructed_json` | json | Reconstructed JSON (path-value mode) | Flattened JSON output | | `interpreted_yaml` | yaml | Interpreted YAML (preserves structure) | Structured data as YAML | | `reconstructed_yaml` | yaml | Reconstructed YAML (path-value mode) | Flattened YAML output | ### 5.4 Script Resolution When the input doesn't look like a SQL query, the CLI attempts to resolve it as a script: 1. Check if input ends with `.sql` - treat as script name 2. Look up script in `~/.musoq/Scripts/{name}.sql` 3. If found, execute the script contents 4. If not found, treat input as a raw query ### 5.5 Query Transformation The CLI performs the following transformations before execution: 1. **Expression to Query**: Simple expressions like `1 + 1` are wrapped in `SELECT ... FROM #system.dual()` 2. **Stdin Rewriting**: References to `#stdin` are rewritten with appropriate model configurations for AI extraction --- ## 6. Data Source Management The `datasource` command manages installed data source plugins, including both .NET assemblies and Python scripts. ### 6.1 Plugin Types | Type | Description | Location | |------|-------------|----------| | `DotNet` | Compiled .NET assemblies | `~/.musoq/DataSources/` | | `Python` | Python v.2 plugin projects | `~/.musoq/Python/Scripts/` | | `BuiltIn` | Plugins bundled with Musoq | Application directory | ### 6.2 datasource list List all installed data sources. ``` musoq datasource list ``` **Output Columns:** | Column | Description | |--------|-------------| | Name | Data source identifier (used in `datasource show`) | | Version | Installed version (semantic versioning) | | Type | Plugin type: `DotNet`, `Python`, or `BuiltIn` | | Enabled | Whether the data source is active (`Yes`/`No`) | | Installed At | Installation timestamp (UTC) | **Example Output:** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Name β”‚ Version β”‚ Type β”‚ Enabled β”‚ Installed At β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Musoq.DataSources.Roslyn β”‚ 7.2.0 β”‚ DotNet β”‚ Yes β”‚ 2024-12-15 10:30:00 β”‚ β”‚ weather_api β”‚ 1.0.0 β”‚ Python β”‚ Yes β”‚ 2024-12-16 14:20:00 β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 6.3 datasource show Show detailed information about a specific data source. ``` musoq datasource show ``` **Output Fields:** | Field | Description | |-------|-------------| | Name | Data source identifier | | Version | Installed version | | Type | Plugin type | | Enabled | Active status | | Installed | Installation timestamp | | Path | Filesystem path to the plugin | | Entry Point | Main assembly or script file | | Architecture | Target architecture (x64, arm64, any) | | Platform | Target platform (windows, linux, osx, any) | **Example Output:** ``` Musoq.DataSources.Roslyn Version: 7.2.0 Type: DotNet Enabled: Yes Installed: 2024-12-15 10:30:00 Path: /home/user/.musoq/DataSources/Musoq.DataSources.Roslyn Entry Point: Musoq.DataSources.Roslyn.dll Architecture: x64 Platform: linux ``` ### 6.4 datasource install Install a data source from the plugin registry. ``` musoq datasource install [options] ``` **Arguments:** | Argument | Description | |----------|-------------| | `` | Plugin name (short or full, e.g., `roslyn` or `Musoq.DataSources.Roslyn`) | **Options:** | Option | Description | Default | |--------|-------------|---------| | `-v, --version ` | Specific version to install | latest | | `--offline` | Use cached registry only | false | | `--non-interactive` | Plain text progress output (for CI/CD) | false | **Examples:** ```bash # Install latest version (uses short name) musoq datasource install roslyn # Install using full package name musoq datasource install Musoq.DataSources.Roslyn # Install specific version musoq datasource install Musoq.DataSources.Roslyn --version 7.1.0 # Non-interactive mode for CI/CD pipelines musoq datasource install Musoq.DataSources.Roslyn --non-interactive ``` **Interactive Progress:** ``` Installing Musoq.DataSources.Roslyn v7.2.0... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:02 βœ“ Successfully installed Musoq.DataSources.Roslyn (v7.2.0) ``` ### 6.5 datasource import Import a data source from a local path or zip file. ``` musoq datasource import [options] ``` **Arguments:** | Argument | Description | |----------|-------------| | `` | Path to plugin directory or zip file | **Options:** | Option | Description | Default | |--------|-------------|---------| | `--name ` | Custom name for imported plugin | Derived from path | | `--non-interactive` | Plain text progress output | false | **Examples:** ```bash # Import from directory musoq datasource import /path/to/plugin # Import from zip file musoq datasource import ./plugin.zip # Import with custom name musoq datasource import ./plugin.zip --name my-custom-plugin ``` ### 6.6 datasource uninstall Uninstall a data source. ``` musoq datasource uninstall ``` **Example:** ```bash musoq datasource uninstall Musoq.DataSources.Roslyn # Output: Successfully uninstalled data source 'Musoq.DataSources.Roslyn' ``` ### 6.7 datasource create Create a new Python data source from a template. ``` musoq datasource create [options] ``` **Arguments:** | Argument | Description | |----------|-------------| | `` | Name for the new Python data source (alphanumeric, underscores allowed) | **Options:** | Option | Description | Default | |--------|-------------|---------| | `-t, --template