Metadata-Version: 2.4
Name: muban-cli
Version: 1.8.0
Summary: Command-line interface for Muban Document Generation Service
Author-email: Muban Team <contact@muban.me>
Maintainer-email: Muban Team <contact@muban.me>
License-Expression: MIT
Project-URL: Homepage, https://muban.me
Project-URL: Documentation, https://muban.me/features.html
Keywords: muban,jasperreports,document-generation,cli,pdf,reporting,templates
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Markup
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0.0
Requires-Dist: requests>=2.25.0
Requires-Dist: urllib3>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
Requires-Dist: pytest-qt>=4.2.0; extra == "dev"
Requires-Dist: pytest-timeout>=2.2.0; extra == "dev"
Requires-Dist: responses>=0.23.0; extra == "dev"
Requires-Dist: black>=23.0.0; extra == "dev"
Requires-Dist: isort>=5.12.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: types-requests>=2.28.0; extra == "dev"
Requires-Dist: flake8>=6.0.0; extra == "dev"
Provides-Extra: gui
Requires-Dist: PyQt6>=6.5.0; extra == "gui"
Provides-Extra: docs
Requires-Dist: mkdocs>=1.4.0; extra == "docs"
Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
Dynamic: license-file

# Muban CLI

A robust command-line interface for the **Muban Document Generation Service**. Manage JasperReports (JRXML) and DOCX templates and generate documents directly from your terminal.

[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)

## Features

- **Graphical User Interface** - Optional PyQt6-based GUI for visual template management and document generation
- **Secure Authentication** - JWT token-based auth with password or OAuth2 client credentials flow
- **Template Management** - List, upload, download, and delete templates (JRXML and DOCX)
- **Tag Management** - Organize templates with key-value tags, filter by tags
- **Template Packaging** - Package JRXML or DOCX templates with auto-detected image assets and optional fonts into deployable ZIP packages
- **Document Generation** - Generate PDF, XLSX, DOCX, RTF, HTML, and TXT documents
- **Async Processing** - Submit bulk document generation jobs and monitor progress
- **Search & Filter** - Search templates and filter by tags or audit logs
- **Audit & Monitoring** - Access audit logs and security dashboards (admin)
- **Multiple Output Formats** - Table, JSON, and CSV for easy data export
- **Automation Ready** - Perfect for CI/CD pipelines with service account support
- **Cross-Platform** - Works on Windows, macOS, and Linux

## Installation

### From PyPI (Recommended)

```bash
pip install muban-cli
```

### From Source

```bash
git clone https://github.com/muban/muban-cli.git
cd muban-cli
pip install -e .
```

### GUI Installation

To use the graphical user interface, install with GUI extras:

```bash
pip install muban-cli[gui]
```

This installs PyQt6 and enables the `muban-gui` command.

### Development Installation

```bash
pip install -e ".[dev]"
```

## Quick Start

### 1. Configure the Server

```bash
# Interactive setup
muban configure

# Or with command-line options
muban configure --server https://api.muban.me
```

### 2. Login with Your Credentials

```bash
# Interactive login (prompts for username/password)
muban login

# Or with command-line options
muban login --username your@email.com
```

### 3. List Available Templates

```bash
muban list
```

### 4. Generate a Document

```bash
muban generate TEMPLATE_ID -p title="Monthly Report" -p date="2025-01-08"
```

## Unauthenticated Access

If your Muban API server has authentication disabled (common in development or internal deployments), you can use the CLI without logging in:

```bash
# Configure the server only (no login required)
muban configure --server http://localhost:8080

# Start using the CLI immediately
muban list
muban generate TEMPLATE_ID -p name="Test"
```

The CLI automatically detects when no credentials are configured and sends requests without an `Authorization` header.

## Configuration

### Configuration File

Configuration is stored in `~/.muban/config.json`. JWT tokens are stored separately in `~/.muban/credentials.json` with restricted permissions.

