---
name: onyx-cli
description: >
  Agent-friendly command-line access to the Onyx AI API for listing models,
  checking credits, inspecting generations, managing media-library assets, and
  creating or editing images and videos without writing raw curl requests. Also supports structured client and
  brand image workflows: onboarding one or many customers, collecting logos and
  product assets, persisting reusable client memory, applying recurring image
  rules, learning style preferences from feedback, and saving generated assets
  in a repeatable folder structure. Use this skill whenever Codex is working
  inside this repository and needs to operate Onyx from the terminal with
  structured JSON output, repeatable commands, downloaded generation assets,
  recurring brand/client image production, or project-specific image memory.
---

# OKTA Studio CLI

Use the local CLI instead of handwritten API calls whenever the task fits one
of the supported commands. The CLI is built for agent use: every command can
emit structured JSON and the generation commands can save returned media to a
local file.

For recurring image work for brands, customers, projects, products, social
posts, ads, or campaigns, first read `references/brand-image-agent.md`. Load
the focused references only when needed:

- `references/onboarding-paths.md` for first-time users and memory setup.
- `references/conversation-patterns.md` for standard, re-entry, feedback, and
  express-mode dialogue.
- `references/prompt-anatomy.md` for the BRIEF-DNA prompt composer that turns
  short user requests into complete `gpt-image-2` design briefs.
- `references/style-dna-library.md` for ready-made Slot 3 style phrases
  (brutalist editorial, risograph, cinematic photoreal, premium luxury, etc.)
  and per-industry default hybrids.
- `references/translation-map.md` for translating everyday user language into
  precise prompt vocabulary.
- `references/anti-patterns.md` for Slot 9 of every BRIEF-DNA prompt (global
  always plus genre-, position-, and format-specific avoids).
- `references/director-mode.md` when the user wants more manual control via
  `/director`.
- `references/director-vocabulary.md` for the curated cinematic option list
  (Lighting, Camera, Lens, Aperture, Film Stock, Photographer, Movie Look,
  Filter, Shot Type) used in `/director`.
- `references/quality-workflow.md` for draft vs. final quality and customer
  credit handling. Code-default pricing is computed via
  `scripts/quote-price.mjs`; live default customer prices come from
  `.\okta.cmd --json models list`. Never paste raw API USD prices.
- `references/error-recovery.md` for API key, credit, model, asset, and safety
  failures.
- `config/defaults.json` for model, memory, format, prompt composer, quality,
  learning, and phase-1 defaults.

## Quick Start

Set authentication first:

```bash
$env:OKTA_API_KEY="onyx_sk_your_key_here"
$env:OKTA_API_URL="https://okta.studio" # optional
```

Run the CLI from the repo root:

```bash
.\okta.cmd meta info
.\okta.cmd config test
.\okta.cmd --json models list --type image
```

Prefer `.\okta.cmd` on Windows PowerShell so `--json` output stays clean. In
the downloaded public kit the executable is packaged at
`skills/okta-cli/scripts/okta-cli.mjs`; in this source repo the same executable
lives at `skills/onyx-cli/scripts/onyx-cli.mjs`.

Default image model for new image work: `gpt-image-2`. Use guided mode by
default: the user briefly describes the goal, and the agent builds the full
BRIEF-DNA prompt from client memory, the references, and the libraries. Offer
`/director` once per session as the precise control mode; do not force it and
do not repeat the offer every turn.

Use `--quality medium` for drafts and `--quality high` for approved finals.
When exact dimensions matter, use `--width`/`--height` or `--settings-json`
for models that support them. Do not pass undocumented CLI flags such as
`--resolution`; use `quote-price.mjs` for resolution-aware price quotes and
`models list` for live model capabilities. Do not present provider/API USD
prices as customer prices; query the code-default customer quote with:

```bash
node skills/okta-cli/scripts/quote-price.mjs --json --model gpt-image-2 --quality high --resolution 4K --aspect 1:1
```

Show price as a compact status line after generation, never as a confirmation
wall before generation:

```text
✓ ./output/acme/2026-04-30/a134-final.png
  79 Credits · 0,79 € · GPT Image 2 · high · 4K · 1:1
```

## Brand and Client Workflow

