Skip to main content

A command line interface for initializing, packaging, and deploying Custom Apps to the Virtualitics AI Platform from a local development environment.

Project description

Virtualitics AI Platform CLI

A command line interface for initializing, packaging, and deploying Custom Apps to the Virtualitics AI Platform (VAIP) from a local development environment.

Installation

pip install virtualitics-cli

Requires Python >= 3.14.

Quick Start

vaip config                          # Configure connection to a VAIP instance
vaip init -n my_app -d "My app" -y   # Scaffold a new VAIP app
cd my_app
vaip build                           # Build a wheel
vaip deploy                          # Deploy to the VAIP instance

Versioning

This project follows PEP 440 and is versioned independently from the Virtualitics AI Platform. Patch versions bump on bug fixes and small improvements; minor and major bumps are for feature releases and breaking changes respectively.

Compatible with VAIP 1.65+.

What's New

2.0.2

  • Public-facing release hygiene — sdist trimmed to ship only what end-users need; example hostnames in docs are now generic placeholders.

2.0.1

  • Bundled Claude Code skill — Run vaip skill install to give Claude Code the ability to drive vaip for you.
  • Agent-friendly CLI surface — Canonical --json envelope ({status, code, message, data}) on every command, granular exit codes (0 ok, 2 config, 3 validation, 4 network, 5 auth, 6 not-found, 7 backend error), --json support added to use-context / delete-context / edit-context, edit-context non-interactive via --host/--token/--username flags, destroy --yes is a real flag (no prompt).
  • vaip status improvements — Human-readable text output (was raw JSON); --json output unchanged.
  • vaip init scaffold fix — Generated App(name=...) now uses the snake_case --project-name so the produced app passes backend validation regardless of what's in --description.

2.0.0

  • Redesigned vaip init — Scaffolds a working two-step app (CSV upload → results dashboard with table and chart), ready to build and deploy immediately.
  • New vaip validate command — Pre-flight checks for pyproject.toml, package structure, Python syntax, and App/Flow definitions before building.
  • Structured JSON output — Global --json flag on all commands for scripting and agent consumption.
  • Fully non-interactive vaip config — Provide all flags (-N, -H, -T, -U) to skip prompts; use --yes to accept stored defaults.
  • Independent versioning — CLI versions are no longer coupled to VAIP platform versions.

Usage

$ vaip [OPTIONS] COMMAND [ARGS]...

Options:

  • --version
  • --verbose / --no-verbose: [default: no-verbose]
  • --json: Emit JSON output for programmatic/agent consumption
  • --install-completion: Install completion for the current shell.
  • --show-completion: Show completion for the current shell, to copy it or customize the installation.
  • --help: Show this message and exit.

Commands

vaip config

Create or update a configuration file for connecting to a VAIP instance. Requires a friendly name, host URL, API token, and username. Supports multiple named contexts.

