Metadata-Version: 2.4
Name: virtualdojo
Version: 0.21.0
Summary: Command-line interface for VirtualDojo CRM
Project-URL: Homepage, https://github.com/Quote-ly/virtualdojo_cli
Project-URL: Documentation, https://github.com/Quote-ly/virtualdojo_cli#readme
Project-URL: Repository, https://github.com/Quote-ly/virtualdojo_cli
Project-URL: Issues, https://github.com/Quote-ly/virtualdojo_cli/issues
Author-email: VirtualDojo Team <support@virtualdojo.com>
License-Expression: MIT
License-File: LICENSE
Keywords: automation,cli,crm,salesforce-alternative,virtualdojo
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Groupware
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx>=0.25.0
Requires-Dist: keyring>=24.0.0
Requires-Dist: platformdirs>=4.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyyaml>=6.0.0
Requires-Dist: rich>=13.0.0
Requires-Dist: tomli-w>=1.0.0
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
Requires-Dist: typer[all]>=0.9.0
Provides-Extra: dev
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: respx>=0.20.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Description-Content-Type: text/markdown

# VirtualDojo CLI

Command-line interface for VirtualDojo CRM - interact with your CRM data, manage records, and automate workflows from the terminal.

## Features

- **Authentication**: Login with email/password or API keys
- **Record Management**: Full CRUD operations on any object
- **Bulk Operations**: Bulk create, update, delete, and upsert from CSV or JSON files
- **Search & Export**: Global full-text search and CSV/JSON export of records
- **Schema Discovery**: Explore objects, fields, and picklists
- **File Management**: Upload, download, and manage files with progress tracking
- **Multiple Profiles**: Manage connections to different servers/tenants
- **Rich Output**: Beautiful tables, JSON, and YAML formatting
- **Filter Support**: Powerful filtering with operators (contains, gte, ne, etc.)

## Installation

### From PyPI (recommended)

```bash
pip install virtualdojo
```

