@zergai/zrouter
v0.4.0
Published
Local Codex account and workspace routing client for ZergRouter
Readme
ZergRouter CLI
zrouter keeps personal Codex subscription credentials on the local machine and
uses ZergRouter only for personal Router API credentials, typed provisioning
requests, and bounded account telemetry. It never uploads or reads a Codex
auth.json file.
Install the public npm package with Node.js 22 or newer:
npm install --global @zergai/zrouter
zrouter --version
zrouter codex --help
zrouter login
zrouter codex account add personal
zrouter codex account use personal
zrouter codex -- exec
zrouter codex configure gpt-5.6
codex --profile zergrouterNo private repository access is required. The CLI is a client of the hosted service; you do not need to start a Router server. The manual setup guide also works with a Router API key without installing this CLI. Do not install similarly named npm packages.
The zrouter-cli-v0.1.0 release is published as @zergai/[email protected].
This uses the zergai npm organization,
owned by idanbeck (the same account that maintains zerg-ztc).
The installed commands remain zrouter and zergrouter.
Maintainers publish only by pushing a
zrouter-cli-v<package-version> tag whose commit is already merged into
development; the release-zrouter-cli.yml workflow validates, packs, and
smoke-tests the exact tarball before publishing it through npm trusted
publishing. (npm provenance is intentionally not requested while the source
repository is private.) Because npm cannot configure a trusted publisher
until the package exists, the protected npm-publish-zrouter environment needs a
short-lived granular NPM_TOKEN for the first publication only, limited to the
@zergai scope/package with Read and write plus Bypass 2FA enabled. The
token must belong to idanbeck; being signed into GitHub does not authenticate
npm. Configure that
workflow as the package's trusted publisher immediately afterward—organization
Epoch-ML, repository zerg, workflow release-zrouter-cli.yml, environment
npm-publish-zrouter, with npm publish allowed—then immediately revoke/remove the
bootstrap token and set the npm package's Publishing access to Require 2FA and
disallow tokens (trusted publishing via OIDC remains allowed). Before pushing
the first tag, verify the publisher is idanbeck using npm whoami and require
PR review plus passing CI. This private repository's GitHub Team plan does not
support environment reviewers, so the human release approval is idanbeck
manually creating the version-matching tag on the reviewed, merged commit.
Repository rulesets restrict creation of zrouter-cli-v* tags to idanbeck and
prevent updates and deletion, including by the creator. The npm-publish-zrouter
environment allows only selected release tag patterns. Never use administrator
merge bypass or create a release tag automatically from an implementation request.
Useful lifecycle commands:
zrouter auth status
zrouter --help
zrouter --version
zrouter agent install
zrouter agent status
zrouter agent sync
zrouter logoutCodex with DeepSeek V4.1 Flash through Router
This is separate from codex account subscription monitoring. Codex runs tools
and approvals locally; Router handles inference, authentication and usage.
Use Codex 0.146+ (acceptance-tested with 0.155.1) and Node 22+.
zrouter login
zrouter codex models
zrouter codex configure --model modal/deepseek-v4.1-flash
zrouter codex doctor --model modal/deepseek-v4.1-flash
codex --profile zergrouterThe CLI writes a managed zergrouter.config.toml profile and, for the recognized
DeepSeek V4.1 route, zergrouter.models.json. Both are owner-only. It preserves
your base config and credentials and refuses to overwrite unmanaged files.
The preset enables freeform apply_patch, a 1,048,576-token context window,
image input and low / high / xhigh / max reasoning. The default reasoning
effort stays high; higher effort is opt-in through Codex's model picker or:
codex --profile zergrouter -c 'model_reasoning_effort="max"'These are the registered Modal endpoint's advertised options; Router forwards
the selected value unchanged. They are not a claim that DeepSeek's direct API
has four distinct strengths (its documented xhigh alias maps to high).
If only low/high appear, update the CLI, rerun the same zrouter codex configure
command (including --api-key-env / --codex-home if used), and restart Codex.
Updating the npm package alone does not refresh an existing on-disk catalog.
For manual setup, re-download the platform's model catalog instead.
Codex may use exec_command instead of shell_command when unified execution
is enabled; both are ordinary function tools and remain local.
For a Router API key instead of browser login, load it into an environment variable from your secret manager, then use:
zrouter codex models --api-key-env ZERGROUTER_API_KEY
zrouter codex configure --model modal/deepseek-v4.1-flash --api-key-env ZERGROUTER_API_KEY
zrouter codex doctor --model modal/deepseek-v4.1-flash --api-key-env ZERGROUTER_API_KEY --probe
codex --profile zergrouterNever pass the key itself as an argument. Keys need models:read and
chat:write, access to the selected route, and sufficient budget. --url
selects a different Router origin (HTTPS, except loopback); configure
--codex-home /absolute/path selects a different profile directory. Launch
Codex with that same CODEX_HOME. Omitting --model on configure preserves
the existing gpt-5.6 default; it does not auto-select DeepSeek.
doctor without --probe checks installed Codex version and model access only.
--probe makes up to five billable requests: streamed text, function call
and simulated result replay, then native custom patch and simulated result
replay. It executes no shell commands or file edits and stops at the first
failure. Exit status 1 means a check failed. This is a compatibility diagnostic,
not a guarantee of coding quality or availability for every future request.
Use the exact ID returned by models. The stable DeepSeek alias and the known
exact Modal endpoint have presets; arbitrary models do not inherit DeepSeek
metadata. Router bridges only Modal's apply_patch custom tool to a function
and back. Full conversation history with store=false is required. Chat-only
providers, arbitrary custom tools, hosted web search and stored continuation
are not supported by this integration.
For setup without the management CLI, use the public manual Codex guide and downloadable catalog.
Return to normal Codex and login
The Router profile is opt-in: exit the current session and run plain codex
without --profile zergrouter to use your base configuration and existing login.
Start a new session when changing provider; this does not migrate a conversation.
To also archive the CLI-managed Router setup:
zrouter codex restore
# Optional: restore, then start native Codex login (no forced logout)
zrouter codex restore --login
# Optional headless login
zrouter codex restore --login --device-authRestore does not require a Router login or selected local account. It validates
the base config before changing files, archives only CLI-managed
zergrouter.config.toml and zergrouter.models.json into a new owner-only
zrouter-restore-backup-… directory in the Codex home, and removes only an owned
legacy managed block (saving the original config.toml first). It preserves
unrelated settings, authentication, local accounts, Router login and the agent.
Repeated restores are safe. configure can recreate the Router profile later.
The result's first stdout line is JSON with backup location and archived names.
--codex-home /absolute/path overrides CODEX_HOME / ~/.codex for both restore
and optional login; use the same CODEX_HOME when launching Codex afterward.
No login is started unless --login is explicit. Failed login leaves the restore
complete, reports the Codex exit status, and retains the backup for recovery.
Run codex login or codex login --device-auth manually to retry.
Unmanaged profiles, symlinks, malformed config and manual base provider/model/
catalog overrides are refused before any active files change. Review those
manually; do not use restore as a factory reset. For the separate manual profile
in our guide, plain codex already avoids it. Unset/review OPENAI_BASE_URL and
shell aliases yourself; restore cannot modify your parent shell or administrator
requirements. It never runs codex logout or deletes auth.json.
Platform administration
Platform and shared-workspace administration use a separate, origin-bound
admin session. The CLI exchanges a ZergAI token read only from standard input
for a bounded five-minute router session; it never accepts that token as a
command-line argument, persists it, or replaces the inference/device credential
used by zrouter auth token. On systems without an OS credential store,
explicitly add --allow-file-token to permit a mode-0600 fallback for the
returned session.
Provider discovery, provider policy, and model-catalog commands require a ZergAI platform-superuser session. Shared-workspace administrators can manage only the credential pools and provider secrets for the workspace carried by their admin session; they cannot read or mutate platform-wide provider or model state.
The admin credential and secret routes moved to the explicit /api/admin/
namespace with this release. Upgrade the CLI before upgrading the Router
server—pre-release CLIs use the retired personal-route aliases and will receive
403 responses from the hardened server.
zrouter admin login --url https://zergrouter.com --token-stdin < /secure/path/zergai-token
zrouter admin status
zrouter admin provider list
zrouter admin provider get openai
zrouter admin provider check openai
zrouter admin provider sync openai
zrouter admin provider sync-policy openai
zrouter admin provider sync-policy openai --cadence 6h
zrouter admin credential list
zrouter admin credential add openai --label Primary --priority 10 --secret-stdin < /secure/path/openai-key
zrouter admin credential update credential-id --label Rotated --secret-stdin < /secure/path/openai-key
zrouter admin credential enable credential-id
zrouter admin credential disable credential-id
zrouter admin credential probe credential-id
zrouter admin credential remove credential-id --yes
zrouter admin secret list
zrouter admin secret set modal --secret-stdin < /secure/path/modal-token
zrouter admin secret clear modal --yes
zrouter admin model list --provider openai
zrouter admin model add openai gpt-5.6 --display-name "GPT-5.6"
zrouter admin model update model-id --enable --failover
zrouter admin model default openai gpt-5.6
zrouter admin model check model-id
zrouter admin model deactivate model-id --yes
zrouter admin logoutAdmin command results are JSON. Provider discovery cadences are off, 1h,
6h, 24h, or 7d; omitting --cadence reads the current policy. Credential
removal and model deactivation require --yes. Provider secret material is
accepted only with --secret-stdin and is recursively removed from output,
including if an upstream API accidentally echoes a secret-bearing field.
Most providers use the multi-credential pool. Modal's shared endpoints use the
single platform-secret lane, exposed only through admin secret set modal and
admin secret clear modal; other providers are rejected from that lane.
zrouter agent install immediately loads and enables an outbound-only local
agent. It supports macOS launchd and Linux systemd user services and rejects
temporary and npx paths for the CLI, Node, Codex, state, and service definition,
including symlinks into those directories. Install the package in a permanent
location (for example a global npm installation), and keep ZROUTER_HOME outside
the OS temporary directory. An invalid installation leaves the existing service
definition untouched. Reinstalling explicitly enables a previously disabled
macOS agent; launchd retries are throttled to once per minute. The
agent polls ZergRouter for strictly typed account-login requests and refreshes
telemetry every five minutes; it does not expose a local port. The worker uploads
only masked identity, plan, state, rate-limit windows, and bigint-safe aggregate
token counts. ChatGPT access and refresh tokens remain inside the selected local
CODEX_HOME.
zrouter agent uninstall unloads and removes the service registration, including
the legacy Linux timer. It retains account data and credentials, works when the
old executable has disappeared, and can be repeated. To replace a stale macOS
installation, run uninstall from a permanent CLI installation followed by
zrouter agent install. A manually renamed .plist.disabled backup remains
untouched.
Once the CLI is paired and the agent is running, My Codex on the ZergRouter dashboard can provision a new isolated account on that device. The local agent uses Codex app-server's official device-code login and reports only short-lived progress plus the safe snapshot after completion. Device sessions created before this capability must be paired again before the dashboard enables provisioning.
zrouter codex configure writes the Codex 0.146+ profile layer at
$CODEX_HOME/zergrouter.config.toml; it does not replace the user's base
config.toml. Use zrouter auth token only as Codex's command-backed auth
provider: stdout is the bearer token and nothing else.
Router device sessions expire after 90 days. Re-run zrouter login when
zrouter auth status reports an expired session or the dashboard snapshot goes
stale. If the device itself was revoked in the dashboard, use
zrouter login --new-device to deliberately create a fresh device identity.
zrouter logout revokes the current remote token and always clears the
local credential; zrouter logout --local-only intentionally skips remote
revocation. On systems without an OS credential store, login requires the
explicit --allow-file-token flag for a mode-0600 local fallback.
Updating the npm CLI
Run zrouter update or zrouter --update to install a newer npm
release. zrouter update --check prints JSON without installing. The
installed channel is preserved (dev, next, or latest); select a channel
explicitly with update --channel dev|next|latest. Updates never downgrade.
Startup checks only notify on stderr when it is a terminal, never prompt or
install, and are cached for one hour. CI, redirected stderr, and help/version
requests skip checks. Set ZERGAI_NO_UPDATE_CHECK=1 to disable startup checks.
Self-installation requires the matching macOS/Linux global npm prefix; local,
linked, npx, or other package-manager installs must use their original manager.
Existing releases need one ordinary npm upgrade before these commands exist.
See shared updater policy for installation safety, channel switching, and packaging details.
