zhi provides a subcommand-based CLI for all operations. Pass --help to any command for usage details.
| Flag | Description |
|---|---|
--workspace |
Path to workspace directory (default: current directory, walks up to find zhi.yaml) |
--verbose |
Enable debug-level logging to stderr |
--version |
Print version information |
zhi initScaffold a new workspace in the current (or specified) directory.
zhi init
zhi init --config-provider structuredfile --store-provider zhi-store-json
zhi init --force # overwrite existing zhi.yaml
Creates zhi.yaml, starter configuration files, sample export templates, and the .zhi/ directory.
| Flag | Default | Description |
|---|---|---|
--config-provider |
structuredfile |
Config provider to use |
--store-provider |
zhi-store-json |
Store provider to use |
--force |
false |
Overwrite existing zhi.yaml |
zhi edit
Launch the interactive UI to browse, edit, and manage configuration.
zhi edit
zhi edit --tree production
zhi edit --ui tui
zhi edit --ui webui
zhi edit --ui mcp-stdio
| Flag | Default | Description |
|---|---|---|
--tree |
(default tree) | Tree ID to load from store |
--ui |
tui |
UI driver to use (tui, webui, mcp-stdio, or an external plugin) |
TUI key bindings:
| Key | Action |
|---|---|
j / k / arrows |
Navigate |
Enter |
Edit selected value |
s |
Save tree to store |
v |
Validate configuration |
a |
Run apply command |
e |
Open export view |
c |
Open component view |
r |
Reload tree |
/ |
Filter paths |
q / Ctrl+C |
Quit |
Esc |
Return to tree view |
zhi getRetrieve a single configuration value.
zhi get database/host
zhi get database/host --raw
zhi get database/host --json
| Flag | Description |
|---|---|
--raw |
Print just the value, no metadata |
--json |
Output as JSON including metadata |
zhi setSet a single configuration value.
zhi set database/host mydb.example.com
zhi set database/port 5432 --validate
| Flag | Description |
|---|---|
--validate |
Validate after setting |
zhi validateValidate the configuration tree and print results grouped by severity.
zhi validate
zhi validate --path database/port
zhi validate --json
Exit code 1 if any Blocking results, 0 otherwise.
| Flag | Description |
|---|---|
--path |
Validate only a specific path |
--json |
Output as JSON |
Example output:
BLOCKING database/port Port must be between 1024 and 65535
WARNING app/log-level Consider using "info" in production
INFO app/name Value is using default
Validation: 1 blocking, 1 warning, 1 info
zhi listList information about the workspace.
zhi list providers # Show built-in and external providers
zhi list trees # Show stored tree IDs
zhi list paths # Show all config paths
zhi list components # Show components with status
| Flag | Description |
|---|---|
--json |
Machine-readable JSON output |
Component list example:
NAME STATUS MANDATORY DEPENDENCIES PATHS
database enabled yes - database/
redis enabled no database redis/
monitoring disabled no - monitoring/
zhi componentManage component state.
zhi component list # List all components
zhi component enable redis # Enable a component (and dependencies)
zhi component disable monitoring # Disable a component
zhi component info database # Show detailed component info
| Flag | Description |
|---|---|
--json |
JSON output |
--force |
Cascading disable (also disable dependent components) |
See Components for details on how components work.
zhi driftDetect configuration drift by comparing exported files on disk against what the workspace would currently generate.
zhi drift # Check all exports for drift
zhi drift --json # JSON output for scripting/CI
zhi drift --watch --interval 5m # Watch mode (foreground)
zhi drift --watch --interval 5m --on-drift "cmd" # Watch with notification hook
| Flag | Default | Description |
|---|---|---|
--json |
false |
Output as JSON |
--watch |
false |
Run continuously, checking at --interval |
--interval |
1m |
Check interval for watch mode (e.g. 30s, 5m) |
--on-drift |
Shell command to run when drift is detected |
Exit codes:
| Code | Meaning |
|---|---|
0 |
No drift (all files in sync) |
1 |
Drift detected |
2 |
Error during drift check |
Example output:
Drift Detection Report
DRIFTED (1):
ansible/inventory/hosts.yml:
--- ansible/inventory/hosts.yml (current)
+++ ansible/inventory/hosts.yml (expected)
@@ -10,3 +10,3 @@
-upstream: 8.8.8.8
+upstream: 1.1.1.1
IN SYNC (3):
ansible/group_vars/webservers.yml
ansible/group_vars/databases.yml
config/app.toml
Run `zhi export` to reconcile, or `zhi export --diff` for full details.
Watch mode only outputs on state transitions (clean→drifted or drifted→clean). The first check treats the initial state as unknown, so if drift exists at startup the hook fires immediately. On graceful shutdown (SIGINT/SIGTERM) the command exits 0.
zhi exportExport configuration to files using templates or built-in formats.
zhi export # Export all templates in zhi.yaml
zhi export --format json # Built-in JSON format
zhi export --format yaml --output config.yml # YAML to file
zhi export --template ./templates/my.tmpl # Custom template
zhi export --format dotenv --all-components # Include disabled components
zhi export --dry-run # Preview without writing
| Flag | Description |
|---|---|
--template |
Path to a Go template file |
--format |
Built-in format: json, yaml, toml, dotenv |
--output / -o |
Output file path (default: stdout) |
--prefix |
Only export paths under this prefix |
--all-components |
Include all components regardless of state |
--dry-run |
Print output without writing files |
See Export and Templates for template syntax.
zhi applyRun the configured provisioning command.
zhi apply # Run the default apply target
zhi apply destroy # Run a named target
zhi apply --dry-run # Show command without executing
| Flag | Description |
|---|---|
--dry-run |
Print command without executing |
--no-export |
Skip the pre-export step |
--timeout |
Override configured timeout (seconds) |
--env KEY=VALUE |
Add/override environment variables (repeatable) |
See Apply for details.
zhi pluginManage shared plugins from OCI registries.
zhi plugin installDownload and install a plugin from an OCI registry.
zhi plugin install oci://ghcr.io/zhi-project/zhi-config-ansible:v1.2.0
zhi plugin install ghcr.io/org/zhi-config-custom:v1.0.0 --force
zhi plugin install ghcr.io/org/zhi-config-custom:v1.0.0 --skip-verify
| Flag | Description |
|---|---|
--platform |
Override platform detection (e.g. linux/amd64) |
--force |
Overwrite existing plugin even if same version |
--skip-verify |
Skip signature verification (not recommended) |
zhi plugin uninstallRemove an installed shared plugin binary and its metadata.
zhi plugin uninstall ansible-config
zhi plugin listList all installed shared plugins with version, signing status, and source.
zhi plugin list
zhi plugin list --json
| Flag | Description |
|---|---|
--json |
Output as JSON |
zhi plugin infoShow detailed information about a plugin including signer identity, binary digest, trust level, ratings, and download statistics. If the plugin is not installed locally, the marketplace is queried.
zhi plugin info ansible-config
zhi plugin info ansible-config --json
| Flag | Description |
|---|---|
--json |
Output as JSON |
zhi plugin rateRate a plugin on the marketplace (1-5 stars with optional review comment). Requires a marketplace API key in ~/.zhi/config.yaml.
zhi plugin rate zhi-project/ansible-config 5
zhi plugin rate zhi-project/ansible-config 4 --comment "Works well but missing docs"
| Flag | Description |
|---|---|
--comment |
Optional review text (max 2000 characters) |
zhi plugin verifyVerify a plugin artifact’s signature without installing. Useful for auditing and compliance.
zhi plugin verify oci://ghcr.io/zhi-project/zhi-config-ansible:v1.2.0
zhi plugin publishBuild an OCI artifact from a zhi-plugin.yaml manifest and push to a registry.
zhi plugin publish --registry ghcr.io/myorg
zhi plugin publish --registry ghcr.io/myorg --sign
zhi plugin publish --registry ghcr.io/myorg --sign --key cosign.key
| Flag | Description |
|---|---|
--registry |
Target OCI registry (required) |
--tag |
OCI tag (default: v{version} from manifest) |
--sign |
Sign the artifact with cosign after pushing |
--key |
Path to cosign private key (default: keyless via Fulcio/OIDC) |
zhi plugin newScaffold a complete plugin project from a template. Generates a standalone repository with implementation stubs, tests, build automation, CI/CD workflows, and a sample workspace. See the Scaffolding Guide for the full reference.
zhi plugin new --name my-config --type config
zhi plugin new --name my-store --type store --author myorg --license MIT
zhi plugin new --name my-transform --type transform --registry ghcr.io/myorg
| Flag | Default | Description |
|---|---|---|
--name |
(required) | Plugin short name, must match [a-z][a-z0-9-]* |
--type |
(required) | Plugin type: config, transform, store, ui |
--lang |
go |
Project language |
--module |
auto-derived | Go module path |
--registry |
Target OCI registry for publishing | |
--author |
Author or organisation name | |
--license |
SPDX license identifier | |
--description |
Short description of the plugin | |
--output-dir, -o |
./zhi-<type>-<name> |
Output directory |
zhi plugin initGenerate a zhi-plugin.yaml manifest for an existing plugin project. For new projects, prefer zhi plugin new which generates the full project structure.
zhi plugin init --name my-config --type config --version 1.0.0
| Flag | Description |
|---|---|
--name |
Plugin name (required) |
--type |
Plugin type: config, transform, store, ui (required) |
--version |
Initial version (required) |
--description |
Plugin description |
--author |
Author name |
--license |
SPDX license identifier |
zhi plugin updateCheck for and install plugin updates from the marketplace.
zhi plugin update --check # Check for available updates
zhi plugin update --check --changelog # Show changelogs for available updates
zhi plugin update ansible-config # Update a specific plugin
zhi plugin update --all # Update all plugins
| Flag | Description |
|---|---|
--check |
Only check for updates, don’t install |
--all |
Update all plugins with available updates |
--changelog |
Show changelogs for available updates |
--json |
Output as JSON |
Pinned plugins are skipped during --all updates but can still be updated explicitly by name.
zhi plugin pinPin a plugin at its current version to prevent it from being updated during zhi plugin update --all.
zhi plugin pin ansible-config
zhi plugin unpinRemove the version pin from a plugin, making it eligible for updates again.
zhi plugin unpin ansible-config
zhi plugin rollbackRestore a plugin to the version that was installed before the most recent update. The previous binary is kept as a backup during each update.
zhi plugin rollback ansible-config
If no backup exists, use zhi plugin install <name>@<version> --force to install a specific version.
zhi plugin searchSearch the marketplace for plugins.
zhi plugin search ansible
zhi plugin search "vault store" --type store
zhi plugin search --type ui --sort rating --verified
| Flag | Description |
|---|---|
--type |
Filter by plugin type (config, transform, store, ui) |
--sort |
Sort by: relevance, downloads, rating, updated (default: relevance) |
--verified |
Show only verified plugins |
--json |
Output as JSON |
--limit |
Maximum results (default: 20) |
zhi plugin registerRegister a published plugin with the central marketplace.
zhi plugin register ghcr.io/myorg/zhi-config-custom:v1.0.0
zhi workspaceManage shareable workspaces.
zhi workspace installInstall a workspace and its plugin dependencies from an OCI registry or marketplace.
zhi workspace install k8s-cluster
zhi workspace install oci://ghcr.io/org/zhi-workspace-k8s:v1.0 ./my-cluster
| Flag | Description |
|---|---|
--skip-plugins |
Don’t install plugin dependencies |
--skip-tools-check |
Don’t check for required external tools |
--dry-run |
Show what would be installed |
zhi workspace publishPublish the current workspace as a shareable OCI artifact.
zhi workspace publish --registry ghcr.io/myorg
zhi workspace publish --registry ghcr.io/myorg --sign
| Flag | Description |
|---|---|
--registry |
Target OCI registry (required) |
--sign |
Sign the artifact with cosign |
--tag |
OCI tag (default: from workspace version) |
zhi workspace lockGenerate or update zhi-plugins.lock by resolving all plugin references to exact OCI digests.
zhi workspace lock # Lock current versions
zhi workspace lock --update # Update and re-lock
| Flag | Description |
|---|---|
--update |
Update all plugins to latest matching versions |
--update-plugin |
Update a specific plugin |
zhi registryManage OCI registry authentication.
zhi registry loginAuthenticate with an OCI registry.
zhi registry login ghcr.io --username myuser
echo $GHCR_TOKEN | zhi registry login ghcr.io --username myuser --password-stdin
| Flag | Description |
|---|---|
--username |
Registry username |
--password |
Registry password |
--password-stdin |
Read password from stdin |
zhi registry logoutRemove stored credentials for a registry.
zhi registry logout ghcr.io
zhi registry listList configured registries and their authentication status.
zhi registry list
zhi vault-credentialsManage Vault credentials for applications deployed with the zhi-store-vault-manager meta-plugin. See Vault Credential Management for the full guide.
zhi vault-credentials refreshGenerate fresh credentials (AppRole wrapped secret_ids or tokens) without a full export/apply cycle.
zhi vault-credentials refresh
zhi vault-credentials refresh --app web-api --output env
zhi vault-credentials refresh --output quiet
zhi vault-credentials refresh --export-template docker-compose
| Flag | Default | Description |
|---|---|---|
--app |
(all apps) | Refresh only a specific app’s credentials |
--output |
json |
Output format: json, env, quiet |
--export-template |
Re-run a specific export template with fresh credentials |
Example JSON output:
{
"vault/credentials/web-api/auth-method": "approle",
"vault/credentials/web-api/role-id": "abc-123",
"vault/credentials/web-api/wrapped-secret-id": "hvs.CAES..."
}
Example env output:
VAULT_CREDENTIALS_WEB_API_AUTH_METHOD=approle
VAULT_CREDENTIALS_WEB_API_ROLE_ID=abc-123
VAULT_CREDENTIALS_WEB_API_WRAPPED_SECRET_ID=hvs.CAES...
zhi vault-credentials bootstrapGenerate the Vault ACL policy required by the vault-manager’s admin token. Run once during initial setup.
zhi vault-credentials bootstrap --dry-run
zhi vault-credentials bootstrap
| Flag | Default | Description |
|---|---|---|
--dry-run |
false |
Print the policy HCL without instructions for applying it |
The output includes the HCL policy and a ready-to-run vault policy write command.
zhi versionPrint version, commit hash, and build date.
$ zhi version
zhi v0.1.0 (commit: abc1234, built: 2026-01-29)