$ vaip config [OPTIONS]
  • -N, --name TEXT: Friendly name for the VAIP instance (e.g., my-vaip) [required]
  • -H, --host TEXT: Backend hostname (e.g., https://your-vaip-instance.example.com) [required]
  • -T, --token TEXT: API token for authentication
  • -U, --username TEXT: Username associated with API token
  • -y, --yes: Accept default token/username without prompting

vaip use-context

Switch the active context for deployment.

$ vaip use-context CONTEXT_NAME

vaip show-context

Display the current configuration file.

$ vaip show-context

vaip delete-context

Delete a specific context from the configuration file.

$ vaip delete-context CONTEXT_NAME

vaip edit-context

Modify a specific context in the configuration file.

$ vaip edit-context CONTEXT_NAME

vaip init

Scaffold a new VAIP app with a working two-step example (CSV upload + results dashboard). All parameters can be provided as flags for fully non-interactive usage.

$ vaip init [OPTIONS]
  • -n, --project-name TEXT: Project name, snake_case only [required, prompted if omitted]
  • -d, --description TEXT: App description [required, prompted if omitted]
  • -v, --version TEXT: App version [default: 0.1.0]
  • -a, --authors TEXT: Author name [default: git user.name]
  • -y, --yes: Skip confirmation prompt

vaip validate

Validate a VAIP app project before building. Checks pyproject.toml, package structure, Python syntax, and App/Flow definition.

$ vaip validate

vaip status

Check connection to the configured VAIP instance and list installed modules.

$ vaip status

vaip build

Build a Python wheel file from the pyproject.toml in the current directory.

$ vaip build

vaip deploy

Deploy the VAIP App wheel to the configured VAIP instance.

$ vaip deploy [OPTIONS]
  • -f, --file TEXT: Path to the wheel file (defaults to ./dist/*.whl)

vaip destroy

Delete a VAIP module and all its apps from the instance.

$ vaip destroy [OPTIONS]
  • -n, --project-name TEXT: Project name to delete [required]
  • -y, --yes: Confirm deletion [required]

vaip publish

Publish a VAIP App to other users in your organization. (Not currently implemented.)

$ vaip publish

vaip skill install

Install the bundled Claude Code skill so an AI agent (e.g. Claude Code) can drive vaip end-to-end via a structured contract. The skill ships with the wheel and gets copied to ~/.claude/skills/vaip/SKILL.md on install.

$ vaip skill install [OPTIONS]
  • -d, --dest PATH: Override install path (defaults to ~/.claude/skills/vaip/SKILL.md)
  • -f, --force: Overwrite an existing SKILL.md if present

Once installed, Claude Code's Skill tool sees the vaip skill and can scaffold, validate, build, deploy, and manage VAIP apps using the canonical --json envelope and granular exit codes.


Changelog

2.0.1

CI/CD

  • Replace weekly cron with manual rollover, add GH App token + auto release notes
    • Drop cron schedule; manual workflow_dispatch only (releases are infrequent)
    • Drop publish-outgoing job; PyPI publish stays separate via build-and-publish.yml
    • Add actions/create-github-app-token@v2 for default-branch flip perms
    • Add gh release create --generate-notes --latest for outgoing version
    • Make tag/release/branch creation idempotent for safe re-runs
    • Rename file weekly-rollover.yml -> release-rollover.yml since cron is gone

Other

  • Bundle Claude Code skill + vaip skill install subcommand
    • Bundle Claude Code skill + vaip skill install Ship a SKILL.md inside the wheel at virtualitics_cli/skill/SKILL.md and add a vaip skill install subcommand that copies it into ~/.claude/skills/vaip/SKILL.md (or --dest
    • Fix test_verbose_flag exit-code assertion for new error codes show-context with no config now returns EXIT_CONFIG_ERROR (2), not generic 1, so the (0, 1) assertion fails on CI where there's no config. Update to (EXIT_OK, EXIT_CONFIG_ERROR).
    • Document vaip skill install in READMEs Add a section under Commands and a What's New bullet so users discover the bundled Claude Code skill that ships with 2.0.1+. Mirror the same change in README_PYPI.md (the user-facing PyPI README).
    • Address review feedback on bundled skill PR
    • skill install: drop redundant Path() cast (dest is already Optional[Path]).
    • skill install: include data={"bundled": str(bundled)} on the bundled-not-found error path for consistency with the other _error_exit calls in the same function.
    • skill install: wrap target.parent.mkdir in try/except → _error_exit so passing --dest with a regular-file path component yields a clean envelope instead of a Python NotADirectoryError traceback.
    • SKILL.md: warn agents loud-and-clear that show-context's data includes bearer tokens at data..token — do not echo verbatim.
    • SKILL.md: drop the "VAIP ≤ 1.65" version-claim wording around the lru_cache and empty-backend bugs. The lru_cache fix is not in flight (tell users to restart the backend container); the empty-store one is the same situation. Skill should not assert version-bound fixes it can't guarantee. Adds test_skill_install_parent_is_file covering the new mkdir-failure path. 113 tests pass; ruff clean.

  • Make CLI agent-friendly: --json everywhere, granular exit codes, non-interactive flags
    • Make CLI agent-friendly: --json everywhere, granular exit codes, non-interactive flags Audit of vaip 2.0.x for use as a Claude skill surfaced several blockers for agent-driven invocation. This consolidates the fixes. Canonical --json envelope All commands now emit {status, code, message, data} when --json is set. Backend payloads (deploy/destroy/publish/status) are nested under "data" rather than spread at the top level (which used to vary per command). This is the only intentionally-breaking change for agents that may have parsed .0.1 --json output. Granular exit codes EXIT_OK=0, EXIT_GENERIC=1, EXIT_CONFIG_ERROR=2, EXIT_VALIDATION_ERROR=3, EXIT_NETWORK_ERROR=4, EXIT_AUTH_ERROR=5, EXIT_NOT_FOUND=6, EXIT_BACKEND_ERROR=7. Network errors (timeout/refused) and HTTP 4xx/5xx from the backend now map to specific codes so agents can branch. use-context, delete-context, edit-context support --json These three commands previously had no --json mode at all. Now they emit the canonical envelope with relevant data (current_context, deleted name
    • dangling-warning flag, updated_fields list, etc.). edit-context goes non-interactive Adds --host/-H, --token/-T, --username/-U flags. Pass any combination to update those fields in one shot. Without flags + text mode, falls back to the legacy interactive prompt. With --json, at least one flag is required (no prompts in JSON mode). destroy --yes is a real flag Was marked required with prompt=True, so even in --json mode it would prompt for a y/n response. Now defaults to False; the command refuses with EXIT_VALIDATION_ERROR if --yes is omitted. Project name still prompts in text mode if --project-name not provided. deploy is more deterministic Wheel resolution sorts dist/*.whl lexicographically and picks the last match (previously: next() over an unordered glob). Warns in text mode when multiple wheels exist. Pass --file to disambiguate. get_current_context cleans up Replaced ad-hoc print + raise with _error_exit calls so config errors now go through the canonical envelope in --json mode. Tests All 107 tests pass. Test assertions updated to reference the new exit code constants. Added new tests covering the JSON envelope shape on use-context / delete-context / edit-context, the --field-flag path on edit-context, and the JSON-mode-requires-flag guard.
    • Update virtualitics_cli/virtualitics_cli.py

  • Refresh CLAUDE.md and exclude from PyPI sdist Update CLAUDE.md to reflect current CLI state:
    • Add validate and status commands to CLI Commands table
    • Document global --json flag in Common Commands section
    • Add JSON envelope details to Key Patterns (note schema variance by command) Exclude CLAUDE.md from PyPI sdist via hatchling config. File is dev-only documentation for Claude Code; shouldn't ship to users. Wheel already excludes it (not in package dir). Part of agent-friendliness audit. CLAUDE.md remains git-tracked for dev use.
  • Use json.loads(r.text) in status to match existing test mocks #27 introduced r.json() in the status text path; existing test mocks set mock_response.text = json.dumps(...) but not mock_response.json, so the mock returned a MagicMock (causing test_status_success to fail on master). Switch to json.loads(r.text) — matches print_response pattern and the existing tests pass without mock changes.
  • Fix init scaffold App name + status text-mode formatting
    • init scaffold's app.py.template was setting App(name="$description"), which produces an unvalidated name. The backend strips spaces and rejects dots, digits, and most punctuation, so any app description with those characters fails to register on deploy. Switch to App(name="$project_name") — project_name is already snake_case- validated by app_name_callback in vaip init -n.
    • status text mode previously dumped raw JSON via print_response. Add a small human-readable summary (host/org/installed modules) and leave --json output untouched. Surfaced during 2.0.1 smoke test against backend 1.65.0; verified locally end-to-end (init -> build -> deploy -> status -> destroy).

1.54.1

Other

  • Handle HTTP timeouts and non-JSON responses gracefully
    • Catch requests.exceptions.Timeout in deploy, destroy, and publish with a helpful message suggesting the operation may still be processing
    • Add print_response() helper that gracefully handles non-JSON server responses (HTML error pages, plain text) instead of crashing
    • Check r.ok for xx status codes before attempting to parse response
    • Add error handling to publish (previously had no try/except at all)
    • Add 7 new tests: deploy timeout, deploy server error, deploy non-JSON success, destroy timeout, publish timeout, publish connection error, publish server error
  • Remove stale TODOs, auto-convert hyphens in destroy, improve 404 message
    • Remove 8 stale TODO comments (pipx, blueprint docs, setuptools-scm, vaip-init detection, authors list)
    • Auto-convert hyphens to underscores in destroy project_name so users can copy the name directly from pyproject.toml
    • Improve destroy 404 error to mention the project name may not exist
    • Add test for hyphen-to-underscore conversion
  • [SECURITY] - Update dependencies to resolve CVEs.
  • Update version to 1.38.0

1.37.0

Other

  • Update deps

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

virtualitics_cli-2.0.3-py3-none-any.whl (26.7 kB view details)

Uploaded Python 3

File details

Details for the file virtualitics_cli-2.0.3-py3-none-any.whl.

File metadata

  • Download URL: virtualitics_cli-2.0.3-py3-none-any.whl
  • Upload date:
  • Size: 26.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"20.04","id":"focal","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for virtualitics_cli-2.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 98cb44b4096e6344df96541dce2ef44ae0b519f85febae09ea62682eb76e9db4
MD5 fa4613965e6d3e309a9d951d5cfe23df
BLAKE2b-256 5c1b1b4c7ff96f66623d5389c0a99527fab4e51d9ee2fca98143e7c4f13d31dc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page