Use this workflow when the user wants ongoing image generation for themselves,
one customer, multiple customers, a product catalog, social media posts,
carousels, ads, listings, or recurring brand assets.

1. Load `references/brand-image-agent.md`.
2. Load `config/defaults.json` and resolve the memory root in this order:
   explicit user path, `ONYX_MEMORY_ROOT`, `.onyxrc`, then config default.
3. Check `last-session.md`, `registry.md`, and `clients/*/profile.md` before
   asking onboarding questions.
4. If client memory exists, ask whether to continue with an existing client or
   create a new one. Do not repeat full onboarding unless the profile is missing
   key details.
5. If no memory exists, use `references/onboarding-paths.md`.
6. Load the selected client's profile, summary, project brief, product brief,
   taste file, feedback file, style preset, asset notes, and latest relevant
   outputs before brainstorming or generating.
7. Persist only reusable preferences, asset references, product notes, output
   folders, feedback, and generation decisions. Never store API keys or secrets
   in client memory.
8. Compose each generation with `references/prompt-anatomy.md`: fill the
   relevant BRIEF-DNA slots from user request + selected client/project/product
   memory + relevant asset notes + fixed image rules + Director choices +
   model settings.
9. Use `references/translation-map.md` to turn vague words like "warm",
   "clean", or "edgy" into concrete prompt language. If the user says
   "modern", ask what kind instead of accepting it as a style.
10. Save prompts, slot/source notes, JSON responses, and generated files into
   the selected client output folder so the next agent can continue the same
   work.
11. After every generation, ask for feedback and update memory according to
    `references/conversation-patterns.md`.

## Command Map

### Metadata and configuration

```bash
.\okta.cmd meta info
.\okta.cmd config show
.\okta.cmd config test
```

Use `config test` before authenticated work if the environment may be stale or
the base URL is uncertain.

### Read-only API access

```bash
.\okta.cmd --json models list --type image
.\okta.cmd --json credits show
.\okta.cmd --json generations list --type video --limit 5
.\okta.cmd --json generations status --job-id <job_id> --wait --output ./output/result.png
.\okta.cmd --json assets list --source upload --limit 10
.\okta.cmd --json assets select --id <asset_id> --output ./output/reference.png
.\okta.cmd --json assets select --id <asset_id> --variant thumbnail --output ./output/reference-thumb.jpg
.\okta.cmd --json assets upload --file ./input/reference.png --name reference.png
```

Prefer `--json` for agent flows so the response is parseable.

### Media library assets

```bash
.\okta.cmd --json assets list --source upload --limit 20
.\okta.cmd --json assets select --id <asset_id> --output ./output/reference.png
.\okta.cmd --json assets select --id <asset_id> --variant thumbnail --output ./output/reference-thumb.jpg
.\okta.cmd --json assets upload --file ./input/reference.png --name reference.png
```

Use the returned `content_url` as `--image-url` for `image edit` or
`video create`. The API resolves that account-bound URL server-side before it
calls the generation provider.

### Quote a price (customer credits)

Returns the customer-facing credits and euros for code-default create/edit
pricing. Reads `config/pricing-snapshot.json` and applies the formula from
`src/utils/pricing.ts`. For production default prices with Convex admin
overrides applied, use `.\okta.cmd --json models list` and read the model's
`pricing.default_credits`.

```bash
node skills/okta-cli/scripts/quote-price.mjs --draft
node skills/okta-cli/scripts/quote-price.mjs --final
node skills/okta-cli/scripts/quote-price.mjs --json --model gpt-image-2 --quality high --resolution 4K --aspect 1:1
node skills/okta-cli/scripts/quote-price.mjs --json --model gpt-image-2 --mode edit --input-images 1 --quality high --resolution 4K --aspect 1:1
node skills/okta-cli/scripts/quote-price.mjs --table gpt-image-2
node skills/okta-cli/scripts/quote-price.mjs --list-models
```

### Create images

```bash
.\okta.cmd --json image create `
  --model gpt-image-2 `
  --prompt "Luxury watch on dark velvet, studio light" `
  --aspect-ratio 16:9 `
  --quality medium `
  --wait `
  --output ./output/watch.png
```