### Environment Variables

| Variable | Description |
| -------- | ----------- |
| `MUBAN_TOKEN` | JWT Bearer token (obtained via `muban login`) |
| `MUBAN_SERVER_URL` | API server URL (default: <https://api.muban.me>) |
| `MUBAN_AUTH_SERVER_URL` | OAuth2/IdP token endpoint (if different from API server) |
| `MUBAN_CLIENT_ID` | OAuth2 Client ID (for client credentials flow) |
| `MUBAN_CLIENT_SECRET` | OAuth2 Client Secret (for client credentials flow) |
| `MUBAN_TIMEOUT` | Request timeout in seconds |
| `MUBAN_MAX_RETRIES` | Max retries for transient errors (default: 3, set to 0 to disable) |
| `MUBAN_VERIFY_SSL` | Enable/disable SSL verification |
| `MUBAN_CONFIG_DIR` | Custom configuration directory |

Environment variables take precedence over configuration files.

### Debug Mode

Both CLI and GUI support a `--debug` flag that enables verbose logging to help diagnose issues:

```bash
# CLI - enable debug mode (must come before subcommand)
muban --debug generate TEMPLATE_ID -p title="Test"
muban --debug list

# GUI - enable debug mode
muban-gui --debug
```

When debug mode is enabled:

- Full request bodies are logged (including parameters, data, and export options)
- All API requests and responses are captured
- Logs are written to `~/.muban/debug.log`

This is useful for:

- Verifying that parameters are being sent correctly to the API
- Diagnosing locale or export option issues
- Providing detailed information for support tickets

## Commands Reference

### Authentication

```bash
# Login with credentials (interactive)
muban login

# Login with username provided
muban login --username admin@example.com

# Login with custom server
muban login --server https://api.muban.me

# Login with OAuth2 Client Credentials (for CI/CD / service accounts)
muban login --client-credentials
muban login -c --client-id my-client --client-secret secret123

# Login with external IdP (ADFS, Azure AD, Keycloak)
muban login -c --auth-server https://adfs.company.com/adfs/oauth2/token

# Skip SSL verification (development only)
muban login --no-verify-ssl

# Check authentication status (shows token expiry)
muban whoami

# Manually refresh access token
muban refresh

# Logout (clear all tokens)
muban logout
```

**Token Refresh:**

- If the server provides a refresh token, it's automatically stored
- The CLI automatically refreshes expired tokens when making API requests
- Use `muban refresh` to manually refresh before expiration
- Use `muban whoami` to see token expiration time

### Configuration Commands

```bash
# Interactive configuration
muban configure

# Set server URL
muban configure --server https://api.muban.me

# Set auth server (if different from API server)
muban configure --auth-server https://auth.muban.me

# Set default author for template uploads
muban configure --author "John Doe"

# Enable auto-upload after packaging
muban configure --auto-upload

# Disable auto-upload
muban configure --no-auto-upload

# Show current configuration
muban configure --show

# Clear all configuration
muban config-clear
```

### Template Management

```bash
# List all templates
muban list
muban list --search "invoice" --format json
muban list --format csv > templates.csv    # Export to CSV
muban list --page 2 --size 50
muban list --sort-by templateType           # Sort by template type (JASPER/DOCX)
muban list -t phase:prod -t department:finance  # Filter by tags (AND logic)

# Search templates
muban search "quarterly report"

# Get template details (includes tags)
muban get TEMPLATE_ID
muban get TEMPLATE_ID --params  # Show parameters
muban get TEMPLATE_ID --fields  # Show fields

# Export template details for Excel (CSV unified format)
muban get TEMPLATE_ID --params --fields --format csv > template.csv

# Export as single JSON object with nested parameters/fields
muban get TEMPLATE_ID --params --fields --format json

# Upload a template (ZIP format)
muban push report.zip --name "Monthly Report" --author "John Doe"
muban push invoice.zip -n "Invoice" -a "Finance Team" -d "Standard invoice template"

# Download a template
muban pull TEMPLATE_ID
muban pull TEMPLATE_ID -o ./templates/report.zip

# Delete a template
muban delete TEMPLATE_ID
muban delete TEMPLATE_ID --yes  # Skip confirmation

# Manage template tags
muban tags get TEMPLATE_ID                     # View tags
muban tags set TEMPLATE_ID phase=prod env=live # Replace all tags
muban tags add TEMPLATE_ID department=finance  # Add/upsert tags
muban tags delete TEMPLATE_ID --yes            # Remove all tags
```

### Template Packaging

The `package` command packages a template file (JRXML or DOCX) into a ZIP file ready for upload. For JRXML templates, it analyzes the file and includes all dependencies (images, subreports). For DOCX templates, it scans images for ALT text with the `image:` prefix and automatically includes referenced assets (static paths, SpEL expression path candidates, and all files from dynamic directories), along with optional custom fonts.

```bash
# Package a JRXML template (creates template.zip)
muban package template.jrxml

# Package a DOCX template
muban package template.docx

# Specify output path
muban package template.jrxml -o package.zip

# Dry run - analyze without creating ZIP
muban package template.jrxml --dry-run

# Verbose output - show all discovered assets
muban package template.jrxml --dry-run -v

# Custom REPORTS_DIR parameter name
muban package template.jrxml --reports-dir-param TEMPLATE_PATH

# Bundle custom fonts (creates fonts.xml for JasperReports)
muban package template.jrxml \
  --font-file fonts/OpenSans-Regular.ttf --font-name "Open Sans" --font-face normal --embedded \
  --font-file fonts/OpenSans-Bold.ttf --font-name "Open Sans" --font-face bold --embedded

# Multiple font families
muban package template.jrxml \
  --font-file arial.ttf --font-name "Arial Custom" --font-face normal --embedded \
  --font-file times.ttf --font-name "Times Custom" --font-face normal --no-embedded

# Use existing fonts.xml file instead of building font list
muban package template.jrxml --fonts-xml path/to/fonts.xml

# Package and upload in one step
muban package template.jrxml --upload
muban package template.docx --upload

# Package and upload with custom name/author
muban package template.jrxml --upload --name "My Report" --author "John Doe"
muban package template.docx -u --name "My Letter" --author "John Doe"
```

**Features:**

- **JRXML & DOCX Support** - Package both JasperReports and DOCX template types
- **Automatic Asset Discovery** - Parses JRXML to find all referenced images and subreports (JRXML only)
- **Recursive Subreport Analysis** - Analyzes subreport `.jrxml` files to include their dependencies (JRXML only)
- **Font Bundling** - Include custom fonts with auto-generated `fonts.xml` or use an existing one via `--fonts-xml`
- **REPORTS_DIR Resolution** - Respects the `REPORTS_DIR` parameter default value for path resolution
- **Dynamic Directory Support** - Includes all files from directories with dynamic filenames (`$P{DIR} + "path/" + $P{filename}`)
- **URL Skipping** - Automatically skips remote resources (http://, https://, etc.)
- **POSIX Path Handling** - Correctly handles path concatenation (e.g., `"../" + "/img"` → `"../img"`)
- **Auto-Upload** - Optionally upload immediately after packaging with `--upload` flag or enable globally via `muban configure --auto-upload`

**Example Output (verbose mode):**

```text
ℹ Packaging: invoice.jrxml
ℹ Working directory: /projects/templates

Main template (JASPER):
  invoice.jrxml

Assets found: 8
  ✓ subreports/header.jasper
  ✓ subreports/footer.jasper
  ✓ assets/img/logo.png
  ✓ assets/img/signature.png [from subreports/header.jrxml]
  ✓ assets/img/faksymile/* (dynamic: $P{signatureFile}, 3 files included)
  ✗ assets/img/missing.png (missing)

⚠ Dynamic asset: assets/img/faksymile/* - included all 3 files from directory
⚠ Asset not found: assets/img/missing.png (referenced in invoice.jrxml)

✓ Created: invoice.zip
```

**Typical Workflow:**

```bash
# 1. Package the template
muban package my-report.jrxml -o my-report.zip
# or for DOCX templates:
muban package my-letter.docx -o my-letter.zip

# 2. Upload to the server
muban push my-report.zip --name "My Report" --author "Developer"
```

### Document Generation

```bash
# Basic generation
muban generate TEMPLATE_ID -p title="Sales Report"

# Multiple parameters
muban generate TEMPLATE_ID -p title="Report" -p year=2025 -p amount=15750.25

# Different output formats
muban generate TEMPLATE_ID -F xlsx -o report.xlsx
muban generate TEMPLATE_ID -F docx -o report.docx
muban generate TEMPLATE_ID -F html -o report.html
muban generate TEMPLATE_ID -F txt -o report.txt

# Using parameter file
muban generate TEMPLATE_ID --params-file params.json

# Using JSON data source
muban generate TEMPLATE_ID --data-file data.json

# PDF options
muban generate TEMPLATE_ID --pdf-pdfa PDF/A-1b --locale pl_PL
muban generate TEMPLATE_ID --pdf-password secret123
muban generate TEMPLATE_ID --pdf-duplex-padding  # Pad to even pages for double-sided printing

# PDF output optimization
muban generate TEMPLATE_ID --pdf-image-compression 0.75     # JPEG re-compression quality (0.0-1.0)
muban generate TEMPLATE_ID --pdf-flatten-transparency        # Strip redundant transparency groups
muban generate TEMPLATE_ID --pdf-font-substitute "DejaVu Sans"  # Substitute base-14 fonts
muban generate TEMPLATE_ID --pdf-cmyk-profile ISOcoated_v2_300_bas.icc  # RGB→CMYK conversion

# General export options
muban generate TEMPLATE_ID --locale de_DE         # Document locale for formatting
muban generate TEMPLATE_ID --no-pagination        # Continuous output without page breaks
muban generate TEMPLATE_ID --locale en_US --no-pagination -F html  # Combine options

# TXT options
muban generate TEMPLATE_ID -F txt --txt-page-width-chars 80 --txt-trim-line-right
muban generate TEMPLATE_ID -F txt --txt-char-width 6.0 --txt-char-height 12.0

# Output options
muban generate TEMPLATE_ID -o ./output/report.pdf --filename "Sales_Report_Q4"
```

**Parameter File Format (params.json):**

```json
{
  "title": "Monthly Sales Report",
  "year": 2025,
  "department": "Finance"
}
```

Or as a list:

```json
[
  {"name": "title", "value": "Monthly Sales Report"},
  {"name": "year", "value": 2025}
]
```

**Data Source File Format (data.json):**

```json
{
  "items": [
    {"productName": "Widget A", "quantity": 100, "unitPrice": 25.50},
    {"productName": "Widget B", "quantity": 50, "unitPrice": 45.00}
  ],
  "summary": {
    "totalItems": 150,
    "totalValue": 4800.00
  }
}
```

### Utility Commands

```bash
# List available server fonts (default)
muban fonts

# List all fonts including template-bundled ones
muban fonts --show-all

# List ICC color profiles (for PDF export)
muban icc-profiles
```

The `fonts` command shows server-installed fonts by default. Use `--show-all` to include fonts bundled with uploaded templates. When using `--show-all`, a "Source" column indicates whether each font comes from the server or a template.

### Admin Commands

```bash
# Verify template integrity
muban admin verify-integrity TEMPLATE_ID

# Regenerate integrity digest
muban admin regenerate-digest TEMPLATE_ID

# Regenerate all digests
muban admin regenerate-all-digests --yes

# Get server configuration
muban admin server-config
```

### Async Document Generation

```bash
# Submit a single async request
muban async submit -t TEMPLATE_ID -F PDF -p title="Report"
muban async submit -t TEMPLATE_ID -d params.json -c my-correlation-id
muban async submit -t TEMPLATE_ID -Q my-custom-reply-queue   # Custom reply queue

# Submit bulk requests from JSON file
muban async bulk requests.json
muban async bulk requests.json --batch-id batch-2026-01-15

# Download result of a completed async request
muban async result REQUEST_ID                    # Auto-derives filename from response
muban async result REQUEST_ID -o report.pdf      # Save to specific path
muban async result REQUEST_ID --ack              # Download and remove from queue
muban async result REQUEST_ID --format json      # Show status as JSON

# List async requests
muban async list
muban async list --status FAILED --since 1d
muban async list --template TEMPLATE_ID --format json
muban async list --format csv > async_jobs.csv    # Export to CSV

# Get request details
muban async get REQUEST_ID

# Monitor workers and metrics (admin)
muban async workers
muban async metrics
muban async health

# View error log
muban async errors --since 24h
```

**Bulk Request File Format (requests.json):**

```json
[
  {
    "templateId": "abc123-uuid",
    "format": "PDF",
    "parameters": [{"name": "title", "value": "Report 1"}],
    "correlationId": "req-001",
    "replyQueue": "document.generation.replies.http"
  },
  {
    "templateId": "abc123-uuid",
    "format": "XLSX",
    "parameters": [{"name": "title", "value": "Report 2"}],
    "replyQueue": "document.generation.replies.http"
  }
]
```

### Audit Commands

```bash
# View audit logs
muban audit logs
muban audit logs --severity HIGH --since 1d
muban audit logs --event-type LOGIN_FAILURE --format json
muban audit logs --format csv > audit_export.csv    # Export to CSV

# Get audit statistics
muban audit statistics --since 7d

# View security events
muban audit security --since 24h

# Dashboard and monitoring
muban audit dashboard
muban audit threats
muban audit health

# List available event types
muban audit event-types

# Trigger cleanup
muban audit cleanup --yes
```

### User Management

```bash
# View your own profile
muban users me

# Update your profile
muban users update-me --email new@email.com --first-name John

# Change your password
muban users change-password

# List all users (admin only)
muban users list
muban users list --search "john" --role ROLE_ADMIN
muban users list --format csv > users.csv

# Get user details (admin only)
muban users get USER_ID

# Create a new user (admin only)
muban users create --username john --email john@example.com --role ROLE_USER

# Update a user (admin only)
muban users update USER_ID --email new@email.com

# Delete a user (admin only)
muban users delete USER_ID --yes

# Manage user roles (admin only)
muban users roles USER_ID --set ROLE_USER ROLE_MANAGER
muban users roles USER_ID --add ROLE_ADMIN

# Enable/disable user accounts (admin only)
muban users enable USER_ID
muban users disable USER_ID

# Set user password (admin only)
muban users set-password USER_ID
```

### Common Options

All commands support these options:

| Option       | Short | Description                                    |
|--------------|-------|------------------------------------------------|
| `--verbose`  | `-v`  | Enable verbose output                          |
| `--quiet`    | `-q`  | Suppress non-essential output                  |
| `--format`   | `-f`  | Output format: `table`, `json`, or `csv`       |
| `--truncate` |       | Max string length in table output (0=no limit) |
| `--help`     |       | Show help message                              |

**Output Format Examples:**

```bash
# Table output (default) - human-readable with colors
muban list

# JSON output - for programmatic parsing
muban list --format json

# CSV output - for Excel/spreadsheet integration
muban list --format csv > templates.csv
muban audit logs --format csv > audit.csv

# Template details with params/fields as unified CSV table
# (columns: Category, Name, Type, Value, Description)
muban get TEMPLATE_ID --params --fields --format csv > template.csv

# Template details as single JSON object with nested arrays
muban get TEMPLATE_ID --params --fields --format json

# Control truncation in table output (default: 50 chars)
muban list --truncate 80          # Longer strings
muban audit logs --truncate 0     # No truncation
```

**CSV Output Notes:**

- All CSV output uses raw numeric values (bytes, milliseconds) for data processing
- No pagination headers or decorative text in CSV output
- The `get` command with `--format csv` outputs a unified table with all template info, parameters, and fields in a single Excel-friendly format

## Graphical User Interface

Muban CLI includes an optional graphical user interface (GUI) for users who prefer a visual approach to template management and document generation.

### Launching the GUI

```bash
muban-gui
```

### GUI Features

The GUI provides a tabbed interface with the following sections:

#### **📦 Package Tab**

- Package JRXML or DOCX template files into deployable ZIP packages
- For JRXML: visual asset discovery and preview of images and subreports
- For DOCX: simple packaging with optional font bundling
- Font bundling configuration
- Dry-run mode to preview package contents
- Auto-upload to server after packaging (when enabled in Settings)

#### **📄 Templates Tab**

- Browse all templates on the server with pagination
- Search and filter templates
- Sort by name, author, size, type, or date
- View template details, parameters, and fields
- Manage tags — add, edit, and remove template tags via dialog
- Upload new templates (ZIP format)
- Download templates to local filesystem
- Delete templates with confirmation

#### **⚙️ Generate Tab**

- Select template and output format (PDF, XLSX, DOCX, RTF, HTML, TXT)
- Fill in template parameters with a dynamic form
- Load parameters from JSON file
- Provide JSON data sources
- Configure export options:
  - **General options**: Document locale for number/date/currency formatting, ignore pagination for continuous output
  - **PDF options**: PDF/A compliance, embedded ICC profiles, password protection, permission settings, duplex padding, image compression quality, flatten transparency, font embedding substitute, CMYK conversion profile
  - **HTML options**: Resource embedding, single-file output, custom CSS
  - **TXT options**: Character grid dimensions, page size in characters, line/page separators, trailing whitespace trimming
- Save generated documents to local filesystem

**Typed Parameter Values:**

When entering parameter values in the GUI, use JSON-like syntax to specify types:

| Input | Type | Example |
| ----- | ---- | ------- |
| `"text"` or `'text'` | String | `"Jan Kowalski"` |
| Number (no quotes) | Number | `123`, `12.5`, `-3.14` |
| `true` / `false` | Boolean | `true` |
| `null` | Null | `null` |
| Unquoted text | String (implicit) | `Hello World` |

This ensures numeric parameters like prices and quantities are sent as numbers to the API for proper locale-aware formatting.

#### **🖥️ Server Info Tab**

- View server configuration and status
- List available fonts (server and template-bundled)
- List available ICC color profiles
- Check API connectivity and version

#### **⚙️ Settings Tab**

- Configure server URL
- Set authentication credentials
- Manage OAuth2 client credentials
- Set default author for template uploads
- Enable/disable auto-upload after packaging
- Test connection to server

### GUI Requirements

- Python 3.9+
- PyQt6 6.5.0 or later
- Configured Muban server (via CLI or Settings tab)

The GUI shares configuration with the CLI, so if you've already configured the CLI with `muban configure` and `muban login`, the GUI will use those settings automatically.

## CI/CD Integration

### GitHub Actions Example

```yaml
name: Deploy Report Template

on:
  push:
    branches: [main]
    paths:
      - 'templates/**'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.9'
      
      - name: Install Muban CLI
        run: pip install muban-cli
      
      - name: Deploy Template
        env:
          MUBAN_SERVER_URL: https://api.muban.me
          MUBAN_CLIENT_ID: ${{ secrets.MUBAN_CLIENT_ID }}
          MUBAN_CLIENT_SECRET: ${{ secrets.MUBAN_CLIENT_SECRET }}
        run: |
          muban login --client-credentials
          cd templates
          zip -r report.zip ./monthly_report/
          muban push report.zip --name "Monthly Report" --author "CI/CD"
```

### GitLab CI Example

```yaml
deploy_template:
  image: python:3.9-slim
  stage: deploy
  only:
    changes:
      - templates/**
  script:
    - pip install muban-cli
    - muban login --client-credentials
    - cd templates && zip -r report.zip ./monthly_report/
    - muban push report.zip --name "Monthly Report" --author "GitLab CI"
  variables:
    MUBAN_SERVER_URL: https://api.muban.me
    MUBAN_CLIENT_ID: $MUBAN_CLIENT_ID
    MUBAN_CLIENT_SECRET: $MUBAN_CLIENT_SECRET
```

### Shell Script Example

```bash
#!/bin/bash
# deploy-template.sh

set -e

TEMPLATE_DIR="./my_jasper_project"
TEMPLATE_NAME="Monthly Sales Report"
AUTHOR="Deploy Script"

# Create ZIP archive
zip -r template.zip "$TEMPLATE_DIR"

# Upload to Muban
muban push template.zip \
  --name "$TEMPLATE_NAME" \
  --author "$AUTHOR" \
  --description "Deployed from commit ${GIT_COMMIT:-unknown}"

# Cleanup
rm template.zip

echo "Template deployed successfully!"
```

## Error Handling

The CLI provides detailed error messages and appropriate exit codes:

| Exit Code | Meaning |
| --------- | ------- |
| 0 | Success |
| 1 | General error |
| 130 | Interrupted (Ctrl+C) |

### Detailed Error Messages

When API errors occur, the CLI displays:

- **Error code** - Machine-readable error identifier (e.g., `TEMPLATE_FILL_ERROR`)
- **Error message** - Human-readable description
- **Correlation ID** - Unique request identifier for support tickets

Example error output:

```text
✗ API request failed: [TEMPLATE_FILL_ERROR] Failed to fill template: Unable to load report (Correlation ID: 00154aac-eb74-4867-a009-c9762fa0e059)
```

The correlation ID can be provided to support teams for in-depth error analysis in server logs.

Correlation IDs are also logged to the application log file for batch operations.

### GUI Error Dialogs

In the graphical interface, API errors are displayed in a custom dialog that:

- Shows the full error message in a scrollable text area
- **Highlights the correlation ID** for easy identification
- Provides a **"Copy ID"** button to quickly copy the correlation ID to clipboard
- Provides a **"Copy All"** button to copy the entire error message

This makes it easy to create support tickets with the relevant debugging information.

### Retry Behavior

The CLI automatically retries requests on transient network errors:

| Status Code | Behavior |
| ----------- | -------- |
| 429 | Rate limited - retries honoring `Retry-After` header |
| 502 | Bad gateway - retries (typically load balancer issue) |
| 503 | Service unavailable - retries (temporary overload) |
| 504 | Gateway timeout - retries (may succeed on retry) |
| 500 | Internal error - **no retry** (application error, needs investigation) |

The retry mechanism respects the `Retry-After` header sent by the server for 429 responses, up to a maximum backoff of 2 minutes.

Configure retry behavior:

```bash
# Disable retries (fail fast)
muban configure --max-retries 0

# Set custom retry count (default: 3)
export MUBAN_MAX_RETRIES=5
```

### Common Errors

```bash
# Not configured
$ muban list
✗ Muban CLI is not configured.
  Run 'muban configure' to set up your server, then 'muban login'.

# Not authenticated
$ muban list
✗ Not authenticated. Run 'muban login' to sign in.

# Template not found
$ muban get invalid-id
✗ Template not found: invalid-id

# Permission denied
$ muban delete some-template
✗ Permission denied. Manager role required.
```

## Development

### Running Tests

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=muban_cli --cov-report=html
```

### Code Quality

```bash
# Format code
black muban_cli
isort muban_cli

# Type checking
mypy muban_cli

# Linting
flake8 muban_cli
```

### Project Structure

```text
muban-cli/
├── muban_cli/
│   ├── __init__.py        # Package initialization, version info
│   ├── __main__.py        # Entry point for python -m muban_cli
│   ├── cli.py             # Main CLI entry point
│   ├── api.py             # Re-exports from api/ package (backward compat)
│   ├── auth.py            # Authentication (password + OAuth2)
│   ├── config.py          # Configuration management
│   ├── packager.py        # Template packager (JRXML/DOCX → ZIP)
│   ├── utils.py           # Utility functions (formatting, output)
│   ├── exceptions.py      # Custom exceptions
│   ├── py.typed           # PEP 561 marker
│   ├── api/               # REST API client (modular)
│   │   ├── __init__.py    # Package exports
│   │   ├── _http.py       # Base HTTP client (session, auth, retry)
│   │   ├── client.py      # MubanAPIClient facade
│   │   ├── templates.py   # Template operations
│   │   ├── users.py       # User management API
│   │   ├── audit.py       # Audit log operations
│   │   ├── admin.py       # Admin operations
│   │   └── async_ops.py   # Async job polling
│   ├── commands/          # Command modules
│   │   ├── __init__.py    # Common options decorator
│   │   ├── auth.py        # login, logout, whoami, refresh
│   │   ├── templates.py   # list, search, get, push, pull, delete
│   │   ├── generate.py    # generate documents (PDF/XLSX/DOCX/RTF/HTML/TXT)
│   │   ├── package.py     # package JRXML/DOCX templates
│   │   ├── async_ops.py   # async job management
│   │   ├── audit.py       # audit logs and monitoring
│   │   ├── admin.py       # admin operations
│   │   ├── users.py       # user management
│   │   ├── resources.py   # fonts, icc-profiles
│   │   └── settings.py    # configure, config-clear
│   └── gui/               # Graphical User Interface (optional)
│       ├── __init__.py
│       ├── main.py        # GUI entry point
│       ├── main_window.py # Main window with tab container
│       ├── error_dialog.py # Error dialog with copy support
│       ├── icons.py       # Icon generation helpers
│       ├── tabs/          # Tab widgets
│       │   ├── __init__.py
│       │   ├── package_tab.py     # Template packaging
│       │   ├── templates_tab.py   # Template browsing
│       │   ├── generate_tab.py    # Document generation
│       │   ├── server_info_tab.py # Server info & fonts
│       │   └── settings_tab.py    # Configuration
│       ├── dialogs/       # Dialog windows
│       │   ├── __init__.py
│       │   ├── data_editor_dialog.py    # JSON data editor
│       │   ├── export_options_dialog.py # PDF/HTML/TXT export options
│       │   ├── font_dialog.py          # Multi-face font config
│       │   └── upload_dialog.py        # Template upload
│       └── resources/     # Icons and images
│           └── logo.png
├── tests/                 # Test suite
│   ├── __init__.py
│   ├── conftest.py        # Test fixtures
│   ├── test_api.py
│   ├── test_auth.py
│   ├── test_cli_simple.py
│   ├── test_commands.py
│   ├── test_config.py
│   ├── test_exceptions.py
│   ├── test_gui.py        # GUI widget tests (pytest-qt)
│   ├── test_packager.py   # Packager tests
│   └── test_utils.py
├── docs/                  # Documentation & API spec
├── .gitlab-ci.yml         # CI/CD pipeline
├── pyproject.toml         # Project configuration
├── LICENSE                # MIT License
└── README.md              # This file
```

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Support

- Email: <contact@muban.me>
- Documentation: <https://muban.me/features.html>

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
