Skip to content

CLI

Commands, arguments, environment variables, lifecycle behavior, and exit statuses.

The @usine/server package provides usine. Run commands from the instance folder, where .usine/runtime.sqlite stores configuration and run history. Each command reads .env before resolving its environment. usine --help prints usage; usine --version prints the installed release.

OptionTypeDefaultDescription
-p, --portinteger, 1–65535USINE_PORT, then 7331HTTP port on 127.0.0.1.
--originHTTP or HTTPS originUSINE_ORIGIN, then loopbackCanonical browser address without a path, query, or fragment.
--log-leveltrace, debug, info, warn, or errorUSINE_LOG_LEVEL, then infoMinimum log level, without case sensitivity.
--allow-volatile-instanceflagoffPermit an instance folder under temporary storage.
--detachflagoffStart a detached process with output in .usine/usine.log.
Terminal window
usine up
usine up --detach --origin https://usine.example.com

Startup takes the instance lock, opens the listener, applies runtime database migrations, loads stored configuration, reads App and worker credentials, checks workers, and recovers attempts. Recovery visits every attempt that still has tracked leftovers on a configured worker and logs one summary per worker with the attempts visited, and how many of them had leftovers that recovery found and reconciled, or kept for their run (kept), failed to reconcile (failed), kept tracked with nothing left on the worker (empty), and discarded (discarded). Reconciling a finished attempt’s checkout removes it when its salvage is pushed or it has nothing to salvage. A checkout whose salvage is retained, partly pushed, or rejected stays on the worker, and each later start reconciles it again and counts it as kept. The next start discards an attempt once nothing of it is left. A finished attempt that has nothing left on its worker is discarded, so later starts skip it: its checkout is gone, and so is its machine when the worker creates one per attempt. On a worker with a long-lived machine, such as an SSH worker that runs attempts in containers, a missing checkout is enough. Open attempts and attempts whose recovery failed stay tracked. On SSH workers, the first preparation after a start logs one warning with the number of unrecognized paths under attempts/, excluding the checkouts of attempts being reattached; the paths are logged at debug level. Empty configuration tables accept a bootstrap import or initialize empty setup configuration. Import and export format describes bootstrap input. Later starts read the database.

The listener answers from the moment it accepts connections, in setup mode too. Until the instance has started, every request returns HTTP 503 with Retry-After: 1. The instance has started when migrations are applied, configuration is loaded, the admin token is written, and either setup mode serves its routes and has logged the sign-in line, or runtime startup begins its worker checks and attempt recovery. From then on, GET /api/version returns the running release. In runtime mode, every other request returns HTTP 503 with Retry-After: 1 until recovery finishes and the runtime routes are installed; GET /api/ready then returns HTTP 200. Startup responses close the connection. When setup completes, the listener keeps the port and returns the same responses until the runtime routes are installed.

Missing or invalid App credentials start setup mode. Polling and schedules stay idle until setup completes. Worker preflight failure stops runtime startup. The App secrets file, .usine/github-app.json, must be a regular file with mode 0600; environment values override corresponding file fields.

A second process cannot run the same instance folder. Temporary paths are refused by default because runtime state needs persistent storage. On macOS, startup warns if system sleep can interrupt remote sessions. Logs use ISO 8601 UTC timestamps.

Session usage and pool rate-limit projection updates, including pool reset scheduling decisions, log at Debug. Use usine up --log-level debug or USINE_LOG_LEVEL=debug to include these per-report diagnostics. Reaching a pool reset deadline logs at Info.

A detached start retains the selected Node binary, options, entry point, and launch flags. It returns when the new process holds the instance lock and GET /api/version returns HTTP 200, so the instance has started as described above: the admin token exists, and setup mode answers requests. It doesn’t wait for attempt recovery; poll GET /api/ready for that. If the process exits first, the command fails and prints its exit and the log tail. After 120 seconds without a start or a new log line, the command reports a timeout while the process can still be starting. Logs have owner-only permissions and require operator-managed rotation.

