Kin / Reference

CLI flags

Launch flags and commands for installation checks, connections, sessions, and automation.

Read as Markdown

Every command-line flag the kin launcher accepts. Flags are the highest-precedence configuration layer — they override environment variables and both settings files. For the full precedence model, see Configuration.

Usage

kin [options]                 # interactive TUI session
kin [options] -- "prompt"     # interactive TUI with a first turn
kin --new [options]           # force a fresh interactive process/conversation
kin -p "prompt" [options]     # headless one-shot: print the answer, exit
echo "context" | kin -p       # headless, prompt (or extra context) via stdin
kin --stdio [options]         # host the interactive session for one local client
kin --serve [--socket PATH]   # the per-user session service for local clients
kin --attach [--resume ID | --continue] [--observe]   # the terminal as a client of that service
kin -p --attach "prompt" [--idle N]   # headless run hosted in that service; a human gate stays live

With no options, kin starts a fresh foreground process and conversation. Use --continue or --resume when saved work is the intent. Run kin --help to print the same flags from argparse.

When a saved interactive session exits cleanly, Kin prints the exact kin --resume <id> command needed to continue it. The handoff follows the final active conversation after an in-session switch and is omitted when no resumable journal survived shutdown. It is printed after the foreground UI exits, so the command lands in shell-visible scrollback.

-p/--print runs one turn with no UI at all and exits with a contract code — 0 ok, 1 error, 2 needs-human, 64 invalid command-line usage (EX_USAGE). It is distinct from an interactive initial prompt. See Headless runs for the permission envelope, the exit codes, and cron examples.

Launching with an initial prompt

Pass one prompt after -- to open the normal interactive TUI and submit that text as its first turn:

kin -- "Review this project"
kin --continue -- "Pick up from the saved work and summarize what remains"
kin --mode strict -- $'Review this project.\nAsk before changing anything.'

Flags go before --. The end-of-options marker keeps text such as update, ls, or -p from being read as a Kin subcommand or flag. This form requires a TTY: it keeps the TUI open for approvals, questions, and later turns. Launch text is literal turn data, so a leading ! does not run shell passthrough and a leading / does not invoke a slash command or skill. Use kin -p when the caller is headless and needs a process exit-code contract.

Flags

