@gptrf/cli
v1.0.0
Published
Official gptrf.ru command-line interface for the public media API.
Readme
@gptrf/cli
Official command-line interface for the gptrf.ru public media API.
Generate images, video, and audio (including the ElevenLabs audio sub-ops), upscale or background-remove images, upload source media, and inspect the model catalog — all from your terminal, authenticated against your gptrf.ru account.
Install
npm install -g @gptrf/cliRequires Node.js ≥ 20 (native fetch, File, FormData).
Authentication
The CLI authenticates against your gptrf.ru account via a browser device-flow login (not a developer API key):
gptrf auth login # opens a verification URL, then stores your session
gptrf auth status # shows the signed-in account (email / balance / plan)
gptrf auth logout # clears stored credentials (idempotent)gptrf auth login starts an RFC 8628 device flow: it prints a verification URL
(and opens it in your browser unless GPTRF_NO_BROWSER is set), you approve the
sign-in there, and the CLI stores the resulting account session locally. Token
refresh is transparent — an expired access token is refreshed and the request
retried under the hood; you never see or handle token material.
Credentials (a full account JWT pair) are written to an OS-appropriate, owner-only config file:
| OS | Path |
| ------- | ----------------------------------------------------- |
| Linux | $XDG_CONFIG_HOME/gptrf/credentials.json (~/.config/gptrf/…) |
| macOS | ~/Library/Application Support/gptrf/credentials.json |
| Windows | %APPDATA%\gptrf\credentials.json |
On Linux/macOS the file is created with 0600 permissions (owner read/write
only) inside a 0700 directory. On Windows it relies on the per-user
%APPDATA% ACL.
Command reference
gptrf auth <login|logout|status>
Authenticate and inspect your session. A bare gptrf auth is equivalent to
gptrf auth status.
| Subcommand | Effect |
| -------------- | ------------------------------------------------------------- |
| auth login | Device-flow login (account OAuth); stores the session. |
| auth logout | Clear stored credentials for the active profile (idempotent). |
| auth status | Show the current account: email, balance (₽), and active plan. |
gptrf model list [--category image|video|audio]
List the public model catalog (id, display name, category, price). A bare
gptrf model is equivalent to gptrf model list. Requires a signed-in session.
| Flag | Effect |
| -------------------- | ---------------------------------------------------------------- |
| --category <value> | Filter the catalog (forwarded verbatim; the server validates it). |
gptrf image \| video \| audio "<prompt>" -m <model> [options]
Submit a media generation job. These are aliases for
gptrf generate <image\|video\|audio> — both forms route to the same builder.
The positional argument is the prompt for image/video and the (required)
text for audio.
By default the CLI submits the job, prints the creation id and estimated cost
(to stderr), then auto-polls until the job reaches a terminal state and prints
the result URL(s). Use --no-wait to submit and return immediately.
| Flag | Kinds | Effect |
| ----------------------- | -------------- | -------------------------------------------------------------------- |
| -m, --model <id> | all (required) | Model id — see gptrf model list. |
| -n, --count <1-4> | image | Number of images. |
| --width <px> | image | Image width. |
| --height <px> | image | Image height. |
| --aspect-ratio <r> | image, video | e.g. 16:9, 1:1, 9:16. |
| --negative <text> | image, video | Negative prompt. |
| --image <file_id\|url> | image, video | Source image for edit / image-to-video (a gptrf upload id or URL). |
| --duration <sec> | video | Duration in seconds. |
| --voice <name> | audio (TTS) | Voice name. |
| --stability <0-1> | audio (TTS) | Voice stability. |
| --similarity-boost <0-1> | audio (TTS) | Voice similarity boost. |
| --style <0-1> | audio (TTS) | Voice style. |
| --speed <0.7-1.2> | audio (TTS) | Speech speed. |
| --timestamps | audio (TTS) | Return word/character timestamps. |
| --no-wait | all | Print the id immediately; do not poll for the result. |
| --idempotency-key <k> | all | Make this submit idempotent across re-runs. |
Notes:
- A flag not valid for the chosen media kind is rejected (not silently ignored) before any charge — so you never pay for a result that dropped a parameter you set.
- A value that starts with
-(e.g.--negative -grainy) must use the attached form:--negative=-grainy. - By default each run uses a fresh idempotency key, so re-running the same prompt
is a new generation. Pass
--idempotency-keyto make a submit replayable. - To upscale an image, use the dedicated
gptrf upscalecommand (→POST /images/upscale); upscaling is not agptrf imageflag.
Examples (model ids drift — discover real ones first with gptrf model list):
# discover real ids first:
gptrf model list --category video
gptrf model list --category audio
gptrf image "neon city at night" -m nano-banana --aspect-ratio 16:9
gptrf video "a drone shot over a forest" -m <video-model-id> --duration 5 --no-wait
gptrf audio "Привет, это тест озвучки" -m <audio-model-id><video-model-id> / <audio-model-id> are placeholders — replace them with a
real id from gptrf model list. (nano-banana is a real image model id.)
gptrf upscale <file_id|url> -m <model> [--factor 1|2|4|8]
Upscale an image (image-only). A prompt-less op — the input is the image: the
positional is an http(s) URL or a gptrf upload file id; -m/--model is
required. Maps to POST /images/upscale (Topaz / Recraft). Like gptrf image,
it submits, prints the creation id + estimated cost (to stderr), then auto-polls
to the result URL unless --no-wait.
| Flag | Effect |
| ----------------------- | -------------------------------------------------------------- |
| -m, --model <id> | Model id (required) — see gptrf model list. |
| --factor <1\|2\|4\|8> | Upscale factor (one of 1, 2, 4, 8). Rejected on remove-bg. |
| --no-wait | Print the id immediately; do not poll for the result. |
| --idempotency-key <k> | Make this submit idempotent across re-runs. |
gptrf remove-bg <file_id|url> -m <model>
Remove an image background (image-only), producing a transparent PNG. A
prompt-less op with the same positional/-m contract as gptrf upscale. Maps to
POST /images/remove-background. --factor is not valid here. Supports
--no-wait and --idempotency-key.
gptrf audio "<text>" | dialogue …
The audio command group. A bare gptrf audio "<text>" -m <model> is
text-to-speech (TTS) — the same builder as gptrf generate audio, mapping to
POST /audio/generate with the ElevenLabs voice controls (--voice,
--stability, --similarity-boost, --style, --speed, --timestamps). A
recognized first token routes to the ElevenLabs sub-op (maps to
POST /audio/<op>):
| Sub-op | Maps to | Key flags |
| ---------------------------------------- | ------------------- | ----------------------------------------------------------------------- |
| audio dialogue --turn "Voice:Text" … | /audio/dialogue | --turn (≥2, repeatable), --stability, --format, optional -m |
TTS and the sub-op support --no-wait and --idempotency-key. A flag not valid
for the chosen op is rejected before any charge.
The
sfx/transcribe/isolateaudio ops are closed and are no longer exposed by the CLI (kept: TTS +dialogue).
gptrf audio "Привет, это тест озвучки" -m <tts-model-id> --voice <voice> --stability 0.6
gptrf audio dialogue --turn "Alice:Hi!" --turn "Bob:Hello."gptrf upload <path> [--kind image|video|audio]
Upload a local media file and print the resulting file_id (consumable as
--image <file_id> for gptrf image / gptrf video).
| Flag | Effect |
| --------------------------- | ----------------------------------------------------------- |
| --kind image\|video\|audio | Media kind (default image). All three are supported. |
The public upload endpoint accepts image, video, and audio; an unrecognized
--kind is rejected locally with a clear message (no doomed request is sent).
Profiles
Switch between workspaces/accounts with --profile:
gptrf --profile work auth login
gptrf --profile work auth statusEach profile is stored in a distinct file (credentials.<name>.json) so
sessions never collide.
Environment variables
| Variable | Purpose |
| ------------------ | ------------------------------------------------------------- |
| GPTRF_BASE_URL | Override the API base URL (e.g. https://api-stage.gptrf.ru). Defaults to https://api.gptrf.ru. |
| GPTRF_CONFIG_DIR | Override the directory holding credentials files. |
| GPTRF_NO_BROWSER | When truthy (1/true/yes/on), auth login never opens a browser — it just prints the verification URL and waits. Useful for CI / headless / SSH sessions. |
Output & global flags
These flags are accepted in any position (before or after the command) and are stripped before the command sees its own arguments:
| Flag | Effect |
| ------------------ | ----------------------------------------------------------------------- |
| --json | Machine-readable JSON on stdout only; all progress/info → stderr. |
| --quiet | Suppress progress/info lines (errors and the primary result still show). |
| --profile <name> | Select the named credentials file (credentials.<name>.json). |
| --base-url <url> | Override the API base URL for this invocation. |
| -h, --help | Show usage. |
| -v, --version | Show the CLI version. |
--json and --quiet are applied centrally by the CLI. --profile and
--base-url are read by each command handler: a command loads credentials from
the selected profile's file and resolves its API base URL with --base-url
taking precedence over GPTRF_BASE_URL, the stored session URL, and the
default (in that order). A blank value (e.g. --base-url=) is ignored.
Stream discipline (so output is pipeable):
- human mode — the primary result goes to stdout; progress/info go to
stderr (so
gptrf ... > out.txtcaptures only the result). --jsonmode — the only thing on stdout is the JSON result/envelope; progress still goes to stderr; a script cangptrf ... --json | jqsafely.
Exit codes
Every invocation exits with a stable code so scripts can branch on the outcome (these are part of the CLI contract and will not change across releases):
| Code | Meaning |
| ---- | ------------------------------------------------------ |
| 0 | Success |
| 1 | Generic / internal error |
| 2 | Usage / invalid request (bad command or arguments) |
| 3 | Insufficient balance or quota exceeded |
| 4 | Rate limited (slow down / poll-interval guard) |
| 5 | Content-policy violation |
| 6 | Authentication failed — run gptrf auth login |
| 7 | Not found (unknown creation / model) |
| 8 | Generation failed |
On failure the CLI prints a single clean line — never a stack trace and never
token material. Under --json the failure is emitted as a structured envelope
on stdout instead:
{ "error": { "code": "ERR_INSUFFICIENT_BALANCE", "message": "…", "details": null } }Publishing
This package is publish-ready: it is @gptrf/[email protected] with
publishConfig.access = "public" (a @gptrf-scoped package would otherwise
default to a restricted/private publish).
Releases are owner-gated and run via the .github/workflows/cli-release.yml
workflow, which fires only on a manually-pushed cli-v* tag (e.g.
cli-v1.0.0). The workflow runs npm ci && npm test && npm run build, verifies
the tag matches package.json's version, then publishes with
npm publish --access public --provenance. It requires an NPM_TOKEN
repository secret (an npm automation token). No tag is pushed automatically and
no token is committed, so publishing always requires a deliberate owner action.
Locally, prepublishOnly runs npm run build && npm test as a safety gate on
any manual publish.
License note: this package ships under a proprietary license (see
LICENSE). The exact legal text is an owner decision and is pending owner confirmation before any real publish.