.usine/instance.json records PID, release, start time, launch settings, systemd unit or launchd service target when applicable, and drain start time. The lock determines whether a process owns the instance; stale process records are replaced on the next start. .usine/instance-id identifies attempt containers and must remain with the instance during moves and restores.

Lifecycle commands verify that the recorded unit owns the process. They use systemctl stop --no-block and systemctl start to preserve service management. Service starts use the service environment and the instance .env. The service user needs authorization to manage the unit. See server deployment.

Set USINE_LAUNCHD_SERVICE=gui/<uid>/<label> in the instance .env and install the matching ~/Library/LaunchAgents/<label>.plist. up records the target only when launchctl print reports its PID. stop uses bootout; restart uses bootout, bootstrap, and kickstart. up --detach starts the configured job, loading its plist if needed, and uses its configured arguments. Commands run as the owning user in the login session. status uses print to verify supervision and reports launchctl failures. A failed start unloads a job waiting to retry. See macOS deployment for both jobs, login requirements, and log paths.

Connect Claude or ChatGPT while usine up runs, from the instance folder:

Terminal window
usine login claude
usine login chatgpt
usine login chatgpt --api-key
usine logout claude
usine logout chatgpt --target usine-gateway

Both commands read connection status from the running instance and authenticate with its local .usine/admin-token. Run them as the user who started the instance. Subscription login polls until authorization completes; logout disconnects the selected provider immediately.

--target <SSH destination> selects one gateway when several are configured. With one gateway, usine selects it automatically. With none, it stores credentials where the local Claude Code and Codex harnesses read them, honoring CLAUDE_CONFIG_DIR and CODEX_HOME.

Local preflight and attempt children use the same credential directories. If one gateway is unavailable, Settings shows its error while other gateways remain usable. --target can select a healthy gateway independently.

Local preflight and children accept subscription credentials and API keys. Claude setup tokens count as subscription credentials. Children report API-key usage in the API keys pool and subscription usage in the matching plan pool.

Without a gateway, usine checks each provider separately using the PATH of the user running usine up. A missing claude or codex command makes its provider unavailable and displays an installation instruction in that provider’s row. usine login reports the same instruction before starting authorization. The other provider remains available when its harness is installed, so an instance can install only one harness, as the quickstart does. Local provider availability changes log once at Info; repeated polls with the same error produce no additional log entries.

Local Claude status uses claude auth status --json, including macOS Keychain logins. Disconnect runs claude auth logout, removes usine’s settings overrides and file credentials, and verifies that Claude reports signed out. It clears the native login for the configured Claude directory, including an older login that a replacement credential overrides.

Local Codex preflight and children use file credential storage, overriding cli_auth_credentials_store in Codex configuration. Connect replaces $CODEX_HOME/auth.json (~/.codex/auth.json by default), and disconnect removes it. Keyring credentials remain available to Codex commands run outside usine. To sign in directly for usine, run codex -c 'cli_auth_credentials_store="file"' login --device-auth.

Subscription sign-in uses the installed Claude Code setup-token command or Codex login --device-auth command in a private temporary directory. Claude requires script and a code from its authorization page. Codex displays a device code for authorization in another browser. --api-key reads a masked key from the terminal. Ctrl+C cancels subscription sign-in. Failed or cancelled authorization preserves the previous login.

Gateway transfers use its authenticated admin API over SSH and require curl on the gateway. Managed credentials persist in its state directory with mode 0600, take precedence over environment credentials, and apply without reloading the service. ChatGPT refreshes use the gateway’s existing token refresh and atomic auth-file replacement. Worker routing changes are configuration revisions. Logout disables the managed provider and removes its routing from workers.

Instance admins can use the same controls in setup and Configuration > Settings > Provider connections. Expiry and last refresh show the provider’s reported values as local dates and times; opaque Claude setup tokens report neither. Pi children, and the Pi parent of coordinator: session agents, authenticate with a separate Pi login.

ArgumentTypeDefaultDescription
nonenoneinstance folderReport the owning process, listener, version, uptime, open runs, and supervising service.
Terminal window
usine status

The command exits with 0 for an owned instance and 3 when stopped. It identifies stale process records and reports an active drain.