Flag Argument What it does Env / settings.toml
-p, --print (flag) Headless one-shot: run the positional PROMPT (and/or piped stdin) with no UI, print the final assistant text to stdout, exit 0 / 1 / 2 (invalid usage is 64). This is not the interactive initial-turn form. The session still journals (resume it in the TUI) unless --no-save. Combinable with --resume / --continue to continue a saved session headlessly — see Resuming headless by continuation — and with --attach to host the run’s conversation in the session service, where a human gate stays live as a pending block instead of a tool error (-p --attach then refuses --mode, --no-save, --token-budget, --max-turns, and the model/provider/preset flags — the service’s launch decided them). NOT combinable with --agent (a profile launch has no TTY to resolve an approval/ask modal).
(positional) PROMPT With -p, the headless prompt (- forces stdin; piped stdin is prepended as context when both are given). Without -p, the TTY-only first turn of an interactive session; pass it after --. Interactive launch text is stripped like composer input but remains literal — no ! or / dispatch.
--stdio (flag) Host the ordinary interactive session for one local program that owns Kin’s standard input and output, as typed JSON lines — no UI, no TTY, no socket. The workspace must already be trusted, unless the client declares workspace_trust and carries Kin’s trust question to the person. Mutually exclusive with -p, --serve, --agent, and a positional prompt; composes with --resume / --continue / --new, --no-save, --mode, and the model flags. See Local clients.
--serve (flag) Run the per-user session service: host conversations for local typed clients on $XDG_RUNTIME_DIR/kin.sock (mode 0600, peer credentials checked) or the systemd-activated socket, one writer and any observers per conversation, over the same JSON lines as --stdio. Each client’s hello names its workspace and conversation, so --workdir, --resume, --continue, and --new are refused; -p, --stdio, --agent, and a prompt are refused too. Composes with --no-save, --mode, and the model and preset flags, which apply to every conversation the service opens. Exits 0 when stopped, 1 when it cannot start. See The session service.
--attach (flag) Run the terminal as a client of the per-user session service instead of hosting the harness in this process: a fresh service conversation, or with --resume ID / --continue the named or newest one, as its writer. The workspace-trust prompt runs first, as for an in-process launch. Quit detaches and leaves the conversation in the service; /role shows, releases, or claims the writer role; /close ends the conversation. With -p, the headless run is hosted in the service instead — see the --idle row and Headless runs. Refuses --stdio, --serve, --agent, --no-save, --mode, and the model, provider, and preset flags; exits 1 for service/socket failures and non-trust refusals, 2 for an untrusted workspace, and 64 for invalid usage. See The terminal attaches.
--observe (flag) (With --attach --resume / --continue.) Attach as an observer of a live conversation: see everything, send nothing, until /role claim takes a released writer role. Takes no prompt; refused with -p.
--socket path (With --serve or --attach.) The service’s Unix socket instead of $XDG_RUNTIME_DIR/kin.sock. With --serve, not combinable with socket activation.
--idle seconds (With -p --attach.) How long the service keeps the run’s conversation alive with no writer attached — the wait window for a needs-human answer (default: the service’s 1800, max 86400). Idle expiry ends the conversation; the journal keeps it resumable.
--output file (With -p.) Also write a markdown run report — prompt, model, mode, duration, needs-human items, final text — to this path (parents created).
--status-file file (With -p, including --attach.) Atomically write content-free JSON {version, exit_code, reason}. Distinguishes workspace_trust from human_gate without prompt, reply, or approval details. Parent must exist; use a per-invocation path. See Content-free status.
--token-budget int (With -p.) Cap cumulative non-cached prompt + completion tokens across every model call in the run. A budget hit finishes the crossing round, gives the root one tools-off wrap-up round (children receive no grace), then exits 1 with reason token_budget. 0 disables. See Fleet safety. KIN_TOKEN_BUDGET / token_budget
--max-turns int (With -p.) Cap the run’s model↔tool round-trips. A cap hit stops with reason turn_cap (exit 1). 0 = unlimited (the default — the doom-loop guard is the real backstop). KIN_MAX_TURNS / max_turns
--provider openai | anthropic Selects the provider family. Default openai, unless a base URL is set and neither identity axis is given, in which case the vLLM heuristic picks anthropic. Explicit openai without --wire-api means Chat. KIN_PROVIDER / provider
--wire-api chat | responses Selects the OpenAI wire shape and implies provider=openai, bypassing the bare-URL Anthropic heuristic. Responses is explicit opt-in; Chat remains the compatibility default. KIN_WIRE_API / wire_api
--model model id The model to call. KIN_MODEL / model
--base-url URL OpenAI-compat endpoint URL (a trailing /v1 is trimmed for the Anthropic wire). KIN_BASE_URL / base_url
--workdir path Working directory for the session. Default: the current directory; if that directory is gone or unreadable (deleted — or Finder-moved to the Trash — while the terminal was open), kin prints a notice and starts in your home directory, or / if home cannot be entered. An explicit absolute path always wins; a relative path requires a live current directory to anchor it.
--temperature float Sampling temperature (OpenAI-compat wire only). KIN_TEMPERATURE / temperature
--top-p float Nucleus sampling top_p (OpenAI-compat wire only). KIN_TOP_P / top_p
--top-k int top_k via extra_body (OpenAI-compat wire only). KIN_TOP_K / top_k
--resume ID Resume an exact conversation by id. Refuses if another live Kin holds that conversation’s process-lifetime lease. Works with -p for a headless continuation turn (e.g. answering a needs-human halt).
--continue (flag) Continue the newest saved conversation for this workdir. Refuses if another live Kin owns it. Works with -p; errors if no saved session exists for the workdir.
--new (flag) Force a fresh conversation. Mutually exclusive with --resume / --continue; harmlessly redundant for fresh headless and agent launches.
--no-save (flag) Run ephemerally — write no session journal and no durable prompt history (not resumable; ↑/↓ and ++ctrl+r++ remain memory-only for this process). KIN_NO_SAVE / no_save
--mode auto | strict Permission mode at launch (the legacy default / accept-edits / plan are still accepted and alias onto the pair, with a deprecation note). Default: auto. Cycle in-session with ++shift+tab++; use /plan for a read-only planning pass. KIN_MODE / mode
--preset preset id Provider preset (built-ins: direct openai / anthropic, plus curated minimax, zai). Bundles wire + endpoint/auth identity; curated presets also supply a default model. CLI > KIN_PRESET > file; an unknown or invalid selected preset exits 1, never falls back. KIN_PRESET / provider_preset
--agent profile name Run the main session as the named profile (e.g. researcher, coder); the profile’s tool allow-list + persona become the thread. TTY-only (refuses when stdin is not a tty).
--version (flag) Print kin <version> and exit 0 (before any TUI import — the get.kinra.ai installer’s success gate).