Or with [pipx](https://pypa.github.io/pipx/) (recommended for CLI tools):

```bash
pipx install virtualdojo
```

### From Source

```bash
git clone https://github.com/Quote-ly/virtualdojo_cli.git
cd virtualdojo_cli
pip install -e .
```

## Quick Start

### 1. Login

```bash
# Login to default production server (prompts for email, password)
vdojo login

# Login to local development server
vdojo login --local
vdojo login -l

# Login to specific server
vdojo login --server localhost:8000 --tenant my-tenant
vdojo login -s dev -t my-tenant

# Login with API key (for CI/CD - use environment variables!)
export VIRTUALDOJO_API_KEY=sk-abc123
export VIRTUALDOJO_TENANT=my-company
vdojo login
```

### 2. Check Connection

```bash
vdojo whoami
```

### 3. List Records

```bash
# List accounts
vdojo records list accounts

# List with filtering
vdojo records list opportunities --filter "stage_ne=closed,amount_gte=10000"

# Output as JSON
vdojo records list contacts --format json
```

## Commands

### Authentication

```bash
# Login (shortcuts available at top level)
vdojo login                                    # Default server, prompts for details
vdojo login --local                            # Local development (localhost:8000)
vdojo login -s dev -t my-tenant            # Dev server
vdojo login --server api.mycompany.com -t prod # Custom server

# Server shortcuts:
#   --local, -l          → http://localhost:8000
#   --server local       → http://localhost:8000
#   --server dev         → dev server
#   --server production  → production server

# Check current user
vdojo whoami

# Logout
vdojo logout

# Manage API keys
vdojo auth api-key list
vdojo auth api-key create --name "CI Pipeline" --expires 90
vdojo auth api-key revoke KEY_ID
```

### Records

```bash
# List records
vdojo records list accounts
vdojo records list accounts --limit 100 --filter "status=active"

# Get single record
vdojo records get accounts acc-123

# Create record
vdojo records create accounts --data '{"name": "Acme Corp"}'
vdojo records create tasks --set "name=Follow up" --set "status=pending"

# Update record
vdojo records update accounts acc-123 --set "status=active"

# Delete record
vdojo records delete accounts acc-123

# Count records
vdojo records count opportunities --filter "stage=negotiation"

# Search across objects (global full-text search)
vdojo records search "acme"
vdojo records search "john@example.com" --objects contacts,leads

# Export to CSV/JSON (paginates through all matches)
vdojo records export accounts --out accounts.csv
vdojo records export opportunities --filter "stage_ne=closed" --out open.json --format json
vdojo records export contacts --columns id,email,name --out contacts.csv

# Relational tree export/import (a record plus its related children)
vdojo records tree-export accounts --id acc-123 --out tree.json
vdojo records tree-export accounts --filter "industry=Tech" --children contacts,opportunities --out tree.json
vdojo records tree-import tree.json --profile other-tenant   # recreates + relinks children
```

#### Bulk operations

Pass a multi-row **CSV** or **JSON array** to `--file` and the command uses the
bulk endpoint. A single JSON object (or `--data`/`--set`) still operates on one
record, so existing usage is unchanged.

```bash
# Bulk create from a CSV (header row = field names) or JSON array
vdojo records create accounts --file accounts.csv
vdojo records create contacts --file contacts.json

# Bulk update — each row/object must include the record id
vdojo records update accounts --file updates.csv
vdojo records update accounts --file updates.json --id-field record_id

# Bulk delete — by id list or from a file of records/ids
vdojo records delete accounts --ids acc-1,acc-2,acc-3 --force
vdojo records delete accounts --file stale.csv --force

# Upsert — update existing rows, create the rest, matched on --external-id
vdojo records upsert accounts --file accounts.csv --external-id id
vdojo records upsert contacts --file contacts.csv --external-id email
```

Common options for the bulk paths:

- `--batch-size N` — records processed per batch
- `--stop-on-error` — abort the batch on the first failure (default: continue)
- `--errors-file errors.json` — write failed rows (with reasons) for re-submission

Bulk operations report a per-run summary and exit non-zero if any record fails.
Upsert has no native server endpoint: it looks up existing records by
`--external-id`, then issues a bulk update plus a bulk create. The match field
should be unique — rows matching more than one record are reported as errors.

### Schema

```bash
# List all objects
vdojo schema objects
vdojo schema objects --type custom  # Only custom objects

# Describe an object
vdojo schema describe accounts

# List fields
vdojo schema fields opportunities
vdojo schema fields contacts --required  # Only required fields

# View picklist values
vdojo schema picklists opportunities --field stage
```

#### Managing objects and fields (admin)

Create, update, and delete custom objects and fields directly via the API.
Field commands auto-route by object type: a custom object (`_co`) uses the
custom-object endpoint, anything else is treated as a standard object.

```bash
# Custom objects
vdojo schema create-object --label "Project"        # api_name derived from label
vdojo schema create-object --label "Invoice" --api-name invoice \
    --name-field-type autonumber --autonumber-format "INV-{0000}"
vdojo schema update-object project_co --label "Projects (2026)"
vdojo schema delete-object project_co

# Fields (on standard or custom objects)
vdojo schema create-field accounts --label "Region" --type picklist \
    --picklist "East,West,Central"
vdojo schema create-field project_co --label "Budget" --type currency --required
vdojo schema create-field accounts --label "Primary Contact" --type lookup \
    --lookup-object contacts
vdojo schema update-field accounts region_cf --label "Sales Region"
vdojo schema delete-field accounts region_cf
```

These commands require admin permissions (`manage_custom_objects` /
`manage_custom_fields`).

#### Export / import (config-as-code)

Export an object's definition (custom object + its fields, or a standard
object's custom fields) to a JSON file, and recreate it elsewhere — useful for
migrating schema between tenants.

```bash
# Export
vdojo schema export project_co --out project.json     # custom object + fields
vdojo schema export accounts --out account_fields.json # standard object's custom fields

# Import (into another tenant via --profile)
vdojo schema import project.json -p other-tenant
vdojo schema import project.json --api-name project_copy      # rename on import
vdojo schema import account_fields.json --into accounts -p other-tenant
```

### Open in browser

```bash
vdojo open                     # open the web app home
vdojo open accounts            # open the accounts list
vdojo open accounts acc-123    # open a specific record
vdojo open --path /admin/users # open an explicit path
vdojo open accounts --print    # print the URL instead of launching
```

### Shell completion

```bash
vdojo --install-completion   # install completion for your shell
vdojo --show-completion      # print the completion script
```

### Users, roles & usage (admin)

```bash
# Users
vdojo users list
vdojo users lookup jane
vdojo users create -e jane@acme.com --firstname Jane --lastname Doe
vdojo users update <id> --title "VP Sales"
vdojo users deactivate <id>

# Roles
vdojo roles list
vdojo roles create --name "Sales Manager"
vdojo roles assign-permission <role_id> <permission_id>

# Token usage & billing
vdojo usage tokens --by-user --from 2026-06-01 --to 2026-06-30
vdojo usage billing      # license/billing status
vdojo usage licenses     # license counts per package
vdojo usage history      # billing history
```

User/role management requires the corresponding admin permissions.

### Page layouts (export/import)

Export a page layout to a portable JSON file and recreate it in another tenant.
The layout structure references fields and related objects by api_name, so it
moves cleanly between tenants. (Layout *assignments* — which profile/record
type sees a layout — are tenant-specific and not included.)

```bash
vdojo layouts list accounts
vdojo layouts export accounts --out account_layout.json     # default layout
vdojo layouts export accounts --all --out account_layouts.json
vdojo layouts import account_layout.json --profile other-tenant
vdojo layouts import account_layout.json --into accounts --name "Imported" --default
```

Imported layouts are created non-default unless you pass `--default`.

### PDF templates (export/import)

Export PDF/document templates (the `configuration` blob — layout, components,
styles, and `{{merge.fields}}`) to a portable JSON file and recreate them in
another tenant. Object associations are by api_name, so templates move cleanly.
(Template *assignments* — defaults/conditions per object/profile — are
tenant-specific and not included.)

```bash
vdojo pdf list
vdojo pdf list --object quotes --status active
vdojo pdf export --name "Standard Quote" --out quote_pdf.json
vdojo pdf export --object quotes --out quote_templates.json
vdojo pdf export --all --out all_pdf_templates.json
vdojo pdf import quote_pdf.json --profile other-tenant
vdojo pdf import quote_pdf.json --name "Quote PDF (copy)" --status draft
```

Each template keeps its source status on import unless you pass `--status`.

### Data guardrails

Validation rules (formula-based, block on save) and duplicate rules (dedupe
detection) for an object. List/create them, and export/import a portable bundle
of both types between tenants.

```bash
vdojo guardrails list accounts
vdojo guardrails create-validation accounts --name "Amount required" \
    --formula "ISBLANK({amount})" --error-message "Amount is required"
vdojo guardrails create-duplicate accounts --name "Dupe email" \
    --match email:exact --match name:fuzzy --action allow_warning

# Migration (both rule types in one file)
vdojo guardrails export accounts --out accounts_guardrails.json
vdojo guardrails import accounts_guardrails.json --into contacts

# Show the file format for import (ready to edit)
vdojo guardrails template --out guardrails.sample.json
```

### DojoScript (server-side code)

Manage server-side DojoScript classes (Python automation), their tests and
triggers, and execute/inspect them — the VirtualDojo equivalent of Apex.

```bash
# Classes
vdojo dojoscript classes list [--type standard] [--active]
vdojo dojoscript classes create --name MyClass --type standard --file my_class.py
vdojo dojoscript classes compile --file my_class.py --type standard   # dry-run
vdojo dojoscript classes activate <id>      # requires compiled + tests passed

# Run + logs
vdojo dojoscript run <api_name> --params '{"x": 1}'
vdojo dojoscript executions <class_id>

# Tests
vdojo dojoscript tests create <class_id> --name "ok" --target-method execute \
    --expected success --data '{"params": {}}'
vdojo dojoscript tests run <class_id>

# Triggers (bind a trigger class to an object event)
vdojo dojoscript triggers create --class <id> --object accounts --event before_insert
```

### Flows (automation)

Read/create/update/list/delete automation flows, and migrate them between
tenants. A flow's definition (nodes/edges/variables) references objects and
fields by api_name, so it's portable; imported flows are created as drafts.

```bash
vdojo flows list [--status active] [--type record_trigger]
vdojo flows get <id>                       # full definition (JSON)
vdojo flows create --file flow.json [--name "Copy"]
vdojo flows update <id> --status active     # or --file to replace the definition
vdojo flows delete <id>

# Migration
vdojo flows export --name "Lead router" --out flow.json   # or --all
vdojo flows import flows.json --profile other-tenant
```

### Webhooks

Manage outbound webhook subscriptions and migrate their config between tenants.
Webhooks fire on record events (e.g. `record.created:accounts`). The signing
secret is shown only once at creation and can't be exported, so an import
issues a fresh secret per webhook.

```bash
vdojo webhooks list
vdojo webhooks events --object accounts          # valid --event values
vdojo webhooks create --url https://example.com/in \
    --event record.created:accounts --event record.updated:accounts
vdojo webhooks update <id> --status paused
vdojo webhooks delete <id>

# Migration (config only — no secrets)
vdojo webhooks export --out webhooks.json
vdojo webhooks import webhooks.json --secrets-out new_secrets.json
```

### Permission profiles

CRM permission profiles (Salesforce-style) — distinct from the CLI connection
profiles selected with `-p/--profile`.

```bash
vdojo permissions profiles list
vdojo permissions profiles create --name "Sales Rep"
vdojo permissions assign-user <profile_id> <user_id>

# Object-level permissions
vdojo permissions object-perms <profile_id>
vdojo permissions set-object <profile_id> accounts --crud
vdojo permissions set-object <profile_id> contacts --read --edit
```

### Files

```bash
# List files and folders
vdojo files list
vdojo files list --folder folder-123       # List folder contents
vdojo files list --type image              # Filter by type

# Get file info
vdojo files info file-123
vdojo files info file-123 --format json

# Upload files
vdojo files upload ./report.pdf                      # Upload to root
vdojo files upload ./report.pdf -f folder-123        # Upload to folder
vdojo files upload ./data/ --recursive               # Upload directory

# Download files
vdojo files download file-123                        # Download to current dir
vdojo files download file-123 -o ./downloads/        # Download to directory
vdojo files download file-123 -o ./report.pdf        # Download with name

# Delete files
vdojo files delete file-123
vdojo files delete folder-456 --force

# Create folders
vdojo files mkdir "New Folder"
vdojo files mkdir "Reports" --parent folder-123

# Move, rename, copy
vdojo files move file-123 --to folder-456
vdojo files rename file-123 --name "new-name.pdf"
vdojo files copy file-123 --to folder-456

# Share files
vdojo files share file-123 --public                  # Generate public link
vdojo files share file-123 --user user-456           # Share with user
vdojo files share file-123 --user user-456 --permission edit
vdojo files unshare file-123 --user user-456
vdojo files shares file-123                          # List shares

# Link files to records
vdojo files link file-123 --object accounts --record acc-456
vdojo files unlink file-123 --link link-789
vdojo files links file-123                           # List links

# Search files
vdojo files search "quarterly report"
vdojo files search "report" --type document --created-after 2024-01-01

# Storage info
vdojo files storage
```

### Configuration

```bash
# Show current config
vdojo config show

# Manage profiles
vdojo config profile list
vdojo config profile add dev --server https://dev.virtualdojo.com --tenant test
vdojo config profile use dev
vdojo config profile remove old-profile

# Change settings
vdojo config set default_limit 100
vdojo config set output_format json
```

## Filter Operators

When using `--filter`, you can use these operators:

| Operator | Description | Example |
|----------|-------------|---------|
| (none) | Equals | `status=active` |
| `_ne` | Not equals | `stage_ne=closed` |
| `_gt` | Greater than | `amount_gt=10000` |
| `_gte` | Greater than or equal | `amount_gte=10000` |
| `_lt` | Less than | `amount_lt=1000` |
| `_lte` | Less than or equal | `amount_lte=1000` |
| `_contains` | Contains text | `name_contains=Acme` |
| `_startswith` | Starts with | `name_startswith=A` |
| `_endswith` | Ends with | `email_endswith=@corp.com` |
| `_in` | In list | `status_in=active\|pending` or `status_in="active,pending"` |
| `_isnull` | Is null | `email_isnull=true` |

Combine multiple filters with commas:

```bash
vdojo records list opportunities --filter "stage_ne=closed,amount_gte=10000,owner_contains=john"
```

## Output Formats

All commands support multiple output formats:

```bash
# Table (default) - human-readable
vdojo records list accounts

# JSON - machine-readable
vdojo records list accounts --format json

# YAML - configuration-friendly
vdojo records list accounts --format yaml
```

## Multiple Profiles

Manage connections to different environments:

```bash
# Add profiles
vdojo config profile add production --server https://api.virtualdojo.com --tenant prod
vdojo config profile add dev --server https://dev.virtualdojo.com --tenant dev
vdojo config profile add local --server http://localhost:8000 --tenant dev

# Switch default profile
vdojo config profile use production

# Use a specific profile for one command
vdojo records list accounts --profile dev
```

## Configuration

Configuration is stored in:
- **Linux/macOS**: `~/.config/virtualdojo/config.toml`
- **Windows**: `%APPDATA%\virtualdojo\config.toml`

Credentials are stored separately with restricted permissions:
- **Linux/macOS**: `~/.config/virtualdojo/credentials.toml`
- **Windows**: `%APPDATA%\virtualdojo\credentials.toml`

## Security

### Credential Storage

The CLI stores authentication tokens securely:

1. **System Keyring (Recommended)**: When available, tokens are stored in your operating system's secure credential storage:
   - **macOS**: Keychain
   - **Linux**: Secret Service (GNOME Keyring, KWallet)
   - **Windows**: Windows Credential Manager

2. **Fallback File Storage**: If no system keyring is available, tokens are stored in `credentials.toml` with restricted file permissions (`0600` - owner read/write only).

**Recommendations:**
- Use full-disk encryption on your machine
- On shared systems, ensure your home directory is not accessible to other users
- Regularly rotate API keys via `vdojo auth api-key create` / `vdojo auth api-key revoke`

### Environment Variables for CI/CD

For automated workflows, use environment variables instead of command-line arguments to avoid exposing credentials in shell history and process listings:

```bash
# Set credentials via environment (secure)
export VIRTUALDOJO_API_KEY=sk-your-api-key
export VIRTUALDOJO_TENANT=your-tenant-id
export VIRTUALDOJO_SERVER=https://api.virtualdojo.com

# Run commands without exposing secrets
vdojo login
vdojo records list accounts
```

Available environment variables:
| Variable | Description |
|----------|-------------|
| `VIRTUALDOJO_API_KEY` | API key for authentication |
| `VIRTUALDOJO_PASSWORD` | Password (for non-interactive login) |
| `VIRTUALDOJO_EMAIL` | Email address |
| `VIRTUALDOJO_TENANT` | Tenant ID or subdomain |
| `VIRTUALDOJO_SERVER` | Server URL |

### HTTPS Connections

The CLI uses HTTPS by default for all production connections. When connecting to HTTP endpoints (like `localhost` for development), a warning is displayed:

```
! Using insecure HTTP connection to http://localhost:8000.
  Credentials will be transmitted in plaintext.
```

**Never use HTTP for production environments.**

### Security Best Practices

1. **Use API keys for automation** - Create dedicated API keys with expiration for CI/CD pipelines
2. **Don't commit credentials** - Never commit `.env` files or credentials to version control
3. **Rotate credentials** - Regularly rotate API keys, especially after team member departures
4. **Use environment variables** - Prefer `VIRTUALDOJO_API_KEY` over `--api-key` in scripts
5. **Audit access** - Review API key usage via `vdojo auth api-key list`

## Development

### Setup

```bash
# Clone repository
git clone https://github.com/Quote-ly/virtualdojo_cli.git
cd virtualdojo_cli

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

# Run tests
pytest

# Run linting
ruff check src/
black --check src/
```

### Running Locally

```bash
# Run CLI directly
python -m virtualdojo --help

# Or after installing
vdojo --help
```

## Requirements

- Python 3.10+
- A VirtualDojo CRM instance to connect to

## Changelog

### v0.4.0 (2025-12-03)

**New Features:**
- File uploads now automatically generate AI embeddings by default
  - Uploaded files are processed for vector search and AI capabilities
  - Use `--no-embeddings` flag to skip AI processing for large binary files
  - Example: `vdojo files upload ./report.pdf` (with embeddings)
  - Example: `vdojo files upload ./large.zip --no-embeddings` (skip processing)

### v0.3.0 (2025-12-03)

**Bug Fixes:**
- Fixed `_in` and `_not_in` filter operators not handling multiple values correctly ([#1](https://github.com/Quote-ly/virtualdojo_cli/issues/1))
  - Now supports pipe delimiter: `name_in=VENDORS|DISTRIBUTORS|RESELLERS`
  - Now supports quoted commas: `name_in="VENDORS,DISTRIBUTORS,RESELLERS"`

**Improvements:**
- File downloads now use secure streaming endpoint (`/stream`) instead of presigned URLs
  - Downloads are authenticated on every request
  - No shareable URLs that could be leaked
  - Works correctly with MinIO in Docker environments

### v0.2.0 (2025-12-02)

- Initial public release
- Authentication with email/password and API keys
- Full CRUD operations on all CRM objects
- Schema discovery and exploration
- File management with progress tracking
- Multiple profile support
- Rich terminal output

## License

MIT License - see [LICENSE](LICENSE) file.

## Links

- [VirtualDojo CRM](https://virtualdojo.com)
- [API Documentation](https://docs.virtualdojo.com)
- [Issue Tracker](https://github.com/Quote-ly/virtualdojo_cli/issues)
