@tsuga/cli
v1.1.1
Published
Tsuga CLI - manage resources from the command line
Downloads
1,592
Maintainers
Readme
@tsuga/cli
Command-line interface for managing Tsuga resources.
Installation
npm install -g @tsuga/clitsuga --helpUpdating
Update to the latest published version:
tsuga self-updateThis runs npm install -g @tsuga/cli@latest. The CLI also checks for new versions once a day and prints a notice when one is available.
Shell completion
Tab-complete commands and flags in bash, zsh, or fish.
For bash and zsh, add the matching line to your shell startup file:
# ~/.bashrc
eval "$(tsuga completion bash)"
# ~/.zshrc
eval "$(tsuga completion zsh)"Then open a new shell (or source the file).
For fish, write the script to your completions directory:
tsuga completion fish > ~/.config/fish/completions/tsuga.fishFish loads it automatically in new shells.
Authentication
All authentication lives under tsuga auth.
Log in as a user (recommended)
For interactive use, log in as a user with a browser authorization flow:
# Prints an authorization URL. On macOS, also opens it in your browser.
tsuga auth login
# Print the saved user access token
tsuga auth token
# Show the current authentication method
tsuga auth status
# Clear the saved user session
tsuga auth logoutAfter tsuga auth login, commands work without an Operation API key.
Operation API key
For non-interactive use (CI, scripts), authenticate with an Operation API key. Generate one from your Tsuga account settings, then save it once:
tsuga auth operation-key <operation-api-key>This writes your operation-api-key to ~/.config/tsuga/config.json. Alternatively, set it per-session without saving:
# Environment variable
export TSUGA_OPERATION_API_KEY=<operation-api-key>
# CLI flag (highest priority)
tsuga --operation-api-key <operation-api-key> dashboards listA --operation-api-key flag or TSUGA_OPERATION_API_KEY env var overrides the saved credential for that one invocation.
Configuration
Show current configuration (includes defaults):
tsuga configDefaults
Commands have built-in defaults so you can omit common flags:
| Flag | Default |
| --------------- | ------- |
| --from | -30m |
| --to | now |
| --query | * |
| --max-results | 100 |
Override defaults persistently:
tsuga config set default from -1h
tsuga config set default query 'level:ERROR'Current defaults are listed by tsuga config (custom overrides marked with *).
Reset all custom defaults:
tsuga config reset defaultsClear a single default by setting it to an empty value:
tsuga config set default cluster ''Clusters
If your tenant has multiple clusters, list them:
tsuga cluster listPick the cluster you want to use by default via the defaults mechanism:
tsuga config set default cluster <cluster-id>Override per-command without persisting:
# Environment variable
export TSUGA_CLUSTER_ID=<cluster-id>
# CLI flag (highest priority)
tsuga --cluster <cluster-id> logs searchPriority order: --cluster flag → TSUGA_CLUSTER_ID env var → defaults.cluster. If unset, the backend falls back to the first cluster.
Usage
Most resources follow the same CRUD pattern:
tsuga <resource> list
tsuga <resource> get <id>
tsuga <resource> create -f payload.json
tsuga <resource> update <id> -f payload.json
tsuga <resource> delete <id>Read-only resources (for example services) support only:
tsuga services list
tsuga services get <id>You can also pass JSON inline with -d:
tsuga teams create -d '{"name": "Platform", "visibility": "public"}'Explaining a call with --rationale
API-calling commands accept an optional --rationale flag to record why they are being run.
It does not change the result; the text is sent as a request header and recorded in the
backend request log, which is useful for understanding agent behavior.
tsuga logs patterns --rationale "exploring telemetry to investigate prod outage"Available resources
cloud-resources, dashboards, ingestion-api-keys, investigations, monitors, notification-rules, notification-silences, quality-reports, retention-policies, routes, services, tag-policies, teams
Notes:
ingestion-api-keysdoes not supportget <id>.servicesis read-only (list,get).cloud-resourcesandquality-reportsare read-only and only supportlist.- For
quality-reports list, pass--cluster <id>(or setTSUGA_CLUSTER_ID/ saved default) when the org has more than one cluster.- Pass
--team <name>toquality-reports listto scope the response to a single team by name (omits cluster-wide global rows).investigationsis beta: it requires an operation API key with theinvestigationspermission and the API may change.
Generating a request skeleton
Any create or update command accepts --generate-skeleton to print a JSON template of the expected request body:
tsuga monitors create --generate-skeleton
tsuga notification-rules update abc-123 --generate-skeletonPipe the output to a file, fill it in, then pass it back with -f:
tsuga monitors create --generate-skeleton > monitor.json
# edit monitor.json
tsuga monitors create -f monitor.jsonExamples
# List all monitors
tsuga monitors list
# Get a specific dashboard
tsuga dashboards get abc-123
# List dashboards filtered by owner
tsuga dashboards list -d '{"filters":{"owners":{"values":["team-1","team-2"]}}}'
# Get a specific service
tsuga services get abc-123
# Create a notification rule from a file
tsuga notification-rules create -f rule.json
# Update a route
tsuga routes update abc-123 -d '{"name": "Updated route"}'
# Delete a retention policy
tsuga retention-policies delete abc-123Telemetry
Time formats
--from and --to accept any of:
| Format | Example |
| ------------ | ---------------------------- |
| Relative | -30m, -1h, -7d, -30s |
| Now | now |
| Unix seconds | 1704067200 |
| ISO 8601 | 2024-01-01T00:00:00Z |
Search logs
tsuga logs search --from -1h --query 'level:ERROR'
tsuga logs search --from 1704067200 --to 1704153600 --query 'service:api'By default, the full JSON response is printed. Use --fields to project specific
dot-paths from each log, and -o tsv|csv for tabular output:
# JSON projected to selected fields (preserves the {logs: [...]} envelope and nesting)
tsuga logs search --from -10m \
--fields timestamp,level,message,context.k8s.pod.name
# TSV with default columns: timestamp, level, message
tsuga logs search --from -10m --query 'level:ERROR' -o tsv
# CSV with custom columns
tsuga logs search --from -10m -o csv \
--fields timestamp,level,message,context.k8s.pod.nameLog attributes
tsuga logs attributes --from -1hLog patterns
# Group recent logs into patterns
tsuga logs patterns --from -1h --query 'level:ERROR'
# List new error patterns observed in the time range
tsuga logs new-error-patterns --from -24h --team my-team --service api --env prod
# List error patterns whose volume increased for a team
tsuga logs error-pattern-increases --from -24h --team my-team --env prodSearch traces
tsuga traces search --from -30m --query 'span_name:GET'Metrics
# List all metrics
tsuga metrics list --from -1h
# Get a specific metric
tsuga metrics get my.metric.name --from -1h
# List dashboards and monitors that use a metric
tsuga metrics assets-usage my.metric.nameAggregation
Run aggregation queries with a JSON body:
tsuga aggregation scalar -f query.json
tsuga aggregation timeseries -f query.jsonUse --generate-skeleton to get a template:
tsuga aggregation scalar --generate-skeleton > query.jsonService graph
Inspect service dependency graphs:
tsuga service-graph get <service-id> --from -1h --query 'env:prod'Experimental
Commands under tsuga experimental are unstable and may change or be removed without notice. Use them only if you accept that risk.
PromQL
Run a PromQL query against the metrics backend. Returns a timeseries shape matching tsuga aggregation timeseries.
tsuga experimental promql --generate-skeleton > query.json
# edit query.json
tsuga experimental promql -f query.jsonOr inline:
tsuga experimental promql -d '{"query":"sum(rate(http_requests_total[5m]))","timeRange":{"from":1704067200,"to":1704070800},"step":"30s"}'timeRange.from / timeRange.to are Unix timestamps in seconds.
LLM telemetry
Configure local Claude Code (~/.claude/settings.json) or Codex (~/.codex/config.toml) to ship OpenTelemetry data to your Tsuga cluster. Needs an OTLP base URL and an ingestion API key (not the same as your operation API key).
tsuga setup claude-code --endpoint <otlp-base-url> --ingestion-api-key <key>
tsuga setup codex --endpoint <otlp-base-url> --ingestion-api-key <key>Both options also read from env (TSUGA_OTLP_ENDPOINT, TSUGA_INGESTION_API_KEY). Pass --no-include-prompts to strip user prompts + tool content from telemetry (default: include). The previous config is saved alongside the file as .bak.<ISO>; restart any running claude / codex sessions afterward.
LLM plugins
tsuga install plugin claude-code
tsuga install plugin codexAdds the tsuga marketplace (tsuga-dev/agent-plugins) and installs the tsuga plugin via the target CLI (claude / codex must be on PATH). For Claude Code, marketplace auto-update is enabled by patching ~/.claude/settings.json with extraKnownMarketplaces.tsuga.autoUpdate = true; pass --no-auto-update to skip. Restart any running claude / codex sessions afterward.
Documentation
Browse and search the Tsuga documentation:
tsuga docs search 'log routes'
tsuga docs get getting-started/send-your-first-logsFeedback
Report friction with Tsuga tools or APIs (a failing command, unusable output, confusing behavior):
tsuga feedback the traces command keeps timing out on large servicesTips
Default output is JSON, so you can pipe to jq:
tsuga dashboards list | jq '.[].name'
tsuga monitors list | jq '.[] | select(.priority == 1)'Read from stdin with -f -:
echo '{"name": "My Team"}' | tsuga teams create -f -