Resume reuses the saved endpoint

When a conversation is saved-only, --resume or --continue reuses its provider and model unless you pass an explicit backend flag (--provider, --wire-api, --model, --base-url, or a sampling flag). Current matching credentials are reattached, but changing a global backend default does not silently retarget the saved conversation.

When the conversation is already live, its process-lifetime lease refuses a second writer. Return to the owning terminal or Herdr pane, or /fork from that process to create a separate conversation id.

auto is the default — safe autonomy

--mode auto is the launch default after exact-workspace trust: edits and shell/code run without per-call prompts using the launching user’s authority. Toggle to strict (ask-first) and back in-session with the ++shift+tab++ keybinding (auto ↔ strict), or use /plan for a read-only planning pass. See Auto mode & trusted workspaces.

kin doctor

Verifies an install — the check the get.kinra.ai installer points you at, and the first thing to run on any new machine:

kin doctor              # full checklist
kin doctor --offline    # skip the endpoint reachability probe

Doctor has its own options, separate from launch flags. It reports for a pass, for a critical failure, and for information.

Doctor also reports whether this process is in a validated Herdr pane with Kin lifecycle reporting or in a plain terminal. For one release it performs a read-only probe of Kin’s retired dedicated tmux server; when predecessor sessions remain, the informational line prints the exact attach, /exit, and server-cleanup rescue path.

  1. installuv, kin, and git on PATH; ~/.local/bin in PATH; task reported info-only (it runs the dev gates — not a consumer prerequisite). GitHub API + Git transport readiness is also info-only: whether gh is on PATH and, unless --offline, whether it has a healthy active login. Inherited GH_* / GITHUB_* tokens are ignored; only a token-free account/source projection crosses from gh; and a missing login points to /github connect. The structured Git data plane uses that account over authenticated HTTPS even when the saved remote uses SSH.
  2. config~/.kin/settings.toml parses (a TOML error is critical, with the line/column; a missing file is only a warning since env vars can carry a full config), and a provider resolves. The walk mirrors the backend factory’s exact chains and names which source supplies the model endpoint and the key (preset / [[providers]] row / provider_keys / KIN_BASE_URL / API-key env vars / top-level api_key). No endpoint and no key from any source is critical.
  3. network (skipped by --offline) — one GET against {base_url}/models with a 5s timeout. Any HTTP response — 401 and 404 included — counts as reachable (auth is not doctor’s job); connection/timeout errors are critical.

After the chunks, one info-only update line (never critical): whether a newer release is published on get.kinra.ai — cache-first (the TUI’s 24h check shares the cache), and under --offline it reports a cached answer or says it can’t tell.

Exit code: 0 when every critical check passes, 1 otherwise (the final line names the verdict and the first fix to try).

kin update

Updates this install to the published release — Install → Updating has the full flow, shapes, and fallbacks:

kin update              # detect the install shape and apply the update
kin update --check      # report only; exit 1 when an update is available

Checkout installs fast-forward, sync dependencies, and refresh an editable tool environment when present. Wheel installs use the manifest-selected, checksum-pinned immutable wheel. Exit 0 means success or already current; exit 1 means failure. With --check, 1 means an update is available and 0 means current or unknown; stderr distinguishes those cases.

kin login and kin logout

kin login opens browser OIDC sign-in, enrolls a revocable Kinra device key, adopts the authenticated service profile, and saves the official connection. When the profile advertises hosted web retrieval, the saved connection makes web_search and web_context available to the next Kin session without a local vendor key. An older inference-only device credential is not broadened; after hosted access becomes available, kin logout followed by kin login enrolls a newly scoped replacement. kin login status reads the last validated identity without a network call and reports the active web-retrieval route from the same offline record: hosted through the login, an explicit local Brave override, or off with the two ways out. kin logout revokes the presented device key first; a network failure keeps local state so a live key is never forgotten. The equivalent in-app commands are /login, /login status, and /logout.

Kin also provides kin login handoff {status|install|reconnect} for trusted hosts such as the private Spaces preview. It reads a bounded account handoff from stdin and returns a secret-free result. Spaces calls it after application sign-in; people do not need to handle the device secret. A Kin logout stays effective until explicit reconnect, and browser sign-out leaves the native connection intact. Existing providers and inherited model roles remain selected. An installation retry must keep the same request ID, key ID and credential. Rejected credentials suspend automatic setup until explicit reconnect.

The authorization callback listens only on 127.0.0.1:53682. For Kin running on an SSH/headless host, open a second terminal on the machine with your browser and keep this local forward running:

