Command-line client for the Nortezh deployment platform.
ntzh lets you list projects, ship new container images, roll back to a previous
revision, inspect deployment history, and manage routes/domains — straight from
your terminal or CI pipeline.
- Installation
- Quick start
- Authentication
- Usage
- Configuration
- Scripting & CI
- Shell completion
- Development
- License
go install github.com/nortezh/cli/cmd/ntzh@latestThis installs the ntzh binary to $(go env GOPATH)/bin. Make sure that
directory is on your PATH.
ntzh bundles a SKILL.md that teaches AI coding agents how to drive
this CLI (deploy recipe, flag shapes, where to look for more help).
One command installs it for every supported agent:
ntzh skill install # install for Claude Code and Codex
ntzh skill install --target=claude # only Claude Code (also read by opencode)
ntzh skill install --target=codex # only OpenAI Codex
ntzh skill install --force # overwrite existing copiesInstall locations:
| Target | Path | Agents that read it |
|---|---|---|
| claude | ~/.claude/skills/ntzh/SKILL.md |
Claude Code, opencode |
| codex | ~/.agents/skills/ntzh/SKILL.md |
OpenAI Codex CLI |
git clone https://github.com/nortezh/cli.git
cd cli
make install # go install ./cmd/ntzh
# or
make build # produces ./ntzhRequires Go 1.26 or newer.
ntzh login # open the browser, sign in
ntzh project list
ntzh deployment list --project=acme
ntzh deployment deploy staging-bo \
--project=acme \
--image=ghcr.io/acme/api:v1.2.3 \
--location=bkk-1ntzh supports two credential types. Both are stored at
~/.config/ntzh/credentials.json with mode 0600.
| Mode | Command | When to use |
|---|---|---|
| Browser | ntzh login |
Interactive use on a laptop |
| Service account | ntzh login --service-account=ci@acme.com --key-file=./key.txt |
CI / headless environments |
ntzh whoami # show current identity
ntzh logout # remove stored credentialsHeads up: Browser tokens expire after 7 days and are not refreshed automatically. Re-run
ntzh loginwhen prompted. Service-account credentials do not expire.
ntzh project list
ntzh project list --output=json--project accepts a project name, slug (the no field), or internal ID.
--location (cluster ID) is auto-detected via deployment.list when omitted.
# List
ntzh deployment list --project=<project>
# Inspect one
ntzh deployment get <deployment> --project=<project> --location=<location>
# Ship a new image (optionally patch env, ports, replicas in the same revision)
ntzh deployment deploy <deployment> \
--project=<project> \
--image=<image> \
--location=<location> \
[--set-env KEY=VALUE ...] [--remove-env KEY ...] \
[--port <n>] [--protocol <p>] [--internal=<bool>] \
[--min-replica <n>] [--max-replica <n>]
# Roll back to a previous revision
ntzh deployment rollback <deployment> \
--project=<project> \
--to=<revision> \
--location=<location>
# Revision history (newest first)
ntzh deployment revisions <deployment> --project=<project> --location=<location>ntzh deployment deploy staging-bo \
--project=acme \
--image=ghcr.io/acme/api:v1.2.3 \
--location=bkk-1Deployment list columns (table mode): NAME, TYPE, STATUS, LOCATION,
REPLICAS, LAST_DEPLOYED.
ntzh deployment get <name> prints the current env (ENV:KEY rows in table
mode, or the env object under --output=json). Use --set-env / --remove-env
on deploy to patch it — each flag is optional, omitted flags leave the value
unchanged.
ntzh domain list --project=<project>
ntzh domain get <domain> --project=<project>
ntzh domain create <domain> --project=<project> --location=<location> [--wildcard] [--cdn]
ntzh domain delete <domain> --project=<project>A route binds (domain, path) to a web-service deployment. The owning project
must already have the domain registered.
ntzh route list --project=<project> [--search=<q>]
ntzh route get --project=<project> --domain=<domain> --path=<path>
ntzh route create --project=<project> --domain=<domain> --path=<path> --target=<deployment> \
[--location=<location>] [--rewrite-path=<expr>] [--skip-domain-verify]
ntzh route delete --project=<project> --domain=<domain> --path=<path>--target accepts a deployment name (e.g. api-prod); the CLI prepends
deployment:// for you. --location is auto-resolved from the target
deployment when omitted.
ntzh reads two files from ~/.config/ntzh/:
~/.config/ntzh/config.json # { "server": "https://api.nortezh.com" }
~/.config/ntzh/credentials.json # 0600 — bearer or service_account
| Variable | Purpose |
|---|---|
NTZH_SERVER |
Override the API server URL |
NTZH_PROJECT |
Default --project for project-scoped commands |
NTZH_LOCATION |
Default --location, skips the deployment.list lookup |
NTZH_CONFIG_DIR |
Override ~/.config/ntzh |
flag > env var > config file > default
| Flag | Purpose |
|---|---|
--output=json |
Emit raw structured responses (parse with jq) |
--debug |
Log HTTP request/response to stderr (Authorization header is redacted) |
# GitHub Actions example
- name: Deploy
env:
NTZH_PROJECT: acme
run: |
ntzh login \
--service-account=ci@acme.com \
--key-file=<(echo "$NTZH_KEY")
ntzh deployment deploy api \
--image=ghcr.io/acme/api:${{ github.sha }} \
--location=bkk-1All commands exit non-zero on failure; errors are written to stderr.
ntzh ships completion scripts for bash, zsh, fish, and powershell
via ntzh completion <shell>.
Quick test in the current shell:
source <(ntzh completion zsh)
compdef _ntzh ntzhPersistent install — make sure compinit is enabled in your ~/.zshrc:
autoload -Uz compinit && compinitThen write the script to a directory on your fpath:
ntzh completion zsh > "${fpath[1]}/_ntzh"
# or, on Homebrew:
ntzh completion zsh > "$(brew --prefix)/share/zsh/site-functions/_ntzh"Restart the shell (exec zsh) and tab-complete on ntzh .
ntzh completion bash --help
ntzh completion fish --help
ntzh completion powershell --helpEach subcommand prints shell-specific install instructions.
make test # go test ./...
make build # build ./ntzh
make lint # golangci-lint runProject layout:
cmd/ntzh/ # main entrypoint
internal/api/ # arpc HTTP client + typed wrappers
internal/auth/ # credential store (bearer, service account)
internal/cli/ # cobra command tree
internal/config/ # config file + env resolution
internal/output/ # table & JSON printers