OptionTypeDefaultDescription
--timeoutinteger seconds > 0120Wait for the process to exit before reporting a timeout.
--forceflagoffStop without waiting for attempts and send SIGKILL if the process exceeds the timeout.
Terminal window
usine stop --timeout 300

The first stop request stops admission and drains running attempts. A command timeout leaves the drain active. Another ordinary stop waits without escalating; --force sends the second termination signal. A stopped instance returns success.

Ctrl+C or SIGTERM starts a drain. Its deadline uses settings.max_attempt_minutes when set. A second signal stops immediately. Retained Pi parent tasks and checkouts can reattach on the next start. If a task cannot be confirmed stopped, its slot remains reserved and reconciliation retries rather than starting duplicate work.

OptionTypeDefaultDescription
--timeoutinteger seconds > 0120Maximum wait for stop and restart lifecycle operations.
--forceflagoffPermit interruption and later reattachment of active attempts.
Terminal window
usine restart

Restart requires a running instance and retains its launch flags. It refuses active attempts unless forced and verifies required gateway credential variables before stopping. A detached restart appends to .usine/usine.log; systemd and launchd instances restart through their service manager. The new process reads the instance environment again. Restart returns when the new process has started, by the same rule as a background start, and fails if the new process exits or its service stops first.

Argument or optionTypeDefaultDescription
<version>registry version, range, or tagconfigured channel for managed global installs, otherwise latestRelease to install.
--channellatest or nextconfigured channelnpm channel for managed global upgrades.
--checkflagoffReport versions without changing packages or process state.
--timeoutinteger seconds > 0120Lifecycle wait for local pin upgrades.
--forceflagoffRestart immediately and reattach active attempts.
Terminal window
usine upgrade --check
usine upgrade

For a global installation managed by systemd or launchd, the command requests the separate upgrade helper and exits after acceptance. The default waits for admitted attempts to finish. Settings and the helper’s journal or log report the final outcome. The helper backs up stores, installs, restarts, and checks version and readiness. Installation or readiness failure restores the prior package and databases.

For an instance-local registry pin, upgrade backs up stores in .usine/backups/, changes package pins, installs with the instance package manager, commits manifest and lockfile changes, and restarts if the instance was running. It refuses active attempts unless forced. Failed installation restores manifests and lockfiles and leaves the instance stopped. Startup failure prints recovery instructions. A stopped instance receives the package update without starting.

A checkout installation requires updating and building its checkout, then restarting. Upgrade an instance describes the procedure.

ArgumentTypeDefaultDescription
<path>new file pathrequiredDestination for the runtime database backup.
Terminal window
usine backup /backups/instance.sqlite

The command creates a compact runtime snapshot with VACUUM INTO while the instance runs and syncs the file and destination directory before reporting success. Durable storage uses SQLite’s backup API. It copies durable storage first and the runtime store second, with owner-only permissions, and refuses an existing destination. The directory must exist and support hard links. A runtime backup failure removes the durable copy. An instance without durable storage produces only the runtime copy and reports it.

The durable path inserts .durable before .sqlite or .db, or appends .durable.sqlite for another extension. Backups omit credentials and connection-record files. See Back up instance state.

Argument or optionTypeDefaultDescription
<runId>run IDrequiredRun to read from the runtime store.
-o, --outputnew file pathURL-encoded run-<runId>.jsonDestination for run evidence and transcript.
Terminal window
usine export-run <run-id> --output /evidence/run.json

The command reads a snapshot without starting execution. JSON contains version, exportedAt, snapshot, and transcript, including event, approval, attempts, results, and effective definitions. The file has mode 0600; an existing path or unknown run is an error.

ArgumentTypeDefaultDescription
<origin>instance originUSINE_ORIGIN, then http://127.0.0.1:<port>Instance that issues the device token after GitHub authorization.
Terminal window
usine sign-in https://usine.example.com

Open the printed device page and enter the code. The token appears once. Store it securely and send it as a bearer token. Its permission ceiling is limited by current role bindings. See Create a device token.

ArgumentTypeDefaultDescription
nonenonelocal running instanceIssue a private one-time browser sign-in URL using local admin access.
Terminal window
usine sign-in-link