ssh -N -L 53682:127.0.0.1:53682 USER@SERVER

Run kin login on the server, then open its printed URL in your local browser. The browser’s loopback callback is carried to Kin without exposing a public listener. When no browser launch succeeds, Kin prints this command. There is no automatic device-code fallback; use a deliberately Console-issued key with kin connect when SSH forwarding is unavailable.

ChatGPT subscription sign-in

kin login chatgpt                  # browser sign-in and select a main model
kin login chatgpt --device-auth    # remote host: enter a code in your browser
kin login chatgpt --model MODEL    # select an account-visible model explicitly
kin login chatgpt status           # inspect saved sign-in locally
kin logout chatgpt                 # remove Kin's local sign-in

Sign in with your own ChatGPT account to use its subscription directly in Kin. Browser sign-in uses localhost:1455/auth/callback; forward port 1455 when running Kin over SSH, or choose device authentication. Successful login lists account-visible models and selects a main model. Other explicit job assignments remain unchanged. The in-app commands accept the same sign-in, device, status, and logout variants, except --model: choose that through /models instead.

Kin keeps private OAuth credentials under KIN_HOME, independently of other applications. Logout is local removal, not remote revocation. See Your ChatGPT subscription for usage limits and model settings.

kin gateway-usage

Reads the current device credential’s own hosted generation activity from the Kinra Gateway. The command is a narrow machine-readable seam for trusted local integrations:

kin gateway-usage

It accepts no arguments. Kin resolves the saved official kinra-api device credential internally, sends it only to the fixed https://api.kinra.ai/v1/usage/self endpoint, validates the complete response, and prints one closed JSON object to stdout. The bearer and identity never appear in the output.

The response contains exactly seven consecutive UTC days ending with the current, partial day. Its request and token counters cover only generation requests made through that device credential. Direct-provider and local work, requests made with another credential, older history, billing, quota, and productivity judgments are outside the command’s scope.

An absent official connection, network or authorization failure, oversized or non-JSON response, or schema mismatch produces no stdout and exits 1 with a bounded error on stderr. Extra arguments are rejected before the credential is read and exit 2.

kin connect

Connects a custom OpenAI-compatible provider in one command — creates (or updates) its global [[providers]] row, collects the API key through a masked prompt, and makes the provider’s model the active selection.

For the official Kinra hosted connection, the catalog-driven short form is all that is needed — wire shape, model, the vision route, and the vision/utility assignments come from the live service catalog, and the connection joins the same 12-hour background profile refresh /login uses:

kin connect kinra-api --base-url https://api.kinra.ai/v1 --refresh-profile

The short form triggers only for exactly this shape: provider id kinra-api, the official base URL, --refresh-profile, and no --wire-api/--model/route flags. It retains a ready saved key (prompting once, masked, otherwise), writes nothing if the live catalog cannot be fetched or validated, and preserves every operator pin on re-runs; an explicit --reasoning-effort LEVEL here becomes such a pin. Every other connection uses the explicit form:

kin connect my-provider \
  --base-url https://my-endpoint.example/v1 \
  --wire-api responses \
  --model my-model \
  --label "My provider"

Same pre-parser dispatch as doctor (none of the flags above apply; implemented in kin.harness.cli.connect). --base-url is always required; --wire-api (chat | responses) and --model are required everywhere except the catalog-driven short form above; --label names the row in the pickers and defaults to the id. Optional --reasoning-effort LEVEL persists the endpoint’s opaque reasoning level on this connection. The special inherit value is accepted only with --refresh-profile and stores a provider-local mask: it overrides broader file settings but emits no reasoning field, so the service can own its default. Another explicit level requests summary = "auto" on the Responses wire.

When the provider hosts a separate vision model beside its main model, the optional --vision-route family also creates a named model route on the same connection and assigns it the vision job — one command, one transaction:

kin connect kinra-api \
  --base-url https://api.kinra.ai/v1 \
  --wire-api responses \
  --model default \
  --refresh-profile \
  --reasoning-effort inherit \
  --label "Kinra hosted inference" \
  --vision-route kinra-vision \
  --vision-model vision \
  --vision-description "Kinra hosted vision" \
  --vision-max-tokens 1024 \
  --vision-reasoning-profile inherit \
  --utility-route kinra-vision