Supported image flags:

- `--model`
- `--prompt` or `--prompt-file`
- `--aspect-ratio`
- `--width` and `--height`
- `--quality`
- `--settings-json`
- `--output`
- `--wait`

Use `--wait --output` when the task needs a real file on disk. Without
`--wait`, the CLI returns `status_url`, `job_id`, and `pending_output` for
long-running jobs instead of failing. Poll manually with:

```bash
.\okta.cmd --json generations status --job-id <job_id> --wait --output ./output/watch.png
```

### Edit images

Single reference:

```bash
.\okta.cmd --json image edit `
  --model gpt-image-2 `
  --prompt "Replace the background with a clean white studio backdrop" `
  --image-url https://example.com/input.jpg `
  --aspect-ratio 1:1 `
  --quality medium `
  --output ./output/edited.png
```

Multiple references (up to 10) — comma-separated or repeated `--image-urls`:

```bash
.\okta.cmd --json image edit `
  --model gpt-image-2 `
  --prompt "Compose social hero: place the product centered, place the brand wordmark top-right at ~8% width, keep the lighting reference's mood" `
  --image-urls https://example.com/product.png,https://example.com/logo.png,https://example.com/lighting-ref.jpg `
  --aspect-ratio 4:5 `
  --quality medium `
  --output ./output/social-hero.png
```

`gpt-image-2` accepts up to 10 input images (`maxInputImages: 10` in
`studio_models.ts`). Use multiple references when you have logo + product +
style anchor — do NOT switch to another model thinking it has "more
references"; gpt-image-2 already handles this.

Supported image edit flags:

- `--model`
- `--prompt` or `--prompt-file`
- `--image-url` (single reference) **or** `--image-urls` (multiple, comma-separated or repeated)
- `--aspect-ratio`
- `--width` and `--height`
- `--quality`
- `--settings-json`
- `--output`

### Apply a saved logo after generation

Use deterministic compositing when a logo must always be in an exact place. Do
not rely only on the image model for strict logo placement or carousel numbers.

```bash
node skills/okta-cli/scripts/apply-logo.mjs `
  --input ./output/post.png `
  --logo ./.agent/onyx-image-memory/clients/acme/assets/logos/logo.png `
  --output ./output/post-branded.png `
  --position bottom-right
```

```bash
node skills/okta-cli/scripts/apply-carousel-number.mjs `
  --input ./output/slide-01.png `
  --output ./output/slide-01-numbered.png `
  --index 1 `
  --total 5
```

### Initialize or inspect memory

```bash
node skills/okta-cli/scripts/init-client.mjs `
  --name "Acme Bikes" `
  --project "Instagram Carousels" `
  --product-id A134 `
  --logo-position top-right `
  --format instagram_post
```

```bash
node skills/okta-cli/scripts/show-summary.mjs --client acme-bikes
```

### Create videos

```bash
.\okta.cmd --json video create `
  --model veo-3.1-fast `
  --prompt "Slow cinematic orbit around the product" `
  --image-url https://example.com/start-image.png `
  --duration 6 `
  --aspect-ratio 16:9 `
  --wait `
  --output ./output/product.mp4
```

Supported video flags:

- `--model`
- `--prompt` or `--prompt-file`
- `--duration`
- `--aspect-ratio`
- `--image-url`
- `--settings-json`
- `--output`
- `--wait`

Current public video model IDs are exposed by `.\okta.cmd --json models list
--type video`; as of this skill refresh they include `kling-v3`,
`kling-2.6-pro`, `seedance-1.5-pro`, the Seedance 2.0 standard/fast/reference
variants, `veo-3.1`, `veo-3.1-fast`, `hailuo-2.3-pro`, `happy-horse-1.0`,
`happy-horse-1.0-reference`, and `grok-imagine-video-1.5`.

If a video returns `status: "processing"`, poll and download it the same way:

```bash
.\okta.cmd --json generations status --job-id <job_id> --wait --output ./output/product.mp4
```

### Product photo to references to video

Use this workflow for agent-run product campaigns:

1. Upload or select the product anchor:
   `.\okta.cmd --json assets upload --file ./input/product.png --name product.png --retention-type pinned`
