PaletteAI CLI
The paletteai CLI is a command-line tool for authoring and testing Definitions, inspecting Workload statuses, importing profile bundles downloaded from PaletteAI Studio, and building air-gapped mirror bundles. The CLI is useful for local development, CI/CD pipelines, and automation workflows.
Installation
Prebuilt binaries are available for multiple platforms and architectures. Choose the appropriate binary for your system.
macOS
At this time, the PaletteAI CLI binaries for macOS are not signed. Refer to Safely open apps on your Mac for instructions on trusting the PaletteAI binary.
- Intel (AMD64)
- Apple Silicon (ARM64)
curl --location --output paletteai https://docs.palette-ai.com/resources/assets/hosted/cli/darwin/amd64/paletteai
chmod +x paletteai
sudo mv paletteai /usr/local/bin/
curl --location --output paletteai https://docs.palette-ai.com/resources/assets/hosted/cli/darwin/arm64/paletteai
chmod +x paletteai
sudo mv paletteai /usr/local/bin/
Linux
- AMD64
- ARM64
curl --location --output paletteai https://docs.palette-ai.com/resources/assets/hosted/cli/linux/amd64/paletteai
chmod +x paletteai
sudo mv paletteai /usr/local/bin/
curl --location --output paletteai https://docs.palette-ai.com/resources/assets/hosted/cli/linux/arm64/paletteai
chmod +x paletteai
sudo mv paletteai /usr/local/bin/
Windows
- AMD64
- ARM64
Invoke-WebRequest -Uri "https://docs.palette-ai.com/resources/assets/hosted/cli/windows/amd64/paletteai.exe" -OutFile "paletteai.exe"
Once downloaded, move the paletteai.exe binary either to a directory in your $PATH (for example, C:\Windows\System32) or add the current directory where it was downloaded to your $PATH.
Invoke-WebRequest -Uri "https://docs.palette-ai.com/resources/assets/hosted/cli/windows/arm64/paletteai.exe" -OutFile "paletteai.exe"
Once downloaded, move the paletteai.exe binary either to a directory in your $PATH (for example, C:\Windows\System32) or add the current directory where it was downloaded to your $PATH.
RC Builds
RC builds are pre-release versions intended for testing upcoming features. They may contain bugs or breaking changes and are not recommended for production use.
RC builds are published alongside each release candidate and are available for the same platforms as stable releases. Replace paletteai with paletteai-rc in the filename if you want to keep both versions side by side.
macOS
RC binaries for macOS are unsigned. Refer to Safely open apps on your Mac for instructions on trusting the binary.
- Intel (AMD64)
- Apple Silicon (ARM64)
curl --location --output paletteai https://docs.palette-ai.com/resources/assets/hosted/cli/darwin/amd64/paletteai?version=rc
chmod +x paletteai
sudo mv paletteai /usr/local/bin/
curl --location --output paletteai https://docs.palette-ai.com/resources/assets/hosted/cli/darwin/arm64/paletteai?version=rc
chmod +x paletteai
sudo mv paletteai /usr/local/bin/
Linux
- AMD64
- ARM64
curl --location --output paletteai https://docs.palette-ai.com/resources/assets/hosted/cli/linux/amd64/paletteai?version=rc
chmod +x paletteai
sudo mv paletteai /usr/local/bin/
curl --location --output paletteai https://docs.palette-ai.com/resources/assets/hosted/cli/linux/arm64/paletteai?version=rc
chmod +x paletteai
sudo mv paletteai /usr/local/bin/
Windows
- AMD64
- ARM64
Invoke-WebRequest -Uri "https://docs.palette-ai.com/resources/assets/hosted/cli/windows/amd64/paletteai.exe?version=rc" -OutFile "paletteai.exe"
Once downloaded, move the paletteai.exe binary either to a directory in your $PATH (for example, C:\Windows\System32) or add the current directory where it was downloaded to your $PATH.
Invoke-WebRequest -Uri "https://docs.palette-ai.com/resources/assets/hosted/cli/windows/arm64/paletteai.exe?version=rc" -OutFile "paletteai.exe"
Once downloaded, move the paletteai.exe binary either to a directory in your $PATH (for example, C:\Windows\System32) or add the current directory where it was downloaded to your $PATH.
Verification
Use the command paletteai --help to verify the CLI was installed.
paletteai --help
Usage:
paletteai [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
convert-crd Convert a CRD to a CUE template
def Manage Definitions
dry-run Dry Run a Workload and output the resulting K8s resources to stdout
export Export CUE template parameters to OpenAPI v3 schema
help Help about any command
mirror Mirror Profile Bundle content from source registries to air-gapped OCI registry (export, push, or sync)
status Displays the status of each subresource of one or more workloads
studio Manage Palette artifact studio artifacts
Flags:
-h, --help help for paletteai
--log-format string Log output format (text or json) (default "text")
-v, --verbosity int Log verbosity level (0-10, where 0 is least verbose)
Use "paletteai [command] --help" for more information about a command.
Updates
The CLI binaries are automatically updated with each PaletteAI release. To get the latest version, download it and replace your existing binary using the Installation instructions.
Global Flags
The following flags are available on all commands.
| Flag | Default | Required | Description |
|---|---|---|---|
-h | --help | N/A | ❌ | Display help for any command. |
--log-format | text | ❌ | Log output format. Accepted values: text, json. |
-v | --verbosity | 0 | ❌ | Log verbosity level (0-10, where 0 is least verbose). |
Commands
convert-crd
Convert a Kubernetes Custom Resource Definition (CRD) to a PaletteAI CUE template. The generated template includes template and parameter blocks derived from the CRD's OpenAPI v3 schema, providing a starting point for authoring PaletteAI Definitions from existing CRDs.
Flags
| Flag | Default | Required | Description |
|---|---|---|---|
-f | --file | N/A | ✅ | Path to the input CRD YAML file. |
-o | --output | N/A | ❌ | Output CUE template file path. If omitted, the template prints to stdout. |
--version | N/A | ❌ | CRD version to convert. If omitted, uses the first version in the CRD. |
Examples
# Convert a CRD and print to stdout
paletteai convert-crd --file /path/to/crd.yaml
# Convert a CRD and save to a file
paletteai convert-crd --file /path/to/crd.yaml --output /path/to/output.cue
# Convert a specific CRD version
paletteai convert-crd --file /path/to/crd.yaml --version v1alpha1
def
Utility commands for working with PaletteAI Definitions.
def render
Render a CUE-formatted Definition into Kubernetes YAML or JSON. Use this command to validate that a CUE Definition produces the expected Kubernetes manifests. If a directory is provided as input, all CUE Definitions in the directory are rendered.
Flags
| Flag | Default | Required | Description |
|---|---|---|---|
--format | yaml | ❌ | Output format. Accepted values: yaml, json. |
--message | N/A | ❌ | Header comment for the top of the rendered Definition. If empty, uses a default message. |
-o | --output | N/A | ❌ | Output file path. If empty, prints to stdout. If input is a directory, the output path must be a directory as well. |
--version | N/A | ❌ | Version string to set in the rendered Definition's spec.version. |
Examples
# Render a CUE Definition to stdout
paletteai def render my-webservice.cue
# Render to a file
paletteai def render my-webservice.cue --output my-webservice.yaml
# Render all CUE Definitions in a directory to another directory
paletteai def render ./defs/cue/ --output ./defs/yaml/
# Render as JSON
paletteai def render my-webservice.cue --format json
dry-run
Dry-run a Workload locally and output the resulting Kubernetes resources to stdout. This renders a Workload using its referenced Definitions without applying anything to a cluster.
By default, the command connects to the cluster (via kubeconfig) to read feature flags. Use --offline to skip cluster connectivity and all validation steps.
Flags
| Flag | Default | Required | Description |
|---|---|---|---|
--debug | false | ❌ | Enable debug mode. When enabled, raw output is printed on manifest errors. |
-d | --definition | N/A | ✅ | Path to a Definition file or a directory containing Definition files. |
-f | --file | workload.yaml | ✅ | Path to the Workload YAML file. |
--k8s-minor-version | 32 | ❌ | Kubernetes minor version to target when rendering resources. |
-n | --workload-namespace | default | ❌ | Namespace for the Workload. |
--offline | false | ❌ | Run in offline/local mode. All cluster validation steps are skipped. |
-x | --definition-namespace | mural-system | ❌ | Namespace to load Definitions from. |
Examples
# Dry-run a Workload with a Definition directory
paletteai dry-run --definition ./definitions/ --file ./workload.yaml
# Dry-run in offline mode (no cluster connection needed)
paletteai dry-run --definition ./definitions/ --file ./workload.yaml --offline
# Dry-run with a custom namespace
paletteai dry-run --definition ./definitions/ --file ./workload.yaml --workload-namespace my-namespace
mirror
Produces an air-gapped content bundle from a Helm chart, or from a Palette Pack tarball that contains values.yaml with pack.content charts and images. "Mirroring" refers to rendering templates with the Helm v3 API (for chart-based export), collecting container images, and optionally pushing charts, images, and—when applicable—the pack archive to an OCI registry.
Many Palette packs can be downloaded from Artifact Studio. If every pack your deployment needs is available there, you do not need mirror export-pack for pack acquisition. If you require a pack that is not available in Artifact Studio, obtain a Pack tarball from your Spectro Cloud representative and use mirror export-pack on a connected host, then mirror push toward your air-gapped registry, so the pack file and its declared dependencies are uploaded together.
Use a two-phase workflow when the connected host cannot reach the destination registry: use mirror export or mirror export-pack to generate a content bundle, move the bundle across the air-gap, and then use mirror push.
Use mirror sync on a host that can reach both upstream chart and image registries and the destination OCI registry. mirror sync does not accept a Pack tarball; for pack inputs you must run mirror export-pack and then mirror push.
HTTP(S) proxy
All mirror commands use the standard Go net/http transport behavior. Outbound HTTP and HTTPS requests honor the following proxy environment variables: HTTP_PROXY, HTTPS_PROXY, and NO_PROXY (and lowercase variants such as http_proxy), as documented for net/http.ProxyFromEnvironment. This applies to all Helm chart pulls, container image pulls/pushes, and OCI chart pushes.
mirror export
Arguments: BUNDLE_DIR — output directory for the bundle (must not already contain bundle.json).
Renders the chart, writes the pack.yaml and bundle.json files, pulls each referenced image into an OCI image layout directory under the images/ directory (preserving multi-architecture indexes), and pulls the .tgz chart archive. It does not require the --dest-registry flag.
| Flag | Shorthand | Default | Required | Description |
|---|---|---|---|---|
--chart-url | -c | N/A | ✅ | Helm chart reference (oci://… or reponame/chart with --repo-url). |
--chart-version | -V | N/A | ❌ | Chart version (required for classic repo charts when the version is not in the URL). |
--repo-url | N/A | ❌ | Classic Helm repository index URL (same idea as helm --repo). | |
--repo-username | N/A | ❌ | Username for --repo-url or for the oci:// chart registry. | |
--repo-password | N/A | ❌ | Password for --repo-url or oci:// chart (prefer env PALETTEAI_MIRROR_REPO_PASSWORD). | |
--repo-ca-cert | N/A | ❌ | CA certificate file or PEM directory for TLS to --repo-url or the oci:// chart registry. | |
--repo-insecure | false | ❌ | Skip TLS verification for --repo-url or the oci:// chart registry. | |
--repo-plain-http | false | ❌ | Use plain HTTP for the oci:// chart registry (no TLS; distinct from --repo-insecure). | |
--release-name | -r | N/A | ✅ | Helm release name used when templating. |
--kube-version | 1.31.0 | ❌ | Kubernetes version for offline helm template kubeVersion checks (must satisfy the chart’s Chart.yaml kubeVersion). | |
--values | -f | N/A | ❌ | Path to a values.yaml file for helm template. |
Examples
# Export a Helm chart from an OCI registry
paletteai mirror export ./my-bundle \
--chart-url oci://docker.io/myorg/my-chart:1.2.3 \
--release-name my-release
# Export a Helm chart from a classic Helm repository
paletteai mirror export ./my-bundle \
--repo-url https://charts.example.com/index.yaml \
--chart-url myvendor/my-chart \
--chart-version 2.0.0 \
--release-name my-release
mirror export-pack
Arguments: PACK_TAR — path to a Palette Pack archive (.tar, .tar.gz, .tgz, or similar). BUNDLE_DIR — output directory for the bundle (must not already contain bundle.json when writing a directory).
Reads the shallowest values.yaml inside the pack (by path depth); nested files with the same name (for example under chart subdirectories) are ignored. Uses pack.content.images and pack.content.charts to pull image artifacts and chart .tgz files into the same bundle layout as mirror export. Copies the source pack archive into spectro-packs/archive/ and records OCI name and tag in bundle.json by parsing the pack tarball filename: the stem must match <name>-<semver> (for example nvidia-gpu-operator-ai-25.10.1.tar.gz yields repository name nvidia-gpu-operator-ai and tag 25.10.1 on push). There are no CLI flags to override that mapping.
Does not use --dest-registry; run mirror push separately.
| Flag | Default | Required | Description |
|---|---|---|---|
--repo-username | N/A | ❌ | Username for oci:// chart registries listed in pack.content.charts. |
--repo-password | N/A | ❌ | Password for those registries (prefer env PALETTEAI_MIRROR_REPO_PASSWORD). |
--repo-ca-cert | N/A | ❌ | CA certificate file or PEM directory for TLS to oci:// chart registries. |
--repo-insecure | false | ❌ | Allow plain HTTP and skip TLS verification for oci:// chart registries. |
--archive | N/A | ❌ | Write the bundle directory tree as .tar, .tar.gz, or .tgz instead of a directory; BUNDLE_DIR names the top-level folder in the archive. |
Examples
# Build a bundle from a Pack tarball (directory output)
paletteai mirror export-pack ./nvidia-gpu-operator-ai-25.10.1.tar.gz ./my-bundle
# Same, wrapped as a single archive for transfer across an air-gap
paletteai mirror export-pack ./nvidia-gpu-operator-ai-25.10.1.tar.gz ./my-bundle \
--archive /tmp/my-bundle.tar.gz
mirror push
Arguments: BUNDLE — directory produced by mirror export or mirror export-pack, or a .tar / .tar.gz / .tgz archive from --archive. Archives are extracted to a temporary directory for the duration of the command.
Loads saved image artifacts (OCI layout directories) and pushes them to --dest-registry, pushes each chart to OCI (oci://<dest>/charts/<chart>), and if bundle.json includes packArchive, pushes the Palette Pack tarball as an OCI artifact to <dest-registry>/spectro-packs/archive/<name>:<tag> using the name and tag in the manifest (derived from the original pack filename). Pass --skip-pack-archive to push only images and charts (not the pack tarball). Only the destination registry must be reachable.
| Flag | Shorthand | Default | Required | Description |
|---|---|---|---|---|
--dest-registry | -d | N/A | ✅ | Destination registry prefix (host:port/path). |
--dest-username | N/A | ❌ | Registry username (basic auth). | |
--dest-password | N/A | ❌ | Registry password (prefer env PALETTEAI_MIRROR_DEST_PASSWORD). | |
--dest-ca-cert | N/A | ❌ | PEM file or directory of PEM/CRT/CER for destination TLS trust. | |
--dest-insecure | false | ❌ | Skip TLS verification for the destination registry. | |
--dest-plain-http | false | ❌ | Use plain HTTP for the destination registry (no TLS; distinct from --dest-insecure). | |
--skip-pack-archive | false | ❌ | Do not push the Palette pack tarball from bundle.json packArchive. Images and charts are still pushed. |
Examples
# Upload a content bundle produced via `mirror export` to an air-gapped OCI registry
paletteai mirror push ./my-bundle \
--dest-registry 10.0.0.1:30003/spectro-content \
--dest-insecure \
--dest-username admin
# Push images and charts only (skip the Palette pack tarball from export-pack)
paletteai mirror push ./my-bundle \
--dest-registry 10.0.0.1:30003/spectro-content \
--skip-pack-archive \
--dest-insecure \
--dest-username admin
mirror sync
Arguments: none (uses a temporary bundle directory that is deleted after the command).
Runs mirror export then mirror push in one process. Requires every flag needed for both phases: chart/source flags and --dest-registry. Does not accept a Pack tarball; use mirror export-pack then mirror push for pack-based bundles.
Examples
# Mirror a Helm chart from a classic Helm repository to an air-gapped OCI registry in one shot
paletteai mirror sync \
--chart-url clearml/clearml \
--chart-version 7.14.7 \
--release-name clearml \
--repo-url https://clearml.github.io/clearml-helm-charts \
--dest-registry 10.0.0.1:30003/spectro-content \
--dest-insecure \
--dest-username admin
Bundle layout (export / export-pack / sync)
After mirror export or mirror export-pack (or internally during mirror sync for chart-only export), the bundle directory contains:
bundle.json— manifest (chart metadata and image list; forexport-pack, alsopackArchivewith the bundle-relative path to the copied pack and the OCI name/tag used on push).pack.yaml— image and chart metadata for Palette.charts/— pulled Helm chart.tgzarchives (for chart-based export, one chart; forexport-pack, one entry perpack.content.chartsline).images/<n>/— one OCI image layout per image (multi-arch preserved).spectro-packs/archive/— present forexport-pack: copy of the source Pack tarball.
export
Export the parameter section of a CUE template to an OpenAPI v3 JSON schema. This is useful for generating schema documentation or validation artifacts from Definitions.
This is not the same as paletteai mirror export; the top-level export command only converts CUE parameters to OpenAPI.
Flags
| Flag | Default | Required | Description |
|---|---|---|---|
-o | --output | N/A | ❌ | Output file path. If empty, the schema is printed to stdout. If input is a directory, the output path is expected to be a directory as well. |
Examples
# Export a CUE template's parameters to stdout
paletteai export path/to/file.cue
# Export to a file
paletteai export path/to/file.cue --output path/to/output.json
status
Display the status of each subresource of one or more Workloads in a given namespace. The output includes component statuses, applied resources, policy statuses, and Definition outputs. Data is displayed in YAML format.
If both --workload-namespace and --workload-name are specified, data for only that Workload is shown. If --workload-name is omitted, data for all Workloads in the namespace is displayed.
Flags
| Flag | Default | Required | Description |
|---|---|---|---|
-a | --workload-name | N/A | ❌ | Name of a specific Workload. If omitted, all Workloads in the namespace are displayed. |
-n | --workload-namespace | default | ✅ | Namespace of the Workloads. |
Examples
# Show status for a specific Workload
paletteai status --workload-namespace nginx-demo --workload-name nginx-demo
# Show status for all Workloads in a namespace
paletteai status --workload-namespace my-namespace
studio
Manage artifacts downloaded from PaletteAI Studio.
studio import
Import artifacts downloaded from PaletteAI Studio into a Kubernetes cluster. Accepts either gzipped tar archives (.tar.gz) or plain directories as input. The command reads a profilebundle.yaml from the archive, parses its composition (infrastructure, application, or fullstack profiles), generates ProfileBundle and WorkloadProfile Kubernetes resources, and applies them to the cluster.
The command automatically detects the cluster's versioning type (basic or semantic) from the mural-feature-flags ConfigMap. When the cluster uses semantic versioning, the --app-version flag is required. When the cluster uses basic versioning, --app-version must not be provided.
Flags
| Flag | Default | Required | Description |
|---|---|---|---|
--namespace | N/A | ✅ | Target Kubernetes namespace for the imported resources. |
--registry-map | N/A | ❌ | Registry UID mappings in source:target format. Can be specified multiple times. Useful for airgap environments where registry UIDs differ from the original bundle. |
--app-version | N/A | ❌ | Application version to set in spec.version of WorkloadProfile and ProfileBundle resources. Required for clusters using semantic versioning. Do not use for basic versioning. |
--dry-run | false | ❌ | Preview the generated YAML resources without applying them to the cluster. |
Examples
# Import a .tar.gz bundle
paletteai studio import --namespace my-project ~/Downloads/clearml-7.14.7.tar.gz
# Import from an extracted directory
paletteai studio import --namespace my-project ~/Downloads/clearml-7.14.7/
# Preview the generated resources without applying
paletteai studio import --namespace my-project --dry-run ~/Downloads/clearml-7.14.7.tar.gz
# Import with registry UID remapping (e.g., for airgap)
paletteai studio import --namespace my-project --registry-map oldUID:newUID ~/Downloads/clearml-7.14.7.tar.gz
# Import with an explicit application version (semantic versioning clusters)
paletteai studio import --namespace my-project --app-version 1.2.0 ~/Downloads/clearml-7.14.7.tar.gz