---
title: CLI
description: "Every jr2 command: its synopsis, its arguments, flags and env vars, and what it prints."
---

# CLI

The `jr2` binary: orchestrate agentic workflows ([ADR-0009](decisions/0009-cli-and-instance-interface.md)). `jr2 --help` prints the same table as this page, and `jr2 <command> --help` prints one command.

Commands: [`version`](#version), [`init`](#init), [`check`](#check), [`up`](#up), [`down`](#down), [`gc`](#gc), [`kit push`](#kit-push), [`run`](#run), [`runs`](#runs), [`status`](#status), [`logs`](#logs), [`send`](#send).

<a id="global-options"></a>

## Global options

These address the deployment; each lists the verbs that take it ([ADR-0019](decisions/0019-one-converging-command-against-the-current-context.md)).

| Flag | Variable | Description | Taken by |
| --- | --- | --- | --- |
| `-n, --namespace <ns>` |  | the deployment's namespace (default: the config's `name`, then the Instance folder's name) | [`version`](#version), [`up`](#up), [`down`](#down), [`run`](#run), [`runs`](#runs), [`status`](#status), [`logs`](#logs), [`send`](#send) |
| `--context <ctx>` |  | the kube context (default: kubectl's current context) | [`version`](#version), [`up`](#up), [`down`](#down), [`gc`](#gc), [`run`](#run), [`runs`](#runs), [`status`](#status), [`logs`](#logs), [`send`](#send) |
| `--url <u>` | `JR2_URL` | attach to a specific orchestrator (skips kube entirely) | [`version`](#version), [`run`](#run), [`runs`](#runs), [`status`](#status), [`logs`](#logs), [`send`](#send) |
|  | `JR2_TOKEN` | the Instance token to send: with `--url` / `JR2_URL` the only one, and otherwise used in place of the one read from the cluster | [`run`](#run), [`runs`](#runs), [`status`](#status), [`logs`](#logs), [`send`](#send) |

## Commands

<a id="version"></a>

### `jr2 version`

```sh
jr2 version [--local] [--json] [--url <u>] [-n <ns>] [--context <ctx>]
```

What runs here (this jr2, the global that handed off, the Instance's Kit) and what the cluster runs.

--local skips the cluster.

Also spelled `jr2 --version`.

**Flags**

| Flag | Description |
| --- | --- |
| `--local` | report what runs here and skip the cluster |
| `--json` | print the one report object on stdout instead of the table |
| `--url <u>` | attach to a specific orchestrator (skips kube entirely) |
| `-n, --namespace <ns>` | the deployment's namespace (default: the config's `name`, then the Instance folder's name) |
| `--context <ctx>` | the kube context (default: kubectl's current context) |

**Environment**

| Variable | Description |
| --- | --- |
| `JR2_URL` | the orchestrator to attach to, when `--url` is not given |
| `JR2_HANDOFF_FROM` | set by the global `jr2` that handed off to this one, which the report names |

**Output**: report, a table on stdout, or the one report object with `--json`. See [Output](#output).

**Decisions**: [ADR-0009](decisions/0009-cli-and-instance-interface.md), [ADR-0056](decisions/0056-a-global-jr2-hands-off-to-the-instances-own-and-an-instance-has-one-kit-version.md).

<a id="init"></a>

### `jr2 init`

```sh
jr2 init [dir] [--name <n>]
```

Scaffold a new instance folder.

Writes AGENTS.md, with the jr2 docs index between its two jr2-docs markers (empty when this jr2 has no docs bundle), and a CLAUDE.md that imports it.

**Arguments**

| Argument | Required | Description |
| --- | --- | --- |
| `dir` | no | the folder to scaffold (default: the current directory) |

**Flags**

| Flag | Description |
| --- | --- |
| `--name <n>` | the package name in package.json (default: the folder's name) |

**Output**: activity, activity on stderr only. See [Output](#output).

**Decisions**: [ADR-0009](decisions/0009-cli-and-instance-interface.md), [ADR-0072](decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md).

<a id="check"></a>

### `jr2 check`

```sh
jr2 check
```

Typecheck this instance and load its workflows, as `jr2 up` does first, with no cluster.

Runs the check that `jr2 up` runs before it stages the Assembly, and exits 1 with the same refusal: a type error, a module that refuses to load (a refusal of `createMachine`, `defineEvent` or `workspace()`), an Open part, a Chart file, a dispatch, an Effect secret or a Size.

Reads no kube context and writes no file, so an Assistant runs it before it gives a change to the user.

**Output**: activity, activity on stderr only. See [Output](#output).

**Decisions**: [ADR-0050](decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md).

<a id="up"></a>

### `jr2 up`

```sh
jr2 up [--yes] [--force] [--skip-provider-preflight] [-n <ns>] [--context <ctx>]
```

Converge the current kube context to this instance.

Reads each `git.credentials` token from the env var it names, after the Instance's .env.

Before the cluster work, sets the text between the jr2-docs markers in AGENTS.md to the docs index of the Kit version, and changes nothing outside them; a folder with no markers is left alone.

**Flags**

| Flag | Description |
| --- | --- |
| `--yes` | answer the questions non-interactively: confirm first-time setup, and take the recommended git ssh key source (for CI) |
| `--force` | build every image again, even one already built or deployed |
| `--skip-provider-preflight` | do not run the provider preflight: no check pod checks the models, so a check that fails when the model works does not stop the converge |
| `-n, --namespace <ns>` | the deployment's namespace (default: the config's `name`, then the Instance folder's name) |
| `--context <ctx>` | the kube context (default: kubectl's current context) |

**Environment**

| Variable | Description |
| --- | --- |
| `NO_COLOR` | draws the git ssh key menu without highlight |

**Output**: activity, activity on stderr only. See [Output](#output).

**Decisions**: [ADR-0019](decisions/0019-one-converging-command-against-the-current-context.md), [ADR-0051](decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md), [ADR-0069](decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md), [ADR-0072](decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md).

<a id="down"></a>

### `jr2 down`

```sh
jr2 down [--all] [--yes] [-n <ns>] [--context <ctx>]
```

Remove the instance from the cluster.

--all: operator too; --yes: no confirmation.

**Flags**

| Flag | Description |
| --- | --- |
| `--all` | also uninstall the per-cluster operator |
| `--yes` | do not ask for confirmation (for CI) |
| `-n, --namespace <ns>` | the deployment's namespace (default: the config's `name`, then the Instance folder's name) |
| `--context <ctx>` | the kube context (default: kubectl's current context) |

**Output**: activity, activity on stderr only. See [Output](#output).

**Decisions**: [ADR-0019](decisions/0019-one-converging-command-against-the-current-context.md).

<a id="gc"></a>

### `jr2 gc`

```sh
jr2 gc [--dry-run] [--repo-ttl <ttl>] [--context <ctx>]
```

Remove jr2's images that no live instance names, and Repo resources no Machine binds and no run attached lately.

**Flags**

| Flag | Description |
| --- | --- |
| `--dry-run` | print what would be removed, and remove nothing |
| `--repo-ttl <ttl>` | how long since a run last attached before an unbound Repo is garbage (default: 7d) |
| `--context <ctx>` | the kube context (default: kubectl's current context) |

**Output**: activity, activity on stderr only. See [Output](#output).

**Decisions**: [ADR-0039](decisions/0039-image-garbage-collects-by-reachability.md), [ADR-0051](decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md).

<a id="kit-push"></a>

### `jr2 kit push`

```sh
jr2 kit push <registry>
```

Mirror the published kit images into a registry.

The v0.5.1 kit images (harness, operator, orchestrator) from their canonical home, and the Custodian's pinned Envoy from its own, for a cluster whose `kitRegistry` names the registry.

**Arguments**

| Argument | Required | Description |
| --- | --- | --- |
| `registry` | yes | the registry to mirror into, as `kitRegistry` names it |

**Output**: result, one JSON result on stdout, and activity on stderr. See [Output](#output).

**Decisions**: [ADR-0044](decisions/0044-kit-images-live-at-a-canonical-home-a-self-host-mirrors-it.md), [ADR-0059](decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md), [ADR-0069](decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md).

<a id="run"></a>

### `jr2 run`

```sh
jr2 run <workflow> [--input <json>] [--detach] [--url <u>] [-n <ns>] [--context <ctx>]
```

Start a run; stream activity, print terminal result.

--detach: just print the runId and return.

A Chart that the door refuses prints one line for each rule that it fails.

Exits 0 only for a run that ended done, and 1 for every other end: failed, error, cancelled, lost, drifted, or parked before it settled; a failed run prints its reason.

**Arguments**

| Argument | Required | Description |
| --- | --- | --- |
| `workflow` | yes | the workflow to start, or a named Chart as `<wrapper>/<name>` |

**Flags**

| Flag | Description |
| --- | --- |
| `--input <json>` | the run's input, as a JSON object (default: {}) |
| `--detach` | print the runId and return, and do not stream |
| `--url <u>` | attach to a specific orchestrator (skips kube entirely) |
| `-n, --namespace <ns>` | the deployment's namespace (default: the config's `name`, then the Instance folder's name) |
| `--context <ctx>` | the kube context (default: kubectl's current context) |

**Environment**

| Variable | Description |
| --- | --- |
| `JR2_URL` | the orchestrator to attach to, when `--url` is not given |
| `JR2_TOKEN` | the Instance token to send: with `--url` / `JR2_URL` the only one, and otherwise used in place of the one read from the cluster |

**Output**: result, one JSON result on stdout, and activity on stderr. See [Output](#output).

**Decisions**: [ADR-0009](decisions/0009-cli-and-instance-interface.md), [ADR-0070](decisions/0070-a-machine-lends-its-parts-to-a-chart.md), [ADR-0073](decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md).

<a id="runs"></a>

### `jr2 runs`

```sh
jr2 runs [--workflows] [--url <u>] [-n <ns>] [--context <ctx>]
```

List live runs; "placing" names the Workspaces that wait for capacity, and "status `<runId>`" says why.

The Workflows a run can start on stderr, each with its origin (machine, chart file, chart) and a Chart wrapper's Charts under it; --workflows prints that listing as the result.

A runtime Chart has no verb: PUT or DELETE /workflows/`<wrapper>`/charts/`<name>` with the Instance token (an MCP or curl), then `jr2 run <wrapper>/<name>` starts it.

**Flags**

| Flag | Description |
| --- | --- |
| `--workflows` | print the Workflow listing as the JSON result instead |
| `--url <u>` | attach to a specific orchestrator (skips kube entirely) |
| `-n, --namespace <ns>` | the deployment's namespace (default: the config's `name`, then the Instance folder's name) |
| `--context <ctx>` | the kube context (default: kubectl's current context) |

**Environment**

| Variable | Description |
| --- | --- |
| `JR2_URL` | the orchestrator to attach to, when `--url` is not given |
| `JR2_TOKEN` | the Instance token to send: with `--url` / `JR2_URL` the only one, and otherwise used in place of the one read from the cluster |

**Output**: result, one JSON result on stdout, and activity on stderr. See [Output](#output).

**Decisions**: [ADR-0009](decisions/0009-cli-and-instance-interface.md), [ADR-0064](decisions/0064-a-workspace-waits-for-capacity.md), [ADR-0070](decisions/0070-a-machine-lends-its-parts-to-a-chart.md).

<a id="status"></a>

### `jr2 status`

```sh
jr2 status [runId] [--json] [--url <u>] [-n <ns>] [--context <ctx>]
```

Print a run's current status (read-through), or the instance's Repos, per node, when given none.

A failed run prints its reason beside the result: failed: `<reason>`.

**Arguments**

| Argument | Required | Description |
| --- | --- | --- |
| `runId` | no | the run to read; without one, the instance's Repos |

**Flags**

| Flag | Description |
| --- | --- |
| `--json` | print the one report object on stdout instead of the table (without a runId) |
| `--url <u>` | attach to a specific orchestrator (skips kube entirely) |
| `-n, --namespace <ns>` | the deployment's namespace (default: the config's `name`, then the Instance folder's name) |
| `--context <ctx>` | the kube context (default: kubectl's current context) |

**Environment**

| Variable | Description |
| --- | --- |
| `JR2_URL` | the orchestrator to attach to, when `--url` is not given |
| `JR2_TOKEN` | the Instance token to send: with `--url` / `JR2_URL` the only one, and otherwise used in place of the one read from the cluster |

**Output**: `jr2 status <runId>`: result, one JSON result on stdout, and activity on stderr; `jr2 bare status`: report, a table on stdout, or the one report object with `--json`. See [Output](#output).

**Decisions**: [ADR-0048](decisions/0048-the-orchestrator-boots-without-its-repos.md), [ADR-0051](decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md), [ADR-0073](decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md).

<a id="logs"></a>

### `jr2 logs`

```sh
jr2 logs <runId> [-f] [--url <u>] [-n <ns>] [--context <ctx>]
```

Replay a run's status; -f to follow until it settles.

**Arguments**

| Argument | Required | Description |
| --- | --- | --- |
| `runId` | yes | the run, or a unique prefix of its id |

**Flags**

| Flag | Description |
| --- | --- |
| `-f, --follow` | follow until the run settles |
| `--url <u>` | attach to a specific orchestrator (skips kube entirely) |
| `-n, --namespace <ns>` | the deployment's namespace (default: the config's `name`, then the Instance folder's name) |
| `--context <ctx>` | the kube context (default: kubectl's current context) |

**Environment**

| Variable | Description |
| --- | --- |
| `JR2_URL` | the orchestrator to attach to, when `--url` is not given |
| `JR2_TOKEN` | the Instance token to send: with `--url` / `JR2_URL` the only one, and otherwise used in place of the one read from the cluster |

**Output**: result, one JSON result on stdout, and activity on stderr. See [Output](#output).

**Decisions**: [ADR-0009](decisions/0009-cli-and-instance-interface.md).

<a id="send"></a>

### `jr2 send`

```sh
jr2 send <runId> --event CANCEL [--keep] [--url <u>] [-n <ns>] [--context <ctx>]
jr2 send <runId> --gate <gate> --event <name> [--input <json>] [--url <u>] [-n <ns>]
[--context <ctx>]
```

Abandon a live run, or deliver a workflow event to an open gate.

With `--event CANCEL`, `--keep`: abandon a live run and destroy its Workspaces; --keep keeps them for inspection until the idle timeout.

With `--gate <gate>`, `--event <name>`, `--input <json>`: deliver a workflow event to an open gate.

**Arguments**

| Argument | Required | Description |
| --- | --- | --- |
| `runId` | yes | the run, or a unique prefix of its id |

**Flags**

| Flag | Description |
| --- | --- |
| `--event <name>` | CANCEL (run control), or with --gate an event the gate accepts Required. |
| `--gate <gate>` | the open gate to deliver the event to |
| `--input <json>` | the event's input, as a JSON object (with --gate) |
| `--keep` | with --event CANCEL: keep the Workspaces for inspection until the idle timeout |
| `--url <u>` | attach to a specific orchestrator (skips kube entirely) |
| `-n, --namespace <ns>` | the deployment's namespace (default: the config's `name`, then the Instance folder's name) |
| `--context <ctx>` | the kube context (default: kubectl's current context) |

**Environment**

| Variable | Description |
| --- | --- |
| `JR2_URL` | the orchestrator to attach to, when `--url` is not given |
| `JR2_TOKEN` | the Instance token to send: with `--url` / `JR2_URL` the only one, and otherwise used in place of the one read from the cluster |

**Output**: activity, activity on stderr only. See [Output](#output).

**Decisions**: [ADR-0009](decisions/0009-cli-and-instance-interface.md), [ADR-0011](decisions/0011-workflow-defined-events.md), [ADR-0013](decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md), [ADR-0025](decisions/0025-cancel-ends-a-run-stop-parks-it.md).

<a id="run-ids"></a>

## Run ids

Any `<runId>` above may be abbreviated to a unique prefix (4+ chars, git-style); an ambiguous prefix lists the candidates and fails rather than guessing.

<a id="env"></a>

## Env

The Instance's .env is loaded before any verb; a variable already set in the environment wins.

<a id="output"></a>

## Output

Result verbs (kit push, run, runs, status `<runId>`, logs) print one JSON result on stdout and activity on stderr, so `jr2 run … | jq` yields the result; report verbs (version, bare status) print a table on stdout, or the one object with --json; activity verbs (init, check, up, down, gc, send) print activity alone.

<a id="exit-codes"></a>

## Exit codes

| Code | Meaning |
| --- | --- |
| 0 | ok |
| 1 | runtime error |
| 2 | usage |
