Skip to main content

Private beta: Request private beta access

zenitya

Working with an agent

How a coding agent should drive zya: output, JSON, errors and safe habits.

View as markdown

This page is written for coding agents (Claude Code, Codex, Cursor and others) that build and deploy Zenitya tools with the zya CLI. People can read it too: it is the shortest path to driving the CLI from scripts.

Read the docs that match the installed CLI with zya docs:

shell
zya docs              # list topics
zya docs agents       # this page
zya docs quickstart   # the end-to-end flow
zya docs cli          # every command and option

A link to <topic>.md in these pages is another topic: read it with zya docs <topic>. The same pages are online at https://zenitya.com/docs, and each one as markdown at https://zenitya.com/docs/<topic>.md. Prefer zya docs: it always matches the CLI you are running.

Before you start

  1. Check the CLI: zya --version. If it is missing, install it with curl -fsSL https://zenitya.dev/install.sh | sh and use ~/.zenitya/bin/zya until a new shell picks up the PATH.
  2. Check the login: zya whoami --json. If it fails with error[AUTH_INVALID], ask the person to run zya login themselves. It opens a browser for Google sign-in, which you cannot complete for them.
  3. Zenitya is in private beta. If sign-in shows a waitlist or a command fails with error[ACCESS_NOT_GRANTED], the person needs an invitation; send them to https://zenitya.com/early-access and stop.
  4. Inside a project, commands use the nearest zenitya.json from the current directory up. Outside one, zya new <directory> creates a project.

The loop

shell
zya new my-tools && cd my-tools && bun install
# edit src/index.ts
bun run check                                         # type-check
zya exec <tool> --local --data '{"...": "..."}'       # run the source
zya deploy --json                                     # build remotely, go live
zya tools list --json                                 # what the credential can call
zya exec <tool> --data '{"...": "..."}'               # run the deployed copy

Always run a tool with --local before deploying it. A deploy takes a minute or two; a local run takes a second.

After the first deploy, a tool is callable only once an owner or admin grants it to a group in the Zenitya app (Groups, then the group, then the tool). If zya tools list does not show a tool you deployed, ask the person to grant it; you cannot do that from the CLI.

Reading output

The CLI is built to be read by programs:

  • stdout is data only. Tool output from exec, listings and --json results. Nothing else is ever written there.
  • stderr is for messages. Progress, notes, warnings and errors. Tool logs from exec are JSON lines on stderr.
  • No decoration when piped. Without a terminal, or with CI set or TERM=dumb, messages are plain lines and listings are tab-separated rows without a header. NO_COLOR turns color off everywhere.
  • Exit code 1 on any failure.

Use --json whenever you parse a result. These commands support it:

Command--json prints
zya deploy{ project, buildId, state, deploymentId, active, toolCount, skills, idempotencyKey }
zya tools list{ project, activeDeployment, tools: [{ name, key, title, description, ... }] }
zya builds list{ builds: [{ id, state, createdAt, deployment, ... }] }
zya builds view <id>{ build, deployment, steps, diagnostics }
zya builds logs <id>One JSON record per line: { seq, phase, stream, capturedAt, text }
zya secrets list{ secrets: [{ name, updatedAt }] } (never values)
zya whoami{ identity, organization, organizationId, scopes, apiUrl, credential }

zya exec always prints the tool's output as JSON, so it needs no flag.

Recipes:

shell
zya deploy --json | jq -r .buildId
zya tools list --json | jq -r '.tools[].key'
zya builds list --json | jq -r '.builds[] | select(.state == "failed") | .id'
zya builds logs <build-id> --json | jq -r 'select(.stream == "stderr") | .text'
zya whoami --json | jq -r .organizationId
zya exec search --data '{"query":"late"}' | jq '.items | length'

Errors

Every failure prints one line on stderr:

text
error[CODE]: what happened
hint: the next step, when there is one

Read the code, follow the hint, and add --verbose for details and a stack trace. A failed API call ends with (request <id>): quote it when reporting a problem to the person. Codes you will meet:

CodeMeaning and what to do
CONFIG_MISSINGNo zenitya.json here or above. cd into the project, or zya new.
CONFIG_INVALIDzenitya.json breaks a rule; the message names the field. See config.md.
INPUT_INVALIDBad arguments or tool input. The hint shows the expected form.
FLAG_UNKNOWN, COMMAND_UNKNOWNTypo; the hint suggests the closest match.
AUTH_INVALIDNot signed in, or the credential lacks a permission. Ask the person to run zya login.
ACCESS_NOT_GRANTEDThe account has no beta access yet. Send the person to https://zenitya.com/early-access.
TOOL_FAILEDThe tool itself failed: error[TOOL_FAILED]: <code>: <message>. invalid_input means the input did not match the schema; execution_error means the code threw.
DEPLOY_FAILEDThe build failed or could not start. Read the build output (below).
SKILL_INVALIDA SKILL.md breaks the format; the message names the file.
BUN_NOT_FOUND--local needs Bun on PATH. Install it from https://bun.sh.

When a deploy fails

shell
zya builds list --limit 1 --json | jq -r '.builds[0].id'
zya builds view <build-id>                     # which step failed and why
zya builds logs <build-id> --phase install     # dependency installation output
zya builds logs <build-id> --phase bundle      # bundling output
zya builds logs <build-id> --phase describe    # loading your tools

A failed build changes nothing: the previous deployment keeps serving calls. See Deploying and builds.

Safe habits

  • Never put a secret on the command line or in source. Pipe it: printf %s "$VALUE" | zya secrets set API_TOKEN --stdin. Better, ask the person to run that command themselves so the value never enters your context.
  • Never print or log secret values, and never commit .env. .env is for --local runs only and is never uploaded.
  • Ask before deploying if the person has not asked you to, and before calling a deployed tool that changes data (one without readOnlyHint).
  • Write precise descriptions. Other agents choose tools by their description and their schema's .describe() text; say what the tool does, when to use it and what it returns. See Writing tools.
  • Keep tools small and deterministic. One tool per workflow step that another agent would otherwise do by hand.

When working in a Zenitya project

Projects created with zya new have an AGENTS.md that says so. If a repository has a zenitya.json, it is a Zenitya project: read this page and Writing tools before changing it.