2. Read the returned `content_url` or call
   `.\okta.cmd --json assets select --id <product_asset_id>`.
3. Create reference images with `image edit`, passing the protected
   `/api/v1/assets/<asset_id>/content` URL as `--image-url`.
4. Upload approved references back into the media library with
   `assets upload --retention-type pinned`.
5. Create video clips from the selected reference asset URLs with
   `video create --wait --output`.
6. For a 90-second result, plan multiple 6-15 second shots and assemble them
   after generation. The current public API creates clips, not one continuous
   storyboard-rendered 90-second timeline.

## Agent Rules

Use these defaults unless the user asks otherwise:

1. Prefer `.\okta.cmd --json ...` on Windows or `node skills/okta-cli/scripts/okta-cli.mjs --json ...` when you need pristine machine-readable output.
2. Run `config test` before paid or stateful operations if credentials or base
   URL might have changed. The CLI request timeout defaults to 180 seconds so
   it can receive the API's long-running 202/`status_url` fallback.
3. `gpt-image-2` is the exclusive default image model. Do NOT substitute another
   model (seedream, nano-banana, ideogram, flux, ...) on your own
   judgement — not for "stronger text", not for "cheaper drafts", not for
   "more references". `gpt-image-2` already supports up to 10 input images
   (see `studio_models.ts` `maxInputImages: 10`) and renders typography
   accurately; it covers the brand-image use cases this skill is built for.
   Switch models only when (a) the user explicitly names a different model,
   (b) the user has been dissatisfied with `gpt-image-2` outputs three
   iterations in a row and you propose an alternative for confirmation, or
   (c) the operation is genuinely outside `gpt-image-2`'s capability set
   (e.g. video). Document the reason in `feedback.md` whenever you switch.
4. Use guided mode first. Offer `/director` once per session or when the user
   asks for more control.
5. Build prompts with the BRIEF-DNA composer before calling the CLI. Pull
   styles from `references/style-dna-library.md`, vague-word translation from
   `references/translation-map.md`, and 6-12 avoids from
   `references/anti-patterns.md`. Never accept `modern` as a final slot value.
6. Use `--quality medium` for drafts. Use `--quality high` only for finals or
   explicit user requests. For exact output dimensions, use `--width`,
   `--height`, or `--settings-json` only when the selected model exposes that
   capability. Do not put a confirmation wall in front of finals; one compact
   status line after generation is enough. Query code-default credits with
   `scripts/quote-price.mjs` rather than estimating; query `models list` when
   the live production default price matters.
7. Brainstorm before generation unless express mode is active.
8. Save media with `--output` when the image will be reused, reviewed, branded,
   or added to client memory.
9. Pass absolute output paths when the destination matters across tools or
   agents.
10. `gpt-image-2` renders text and logos accurately when given literal strings.
    Default for brand wordmarks, headlines, taglines, product names, prices,
    and visible copy is to put them verbatim in Slot 6 (Content literals) and
    let the model render them in-prompt. Use `scripts/apply-logo.mjs` only for
    repeatable exact-pixel-position needs (carousel slide consistency,
    watermark uniformity, packshot families). Use
    `scripts/apply-carousel-number.mjs` for slide numbering — the model is
    unreliable for sequential numbers. See `references/brand-image-agent.md`
    "Brand-asset decision tree" before defaulting to post-processing.
11. Pre-flight check before any image generate when a brand or product is in
    scope: Slot 6 (Content literals) MUST contain every visible string the
    image needs. Empty Slot 6 + a brand-named brief = predictably text-less,
    generic output. If literals are missing, STOP and ask one question before
    generating.
12. For phase-1 beginner flows, avoid videos, bulk runs over 5 images, custom
    pixel dimensions, restoration, upscaling, and complex multi-reference work
    unless the user explicitly asks and understands the tradeoff.
13. If the CLI does not expose a needed endpoint yet, fall back to
   `skills/onyx-api/SKILL.md` and call the API directly.

## When To Prefer The CLI Over Raw API Calls

- You need stable terminal commands another agent can repeat.
- You need JSON envelopes around results for automation.
- You want a returned image or video downloaded directly to disk.
- You want a fast connectivity check before a generation request.
