Status: foundation contract established by the Wayfinder ticket Task: scaffold the regru CLI contracts. Resource-specific flags and provider result schemas remain owned by their implementation tickets.
regru is a human-friendly and agent-safe CLI for the REG.RU services used by
this project. It is distributed as one Go binary.
regru [global flags] <command> [subcommand] [arguments]
The visible command tree is:
regru auth login|status|refresh|logout
regru account add|list|show|use|remove|doctor
regru capability list|probe
regru vps list|get|ips|create|rename|start|stop|reboot|rebuild|resize|password-reset|clone|delete
regru vps action show|wait
regru vps ip list|show|add|ptr|remove
regru vps ssh-key list|add|rename|remove
regru vps snapshot list|create|remove
regru vps backup status|enable|disable|restore
regru vps plan list|show
regru vps image list|show
regru s3 service show
regru s3 service quota set
regru s3 bucket list|show|create|update|delete
regru s3 bucket policy|cors|lifecycle|website get|set|delete
regru s3 bucket versioning get|set
regru s3 credentials list|create|revoke
regru billing balance|history
regru billing invoice list|show|status|create|delete|payment-link
regru billing invoice payment-method list|set
regru support ticket list|get|create|reply|attach|close|reopen
regru completion bash|zsh|fish|powershell
Commands remain visible in help and completion before their adapters are
implemented. A live unavailable command fails closed with a structured
capability_unavailable error and exit code 7.
| Flag | Contract |
|---|---|
--account NAME |
Select one local account profile. Falls back to REGRU_ACCOUNT; no command prompts for an account name. |
--json |
Emit exactly one versioned JSON success or error envelope. Mutually exclusive with --plain. |
--plain |
Emit stable line-oriented text. Mutually exclusive with --json. |
--no-input |
Disable all prompts and interactive login. Read-only commands may still run. |
-n, --dry-run |
Validate locally and render a redacted mutation plan with zero executor, provider, browser, DNS, or network calls. |
-f, --force |
Satisfy the confirmation requirement for a requested mutation. It never bypasses capability, authentication, identity, drift, timeout, or redaction checks. |
--no-color |
Disable ANSI color. Color is also disabled for non-TTY stderr, NO_COLOR, or TERM=dumb. |
--timeout DURATION |
Bound one network operation. Default 30s; must be greater than zero and no more than 5m. |
-h, --help |
Show command help. |
--version |
Print the binary version to stdout. |
auth login additionally has --login-timeout, defaulting to 10 minutes and
bounded to 1–30 minutes.
CloudVPS commands use --timeout for each credential or HTTP request and
--wait-timeout for the complete asynchronous action wait. The wait defaults
to 10 minutes and is bounded to 1 second–24 hours. Mutations wait by default;
vps --no-wait ... returns the accepted action without polling. See the
CloudVPS command guide.
REG.RU S3 commands use separate private-control-plane and signed-protocol
adapters; see the S3 command guide.
Billing commands preserve the boundary between REG.API invoices and CloudVPS
finance; see the billing command guide.
Support commands expose a typed experimental boundary but currently fail closed
with operation-specific reasons; see the support command guide.
Account selection follows this precedence:
--account > REGRU_ACCOUNT > project account > user default > no selection
User profiles live in the platform user-config directory. A project
.regru/config.toml may only select an existing account alias; it cannot
define profiles, endpoints, session handles, or credential routing. Secrets,
cookies, browser storage, CSRF values, and service credentials are never
accepted as flags, environment variables, or normal config.
capability probe checks only provider surfaces for which the selected profile
has local credential or portal routing. The current bounded checks cover portal
session status, CloudVPS authentication through a balance-shape read, REG.API
billing through a balance-shape read, the REG.Cloud S3 semantic probe, and the
experimental support adapter gate. Each check is capped at five seconds or the
shorter command timeout. A failed check does not hide successful siblings:
human, JSON, and plain output report partial availability using only normalized
capability, state, and reason fields. Provider response bodies, balances,
resource collections, identifiers, request IDs, and adapter messages are
discarded before rendering.
auth login opens a headed Chrome or Chromium process with a dedicated profile
owned by the selected local account. Authentication fields, CAPTCHA, and
second-factor challenges stay in that browser. A successful provider refresh
is reduced in an isolated browser world to an opaque keyed principal digest
plus the provider's screen_name, exposed as the REG.RU provider login. The
provider user ID, cookies, CSRF values, and response body never leave that
world.
Each login is staged in a new browser profile. It replaces the committed
session reference only after authentication and principal matching succeed, so
cancellation, timeout, contract drift, and account mismatch preserve the
previous session. --force requests a fresh staged login; without it, an
already active session is returned unchanged.
auth status and auth refresh both perform an authoritative provider refresh
inside the committed browser profile. This may extend the provider session.
After every successful auth login and every active auth refresh, the CLI
also reconciles the public IPv4 addresses observed by the browser session and
the CLI's REG.RU-hosted egress probe with the REG.API allowlist. If existing
addresses or networks already cover them, no mutation is sent. Otherwise the
missing addresses are added through REG.RU's own account contract without a
separate prompt; that provider flow can invalidate other
REG.RU web sessions. The address, allowlist, CSRF material, and provider response
remain inside the isolated browser world. Synchronization failure does not turn
a valid portal login or refresh into an authentication failure: it adds only
the stable, redacted regapi_ip_sync_failed warning. auth status does not
modify the allowlist.
Their stable state values are not-established, active, and session-lost;
the latter deliberately does not guess whether the provider invalidated the
session because of expiry, logout elsewhere, revocation, or another cause.
An active result keeps the local profile alias in account and reports the
freshly observed REG.RU login separately as providerLogin. Human output labels
it REG.RU login; plain output appends provider_login=<escaped-login> to the
existing account and state fields. A missing or non-string login in an otherwise
authenticated probe is private-contract drift, not an empty or guessed login.
auth logout removes local browser state only after the provider confirms that
the session is gone. An ambiguous logout keeps the local reference and returns
outcome_unknown.
Normal config stores only an opaque s_... session reference. The observed
provider login is not written to normal config or browser-session metadata.
Browser state lives beneath <UserConfigDir>/regru/portal-sessions, separately
for every account, with an OS-backed exclusive lock while in use. The directory
is private to the current OS user but is intentionally not wrapped in
application-managed encryption.
Portal-session failures use stable codes including missing_browser,
login_cancelled, portal_profile_busy, authentication_expired,
account_mismatch, browser_session_interrupted,
private_contract_drift, and outcome_unknown. Successful active auth output
contains the account alias, provider login, reduced state, and currently
verified capability names. It never contains the provider user ID, identity
digest, opaque session reference, browser profile path, cookies, CSRF values,
browser storage, tokens, or credential-process fields.
An account may configure an external credential helper in the user-only profile:
[accounts.work.credential_process]
command = ["/usr/local/bin/credential-helper", "get", "work"]regru starts this argv directly, without a shell, only when a provider
adapter requests a credential. Help, completion, local validation, dry-run,
unimplemented commands, and adapters that do not request credentials never
start it. The helper has a 30-second maximum runtime, further bounded by the
command timeout.
The helper returns one strict, bounded JSON document on stdout using the
internal regru.credential-process/v1 protocol. Its stdout is captured rather
than inherited, and its stderr is discarded. Failures are rendered as stable
regru error codes without helper output. The command and its arguments are
user-owned routing metadata, not secret values; credentials must never be
placed in them. A project config cannot define or replace the helper.
Primary success data goes to stdout. Diagnostics, progress, browser-launch notices, prompts, and final errors go to stderr. Cobra handlers do not print errors; the process runner renders each final error exactly once.
Human output may evolve for readability. --plain and the JSON schema are
automation contracts.
JSON success:
{
"schemaVersion": "regru.cli/v1",
"ok": true,
"command": "auth status",
"data": {
"account": "personal",
"providerLogin": "provider-login",
"state": "active",
"reason": "",
"capabilities": ["auth.browser_session"]
},
"warnings": []
}JSON error:
{
"schemaVersion": "regru.cli/v1",
"ok": false,
"command": "vps list",
"error": {
"code": "network_error",
"message": "CloudVPS rejected the request",
"exitCode": 6,
"retryable": false,
"details": {
"provider": "CloudVPS",
"provider_code": "VALIDATION_ERROR",
"http_status": 400
}
}
}Plain success is one stable record per line. Plain errors use
code<TAB>message on stderr. vps backup status <server-id> --plain emits
server-id<TAB>backups-enabled<TAB>last-backup-date; the enabled field is
true or false, and the date field is empty when the provider returns null.
The established five-field vps get --plain record is not extended with backup
fields.
| Exit | Meaning |
|---|---|
| 0 | Success or a completed local dry-run |
| 1 | Unexpected/internal failure |
| 2 | Invalid invocation or flag value |
| 3 | Missing or invalid local configuration |
| 4 | Interaction or confirmation required |
| 5 | Authentication or account-identity failure |
| 6 | Network/provider failure |
| 7 | Capability unavailable or not implemented |
| 8 | Private provider contract drift |
| 10 | A mutation may have committed but cannot yet be verified |
| 124 | Operation deadline exceeded |
| 130 | Interrupted by Ctrl-C |
More precise automation decisions use the stable error code, not only the
process exit value.
Fresh browser login requires a TTY on stdin and fails before acquiring a
browser or adapter when --no-input is set or stdin is not a TTY. Normal
noninteractive commands never launch a browser implicitly.
Mutations require a TTY confirmation or --force. --dry-run occurs before
confirmation and before the injected executor, so it cannot make a provider,
portal, S3, browser, BFF, or CDP call. Dry-run output reports only the account
alias, operation name, and argument count; it does not echo opaque identifiers
or paths.
The process root is canceled on Ctrl-C. The first interrupt propagates through the command context; signal interception is then removed so a second Ctrl-C uses the platform's immediate exit behavior. All operation waits are bounded.
regru --help
regru --version
regru --account personal auth status --json
regru --account personal --no-input billing balance --plain
regru --account personal vps plan list --region openstack-msk3
regru --account personal --dry-run vps create --size cloud-2 --image ubuntu-24-04-amd64 --region openstack-msk3
regru --account personal --force vps action wait action-id --wait-timeout 20m
regru --account personal --force auth logout
regru completion zsh