The URL works once within ten minutes. Local lifecycle and link commands require a regular .usine/admin-token owned by the current user with mode 0600. Startup replaces that file. See Access.

OptionTypeDefaultDescription
--origin <url>instance originrunning instance of the current folderInstance whose operator tools to serve. With --origin, the command sends USINE_TOKEN; without it, it uses .usine/admin-token.
Terminal window
USINE_TOKEN=<token> usine mcp --origin https://usine.example.com

The command serves the operator API as MCP tools over standard input and output, for a client that starts it as a local command. At start, it reads the instance’s /api/openapi.json and the token’s session, and lists only the tools that the token permits. It refuses a start response over 8 MiB, one that takes over 30 seconds, or one that nests arrays and objects over 256 levels deep or holds over 200,000 of them, before decoding it. It inlines schema references until the input schemas of the whole document hold 500,000 characters of JSON, at most 32 references deep, and at most 64 levels of arrays and objects deep; past any of these limits, the schema accepts any value at that point and a warning is logged. It sends the token only to the origin: a tool call whose URL resolves to another host returns an error result. It writes its logs to standard error. See Connect an MCP client.

usine config documents export, import, edit, and log. These commands access the local database directly and save configuration revisions.

VariableTypeDefaultDescription
USINE_LAUNCHD_SERVICEgui/<uid>/<label>noneLaunchAgent target for supervised detached starts and lifecycle commands. The matching plist is in ~/Library/LaunchAgents/.
USINE_PORTinteger, 1–655357331Port used when --port is absent.
USINE_ORIGINoriginloopback listenerCanonical origin used when --origin is absent.
USINE_LOG_LEVELlog levelinfoMinimum log level used when the flag is absent.
USINE_ALLOW_VOLATILE_INSTANCE1offEquivalent to --allow-volatile-instance.
USINE_TOKENsecret stringnoneInstance token that usine mcp --origin sends.
TMPDIRpathOS defaultAdditional path considered temporary by the volatile-instance check.
USINE_GITHUB_APP_IDpositive integerApp secrets fileGitHub App ID.
USINE_GITHUB_PRIVATE_KEYPEM stringApp secrets fileApp RSA private key in RSA-specific or generic PEM encoding.
USINE_GITHUB_CLIENT_IDstringApp secrets fileApp client ID for member sign-in.
USINE_GITHUB_CLIENT_SECRETsecret stringApp secrets fileApp client secret for member sign-in.
USINE_GITHUB_WEBHOOK_SECRETsecret stringApp secrets fileSignature secret for endpoint webhook hints.
PI_CODING_AGENT_DIRpath~/.pi/agentConfiguration and credential directory of Pi children and of the Pi parent of coordinator: session agents.
Worker credential variable namessecret stringsrequired when configuredProvider tokens, API keys, gateway admin tokens, and Access credentials referenced by worker records.
OTEL_RESOURCE_ATTRIBUTESpercent-encoded key=value listemptyAdditional span resource attributes when tracing is enabled.

Restart retains recorded port, origin, and log-level flags. Set a different flag on the next explicit start to change them. Invalid process settings fail with a diagnostic. Invalid App credentials enter setup mode. Child processes receive a restricted environment rather than all orchestrator secrets.

Every command reads .env in the instance folder. Shell environment values take precedence; empty values count as unset. A missing file is allowed; an unreadable file is an error. Each line is KEY=value, optionally prefixed by export. Quote values containing a hash character. Single, double, and backtick quotes are accepted; double-quoted \n becomes a newline. Variable and command substitutions stay literal.

USINE_ORIGIN=https://usine.example.com
USINE_PORT=7331

Keep .env private, set mode 0600, and exclude it from git. Changes take effect when a command starts; the running orchestrator does not reread it on configuration changes.

SIGHUP sent to the orchestrator process requests a reread of stored configuration. It does not import files or reread .env. Most revisions apply automatically. See revision application.

