> ## Documentation Index
> Fetch the complete documentation index at: https://orbit.nckrtl.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# tool

> Discover installed packages, adopt one installed package, and install, update, show, and remove one package through apt, Vite+, Composer, or Homebrew.

The `tool` family manages packages on a Node. A Tool is one package that Orbit manages through one Tool Manager. The [Tools reference](/docs/reference/tools) explains where Tools run, the supported managers, and the discovery, adoption, install, update, and removal rules.

## Commands

| Command | Result |
| - | - |
| [`tool:manager:list`](#orbit-toolmanagerlist) | List the managers a Node supports and their state. |
| [`tool:scan`](#orbit-toolscan) | Discover installed Homebrew and Vite+ packages without taking ownership. |
| [`tool:adopt`](#orbit-tooladopt) | Register one supported installed package without changing it. |
| [`tool:install`](#orbit-toolinstall) | Install one package, and install its manager first when needed. |
| [`tool:list`](#orbit-toollist) | List the Tools on a Node. |
| [`tool:show`](#orbit-toolshow) | Show one Tool. |
| [`tool:update`](#orbit-toolupdate) | Update one Tool within its constraint. |
| [`tool:remove`](#orbit-toolremove) | Remove one Tool and delete its record. |

Every command accepts `--json`. `--node` takes a positive numeric Node ID. The CLI refuses any other value with `tool.node_id_invalid`.

## orbit tool:manager:list

List every manager the Node supports, with its ID and state. An `uninstalled` manager has no ID.

```bash theme={"dark"}
orbit tool:manager:list --node=ID [--json]
```

## orbit tool:scan

Read installed Homebrew formulae, casks, and Vite+ global packages for one Node. The result distinguishes registered ownership, dependencies, adoption support, and each manager's scan state. It changes no packages or Tool records. An unsuccessful scan is explicit, not an empty successful inventory. The HTTP shape, scan states, and error codes are in [Discover installed packages](/docs/reference/tools#discover-installed-packages).

Human output shows the Node, the inspection time, and one row for each manager's scan state. It then shows one row for each package from a `complete` manager: manager, package, kind, version, dependency, Tool ID when the package is registered, and adoption. An unsupported package includes its block token. A null version, including a non-SemVer formula revision or cask version, is an em dash. A manager that is `absent`, `unsupported`, `incomplete`, or `conflicting` is named separately, because its empty package list is not an inventory. JSON output is that inventory plus `request_id`.

```bash theme={"dark"}
orbit tool:scan --node=ID [--json]
```

## orbit tool:adopt

Take ownership of one supported installed package. The Gateway checks its live state again and records intent without reinstalling or updating it.

```bash theme={"dark"}
orbit tool:adopt <package> --node=ID --manager=MANAGER [--constraint=CONSTRAINT] [--yes] [--json]
```

Use `brew` for a Core formula, `brew-cask` for a supported official macOS cask, `vp` for a package in the enrolled account's Vite+ global scope, or `apt` or `composer` on Linux. The optional SemVer constraint must accept the installed version. A repeated adoption with the same intent is unchanged. A missing or unsupported package or a conflicting constraint fails without creating a Tool. The HTTP body, outcomes, and error codes are in [Adopt a Tool](/docs/reference/tools#adopt-a-tool).

Without `--yes`, a terminal asks `Take ownership of package [name] (manager on Node #ID) and manage later updates and removal?` The question includes `, constraint <range>` when a constraint was supplied. The default is No. Noninteractive and JSON calls require `--yes`. Declining, Ctrl-C, or end of input exits with `input.cancelled` and sends no request. A call that cannot prompt exits with `input.confirmation_required` and sends no request.

Human output uses the Tool detail. `applied` says the package was adopted, including a repair of a failed row. `unchanged` says this ownership already exists and the progress settles as `Ownership unchanged`. JSON output is that Tool object plus `request_id`. A refusal prints the Gateway code and message. Its `details` keep `step`, `outcome`, `id`, and `adoption_block` when the Gateway sent those safe tokens. Node access records stay out of the CLI error.

## orbit tool:install

Install one package on a Node.

```bash theme={"dark"}
orbit tool:install [package] --node=ID [--manager=MANAGER] [--constraint=CONSTRAINT] [--json]
```

| Argument | Required | Meaning |
| - | - | - |
| `package` | when the command cannot prompt | The package name in the manager's own form, at most 255 characters. In a terminal, the command asks for it. Otherwise it fails with `tool.package_required`. |

| Option | Meaning |
| - | - |
| `--node=ID` | Numeric Node ID. |
| `--manager=MANAGER` | `apt`, `vp`, `composer`, `brew`, or `brew-cask`, limited to those the Node supports. In a terminal, the command offers the Node's `active` and `uninstalled` managers. Otherwise it fails with `tool.manager_required`. |
| `--constraint=CONSTRAINT` | Optional SemVer range. It only stops an unsafe version. |

```bash theme={"dark"}
orbit tool:install @openai/codex --node=12 --manager=vp --constraint='^0.150'
orbit tool:install laravel/installer --node=12 --manager=composer
orbit tool:install ripgrep --node=12 --manager=brew
```

Use `vp` for npm packages such as Codex and Claude Code, `composer` for `vendor/package` tools, `apt` for Ubuntu packages, and `brew` for a Homebrew Core formula with a compatible verified bottle. `brew-cask` manages supported official Homebrew casks on macOS.

The result is `applied` for a new install. It is `unchanged` when the Tool already exists and its package is installed, such as on a retry or a repeated install. When an install fails after the Gateway created the Tool, the error names the Tool ID, so you can retry or remove it.

## orbit tool:list

List the Tools on one Node with their manager, package, version, and status.

```bash theme={"dark"}
orbit tool:list --node=ID [--json]
```

## orbit tool:show

Show one Tool.

```bash theme={"dark"}
orbit tool:show <tool> [--json]
```

## orbit tool:update

Update one Tool to the manager's current candidate.

```bash theme={"dark"}
orbit tool:update <tool> [--json]
```

The result is `applied` when the version changed and `unchanged` when it did not. It is `blocked_by_constraint` when the candidate falls outside the stored constraint. The Tool then stays as it is.

## orbit tool:remove

Remove one Tool and delete its record.

```bash theme={"dark"}
orbit tool:remove <tool> [--yes] [--json]
```

| Option | Meaning |
| - | - |
| `--yes` | Skip the confirmation. A call without a terminal, or with `--json`, needs it. |

Without `--yes`, the command reads the Tool first. An unknown ID fails there with `http.404`. In a terminal, the command then asks `Remove Tool [package] (manager on Node #ID) by uninstalling it and deleting its record?`. The default answer is No. Declining, Ctrl-C, or end of input exits with `input.cancelled` and changes nothing. Without a terminal, the command fails with `input.confirmation_required`.

A failed removal keeps the Tool as `failed`. Run the same command again to retry. [Remove a Tool](/docs/reference/tools#remove-a-tool) lists each outcome.

## Related

* [`node`](/docs/cli/node) adds the Nodes that run the managers.
* [`doctor`](/docs/cli/doctor) reports Tool drift without changing packages.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.