Nuvelics documentation
CLI

Scripts and agents

How to run the nuvelics tool unattended from a script or an AI agent, safely, with the checks to make before every run.

The nuvelics tool is built to be driven by a script or an AI agent with no person at the keyboard. This page is the set of rules that makes that safe. Most of them exist so that an unattended job cannot act on the wrong organization or leak a secret.

Always pass -o json. Most commands then print one JSON object on standard output, and every failure prints one on standard error. The exceptions are the delete, revoke and remove commands (including story photos rm), the local context and config commands, and login and logout, which print plain text instead of the envelope. For the confirmation lines, rely on exit code 0 and do not parse standard output; context list, context current, config list and config get print a plain list or value you can read. See Output.

A person signs in first

Signing in is a human step. The tool reads no credential from the environment and an unattended job has no way to get one. A person runs nuvelics login once on the machine, which needs a keychain. The job then uses what is stored. A machine with no keychain, such as most build servers, cannot run the tool unattended today.

Start with whoami

Make nuvelics whoami -o json the first call of every run:

nuvelics whoami -o json
  • Exit 0 means you are ready. .data.context is the active context name, which you will need for writes, and .data.organization.id is the organization you are about to act on. .data.user is null for a service key.
  • The kind unauthenticated (exit 2) means no credential is stored for the context. The kind forbidden (exit 3) from whoami means the API rejected the stored credential, because it was revoked or can no longer be renewed. Both are hard stops, and a person must sign in again. Report that the machine needs nuvelics login --context <name> and do nothing else. Do not retry, try another context, or look for another way in.

The sign-in check runs on the machine before any request is sent, so on a signed-out machine it costs nothing and changes nothing.

Name the context on every write

Reads use the active context. Anything that creates, changes, approves, pushes or deletes must name its context, or the tool refuses with ambiguous-context and sends nothing:

nuvelics pitch approve <id> --context acme -o json

Take the name from whoami, or from a context the person who set up the job chose on purpose. Do not infer it from what a name looks like; the tool gives names no meaning. Destructive commands also need --yes. The command reference marks which ones. See Contexts.

Find out what exists

Do not rely on a memorized command list. The tool prints its own:

nuvelics reference -o json

It lists every command with its options and what each option accepts, straight from the commands the tool actually has. Lists can be asked what they filter on, as described in Filters and paging.

Handle errors by kind

Branch on error.kind and error.retryable, as set out on Exit codes and errors:

  • Retry only when retryable is true, with a wait between attempts and a small limit.
  • usage means fix the command. Do not run it again unchanged.
  • forbidden is a real answer, not a fault to work around. Report it.
  • rejected means the item's state already rules the action out. Look at the item if you need to confirm, then move on.
  • Include requestId in anything you escalate.

Keep secrets out of commands

No flag takes a secret as its value, because a value on the command line is visible in process lists and shell history. Pass a secret on standard input with --secret-stdin:

printf '%s' "$SECRET" | nuvelics credential create \
  --name "CI bearer" --type bearer --secret-stdin --context acme -o json

A command that would ask for a hidden value fails at once when there is no terminal, naming --secret-stdin. It never waits for input nobody can give. Do not print a secret, put it in a log, or echo it back. The output of nuvelics api-key list never contains a key's secret, so it is safe to log.

What an unattended job must not do

  • Do not try to sign in. No nuvelics login, no borrowed key. An unauthenticated error goes to a person.
  • Do not create or revoke API keys from the command line. The tool has no command for it, on purpose. People manage keys in the web app, on the API keys tab. Do not reach for a direct API call to do the same.
  • Do not act outside the organization you were given. If a response names an organization or context you did not expect, stop and report it.

Example: review new pitches

# 1. Ready? Stop here on kind "unauthenticated".
nuvelics whoami -o json

# 2. What can pitches be filtered on?
nuvelics pitch list --limit 1 -o json | jq '.data.filters.available'

# 3. List the new ones, using a field from step 2.
nuvelics pitch list --filter status.eq=new --limit 50 -o json | jq '.data.items[] | {id, title}'

# 4. Act. The write names its context.
nuvelics pitch approve <id> --context acme -o json

If step 4 returns rejected, someone already approved or dismissed the pitch. Do not run it again. If it returns forbidden or not-found, stop and report; neither improves on a retry.

If you would rather give an assistant access through a chat client, with no shell involved, see Agents.

Report a problem with this page

On this page