--vision-route names the [model_routes.<id>] entry (--vision-model is then required; --vision-description, --vision-max-tokens, --vision-reasoning-profile, and --vision-effort are optional). The effort flag requires the profile flag; the profile is a closed qwen-llamacpp choice or the refresh-only inherit sentinel. Effort is one of default, off, or thinking-128/512/1024/2048 and cannot accompany inherit. The route is created with vision = true and assigned as [model_assignments].vision; the main model stays --model — the vision route never displaces it. The flags are a closed schema on purpose: there is no raw-TOML or JSON passthrough.

--utility-route <id> additionally assigns an existing route — the one --vision-route stages in the same command, or one already saved — as [model_assignments].utility, kin’s housekeeping job (session auto-titles), which keeps tiny side-calls off the main model’s prompt cache. It is assignment-only: it never creates a route, a vision route is never treated as a utility route implicitly, and an id matching no route refuses without writing anything.

The key is prompt-only, by design. There is no --api-key flag and no environment fallback — a key on the command line lands in shell history and process listings, so a literal --api-key argument is refused (without echoing its value). Everything is written to the global ~/.kin/settings.toml through the same locked transaction the /models hub uses; a project’s .kin/settings.toml never holds a credential.

--refresh-profile is an explicit service-managed update mode. On an existing same-endpoint/wire connection it retains a ready saved credential, may advance a legacy concrete primary selector to the stable default alias, permits the named vision route’s model and supplied reasoning profile to advance on that same provider, and lets the two inherit sentinels establish service reasoning ownership (a provider-local mask for Main and removal of route shaping for Vision). On a new or unkeyed connection it still opens the masked prompt. Provider endpoint/wire conflicts, arbitrary main-model substitutions, another provider’s route, and vision = false remain hard refusals. Without this flag, the historical rotation and route-conflict behavior is unchanged. For a short tester checklist, use Update an existing Kinra hosted connection.

Re-running the command is safe:

  • Absent id — the connection is created, keyed, and activated.
  • Same endpoint/wire/model — the stored key is rotated and the provider re-activated. Pass --label to rename it or --reasoning-effort to update its request policy; omitted values retain the saved row.
  • Same identity plus --refresh-profile — an existing key is retained; the stable default selector plus explicitly supplied service-managed route and reasoning policy updates land atomically. Re-running an already-current generated command is a state no-op.
  • Conflicting id (a row with the same id but a different endpoint, wire, or model) — the command refuses without changing anything and points at the fix: pick a different id, or edit the existing connection in the /models hub.
  • Existing --vision-route id — an identical route is a no-op; a route pointing at a different provider, model, or vision = false refuses without changing anything (description and max-tokens update in place). If the vision job was assigned to another route, the command reassigns it and says so. --refresh-profile may advance the model/profile only when the route is already on this provider with vision = true.
  • --utility-route — re-assigning is always safe; if the utility job was bound to another route, the command reassigns it and says so. Everything — provider row, key, vision route, and the vision/utility assignments — lands in one locked save; a refused or failed run writes nothing (no provider-only half-state).

Exit code: 0 connected / 1 refused or failed / 2 usage error.

kin settings

Shows the effective configuration with provenance — the answer to “why isn’t this setting applying”:

kin settings                    # effective keys, env overrides, lint (for cwd)
kin settings --workdir <path>   # overlay a different project's .kin/settings.toml

Same pre-parser dispatch as doctor (implemented in kin.harness.cli.settings_cli; the projection is shared with kin doctor). Read-only, and secret values render as set — never bytes. Three blocks:

  1. effective configuration — every key set in any file layer, its value, and the layer that wins (~/.kin/settings.toml, credentials.toml, grants.toml, or the project .kin/settings.toml), with shadowed lower layers named.
  2. env overrides — active KIN_* (plus vendor key) variables, which outrank every file at launch.
  3. lint — unknown keys (typos), global-only keys ignored in a project file, keys pending migration to their sibling file, weak credentials.toml permissions, and files that fail to parse. The same rows appear in kin doctor as advisory lines.

Exit code: always 0 — lint is advisory; kin doctor owns the critical checks.

For what each provider supports, see Models & providers. For the modes themselves, see Modes & permissions. For --agent, see Agents.

Depot companion

kin depot status reports whether the environment’s native companion is installed and a Kinra connection is saved. Depot independently checks access. kin depot help lists the personal operations; kin depot help repo_bootstrap shows one exact contract. kin depot op OPERATION reads one JSON object from standard input and returns a JSON result, exiting 0 for success or 1 for a reported failure. No credential, URL or executable argument is accepted.

These commands require the host’s appointed companion for actual operations. The terminal and browser can use the same native connection without copying its key into another configuration file.