StatusTypeDefaultDescription
0exit codesuccessCommand completed or help printed.
1exit codefailureInvalid usage, refused operation, timeout, or operational error on standard error.
3exit codestatus onlyNo process owns the instance.
130exit codesignaled shutdownForeground orchestrator stopped after SIGINT or SIGTERM.

The @usine/gateway package provides a separate usine-gateway binary with no arguments. It logs one JSON object per line. Refused proxy requests include x-usine-gateway-refusal and a logged reason.

Environment files listed by USINE_GATEWAY_ENVIRONMENT_FILES override process values, with later files taking precedence. This differs from the instance .env. Missing required values, invalid settings, or an unreadable allowlist stop startup.

VariableTypeDefaultDescription
USINE_GATEWAY_ENVIRONMENT_FILESstringnoneEnvironment files separated by :, each with one KEY=value per line. Quote a value that contains #. A variable in a later file overrides the same variable in an earlier file and in the process environment. Read from the process environment only.
USINE_GATEWAY_DOMAINstringrequiredThe private DNS domain. The same value as gateway.domain in the stored configuration.
USINE_GATEWAY_ADMIN_TOKENstringrequiredBearer token of the admin API, at least 32 characters. The orchestrator’s variable named by admin_token_env contains the same value.
USINE_GATEWAY_CALLER_KEYstringrequiredHMAC key that signs caller tokens, at least 32 characters. Only the gateway has it.
USINE_GATEWAY_EGRESS_ALLOWLISTstring/etc/usine-gateway/egress-allowlistFile of hosts that the forward proxy allows. One rule per line: host or *.domain, optionally with :port. A rule without a port allows 443 and 80. # starts a comment.
ANTHROPIC_API_KEYstringnoneAnthropic API key that the gateway adds for Claude Code.
USINE_GATEWAY_ANTHROPIC_SUBSCRIPTION_TOKENstringnoneAlternative Anthropic credential: a Claude subscription token from claude setup-token, valid for one year. Setting both Anthropic variables is an error.
OPENAI_API_KEYstringnoneOpenAI-compatible API key that the gateway adds for Codex.
USINE_GATEWAY_CHATGPT_AUTH_FILEstringnoneAlternative OpenAI credential: the absolute path of a Codex auth.json with a ChatGPT login, which the gateway refreshes and rewrites, so the service needs write access to its directory. Setting both OpenAI variables is an error. If the file isn’t a ChatGPT login, the binary exits before it starts listening.
USINE_GATEWAY_ANTHROPIC_UPSTREAMstringhttps://api.anthropic.comBase URL for Anthropic requests.
USINE_GATEWAY_OPENAI_UPSTREAMstringhttps://api.openai.comBase URL for OpenAI requests with OPENAI_API_KEY.
USINE_GATEWAY_CHATGPT_UPSTREAMstringhttps://chatgpt.com/backend-api/codexBase URL for OpenAI requests with USINE_GATEWAY_CHATGPT_AUTH_FILE.
USINE_GATEWAY_PROXY_HOST, USINE_GATEWAY_PROXY_PORThost string, integer port 0–65535127.0.0.1, 80Listener of the reverse proxy that workers call for GitHub and LLM providers.
USINE_GATEWAY_EGRESS_HOST, USINE_GATEWAY_EGRESS_PORThost string, integer port 0–65535127.0.0.1, 3128Listener of the forward proxy.
USINE_GATEWAY_ADMIN_HOST, USINE_GATEWAY_ADMIN_PORThost string, integer port 0–65535127.0.0.1, 7070Listener of the admin API. admin_port in the stored configuration is the same port. The executor forwards a local port to it over SSH.

A port of 0 lets the operating system assign an available port. Each listener logs its bound host and port when it starts listening.

For example, set USINE_GATEWAY_DOMAIN=gw.internal, private listener addresses, and the required secrets in the gateway environment files.

systemctl reload usine-gateway sends SIGHUP and rereads provider settings, ChatGPT auth, upstreams, and the egress allowlist. An invalid reload keeps the accepted settings and logs the reason. Attachments and open tunnels continue. Domain, listener, admin-token, and caller-key changes require restart. After a gateway restart loses attachments, the executor registers running attempts again within two minutes. Configure a gateway describes setup.