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

# Setup

> Commands you run when setting base up, registering a workspace, changing how it is configured, storing an API key, checking the graph is healthy, or taking base off a machine again.

The commands here are the ones you run occasionally: once when you install, once per workspace, and then only when something needs changing or checking. `base doctor` is the exception, and it is worth running any time the graph feels wrong.

<Warning>
  `base uninstall --purge` deletes the entire global tier (the graph, your star commands and your stored secrets) with no preview and no confirmation. It is the only command in base with that combination. `base secret rm` also deletes immediately.
</Warning>

## base install

Install base on this machine: build it, put it on your path, create `~/.base-gbl/`, wire the hooks, and write the manifest.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base install
base install --skip-hooks
base install --starter-commands
base install --no-starter-commands
base install --full
```

| Flag                    | What it does                                                                            |
| ----------------------- | --------------------------------------------------------------------------------------- |
| `--carl <CARL>`         | Path to a `carl.json` file, for a one-time migration of older decisions.                |
| `--skip-hooks`          | Do not wire the hooks into `settings.json`.                                             |
| `--full`                | Register the other ChrisAI components (PAUL, SEED, SKILLSMITH) in the manifest.         |
| `--starter-commands`    | Install the starter star commands without asking: `*handoff`, `*fork`, `*base`, `*end`. |
| `--no-starter-commands` | Skip the starter star commands without asking.                                          |

**What the installer wires today.** It writes hooks into `~/.claude/settings.json`, appends a base section to `~/.claude/CLAUDE.md`, and installs the bundled `base-help` skill into `~/.claude/skills/`. That is one agent host. Other hosts are not wired by the installer, and there is no flag that wires them. You would be connecting them by hand. Established from source at `4866996`, the commit the shipped 0.13.2 binary was built from.

`--skip-hooks` leaves base installed as a command-line tool with nothing running automatically. That is the right choice if you want to try the commands before anything starts appearing in your sessions.

<Note>
  Running `base install` again is also how you refresh the bundled skill. `base update` moves the binary and leaves the skill where it was, so after an update the skill on your machine can describe the previous release. See [Known issues](/known-issues).
</Note>

## base activate

Enter a Skool classroom key to remove attribution.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base activate YOUR-KEY-HERE
```

The key comes from the ChrisAI community. base works without it.

## base update

Update the base binary from public GitHub releases, or quiet the banner that tells you to.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base update --check
base update
base update --force
base update --snooze
```

| Flag       | What it does                                                        |
| ---------- | ------------------------------------------------------------------- |
| `--check`  | Report whether a newer release exists, without installing anything. |
| `--force`  | Install even when you are already on the latest version.            |
| `--snooze` | Dismiss the update banner for 24 hours.                             |

`--check` re-validates as well as reporting, so it is the honest answer to "am I current" rather than a cached one.

## base uninstall

Take base off this machine: remove the hooks from `settings.json`, remove the binary, and strip the base section out of `CLAUDE.md`.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base uninstall
base uninstall --purge
```

| Flag      | What it does                |
| --------- | --------------------------- |
| `--purge` | Also delete `~/.base-gbl/`. |

<Warning>
  **`--purge` is the one to be careful with.** `~/.base-gbl/` holds the global graph, your star commands and your stored secrets. There is no preview, no confirmation prompt and no backup. Plain `base uninstall` leaves all of it in place, so reinstalling later picks up where you left off.
</Warning>

## base scaffold

Set a directory up as a workspace: create `.base/`, write the initial configuration files, and register it globally.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base scaffold
base scaffold ~/basemode
```

The path is positional and defaults to the directory you are in.

Do this for every real project before you work in it. Outside a registered workspace, base refuses to write at all rather than guessing a tier: you get `no .base/ directory found` and the two ways forward, which are scaffolding here or passing `-g` to target the global tier deliberately. Earlier versions fell back to global silently, and a handoff filed that way resurfaced in every unrelated project forever.

### base workspace sync

Regenerate the registered-workspaces block in `~/.claude/CLAUDE.md` from `base.toml`.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base workspace sync
```

`base.toml` is the source of truth for what is registered; this command republishes it. There is no `base workspace list`. Read `base.toml`, or run `base project list --all`.

## Operator profile

The operator profile is who you are: the identity block that gets loaded alongside everything else.

### base operator init

Create the profile at `~/.base-gbl/operator.toml`.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base operator init --name "Chris"
```

| Flag            | What it does         |
| --------------- | -------------------- |
| `--name <NAME>` | Your name. Required. |

### base operator show

Print the current profile.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base operator show
```

## Configuration

`base.toml` holds base's settings, and these three commands read and write it using dot-notation keys.

### base config get

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base config get memory.mode
base config get signal.enabled
```

### base config set

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base config set multimodal.enabled true
base config set devmode.enabled true
```

Both arguments are positional: the key, then the value.

### base config list

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base config list
```

Run this before setting anything. It shows the keys that exist and what they are currently set to, which is faster than guessing at a key name.

## Secrets

Secrets live in `~/.base-gbl/.env` with `0600` permissions. Plugins read them from their environment, which is the point: a key set this way never has to be typed into a chat.

### base secret set

Prompt for a secret with echo off. The value is masked as you paste it and never printed back.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base secret set GEMINI_API_KEY
```

The key name is positional. The value is prompted for, not passed as an argument, so it never lands in your shell history.

### base secret list

List the key names you have stored, with masked values.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base secret list
```

This never prints a full secret.

### base secret rm

**Destructive, no preview.** Remove a stored secret.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base secret rm GEMINI_API_KEY
```

## base doctor

Diagnose graph health across both tiers, and repair or restore it. It exits nonzero when the graph is unhealthy, which makes it usable in a script.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base doctor
base doctor --json
base doctor --repair
base doctor --restore
base doctor --restore 2026-08-25T10-14-02
```

| Flag                    | What it does                                                                                   |
| ----------------------- | ---------------------------------------------------------------------------------------------- |
| `--json`                | Emit machine-readable JSON instead of the human report.                                        |
| `--repair`              | Quarantine malformed lines and atomically rewrite the good set. Backs up first.                |
| `--restore [<RESTORE>]` | Restore the workspace graph from a backup snapshot. On its own, lists the snapshots available. |

The check itself does not depend on the parser, so it still gives a straight answer about a graph that other commands are choking on. Run bare `--restore` first to see what snapshots exist before naming one.

## base dashboard

Launch the Command Center, a local web interface over the graph.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base dashboard
base dashboard --port 4000
```

| Flag            | Short | What it does                              |
| --------------- | ----- | ----------------------------------------- |
| `--port <PORT>` | `-p`  | Which port to serve on. Defaults to 3741. |

`base dash` is the short alias.

## Extensions

An extension adds commands to base. `base ext` is the short alias.

### base extension list

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base extension list
```

### base extension validate

Check an extension manifest before you trust it.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base extension validate ./base-extension.toml
```

Validate anything you did not write yourself. This reads the manifest and reports whether it conforms, without installing anything.

### base extension install

Install an extension from a validated manifest file.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base extension install ./base-extension.toml
base extension install ./base-extension.toml --bundle
```

| Flag       | What it does                                                                        |
| ---------- | ----------------------------------------------------------------------------------- |
| `--bundle` | Copy the handler into `~/.base-gbl/plugins/<name>/` and repoint the manifest at it. |

Without `--bundle`, the installed manifest points back at wherever the handler currently sits, so moving or deleting that folder breaks the command. With it, the install is self-contained and survives the source repository going away.

### base extension add

Fetch a plugin's prebuilt binary for this machine from its GitHub release, verify the checksum, unpack it and install it. No build toolchain needed.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base extension add ./base-extension.toml
```

The manifest needs a `[dist]` block for this to work. Where no prebuilt asset matches your machine, it falls back to building from local source.

### base extension scaffold

Create a new conformant cross-platform plugin.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base extension scaffold weather
base extension scaffold weather --path ~/dev --build --git
base extension scaffold weather --bootstrap
```

| Flag            | What it does                                                                       |
| --------------- | ---------------------------------------------------------------------------------- |
| `--path <PATH>` | Parent directory to create `<name>-cli/` in. Defaults to the directory you are in. |
| `--into <INTO>` | An exact target folder, new or empty, instead of the default `<name>-cli`.         |
| `--repo <REPO>` | GitHub `owner/repo` for releases. Defaults to `ChristopherKahler/<name>-cli`.      |
| `--build`       | Run the prepare script after writing the files.                                    |
| `--git`         | Initialize a repository and make the first commit.                                 |
| `--create-repo` | Create a private GitHub repository, wire the remote and push. Implies `--git`.     |
| `--bootstrap`   | All of it at once: build, git, and create the repository.                          |

The name you pass becomes the command, so `base extension scaffold weather` gives you `base weather`.

### base extension run

Run a plugin command explicitly, by name.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base extension run weather
```

Anything after the name is forwarded to the handler untouched, so `base extension run weather --city Austin` reaches the plugin exactly as you typed it. Use this form when a plugin command's name collides with something else. It is unambiguous where the bare `base weather` might not be.

### base extension remove

**Destructive.** Remove an installed extension by name.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base extension remove weather
```

## base hook

Handle one hook event. You do not normally run this yourself: the installer wires it into your agent host's settings, and it is what fires at session start, on each prompt you send, and around tool calls.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
base hook session-start
base hook user-prompt-submit
base hook pre-tool-use
base hook post-tool-use
base hook stop
```

The event type is positional, and those five are all of them.

<Note>
  `base help hook` names only three of the five. The binary handles `pre-tool-use` and `stop` as well; verified from source at `4866996`, where the dispatcher has an arm for each. The help string is out of date, not the command.
</Note>

Running one by hand is how you see exactly what a hook would emit, which is useful when nothing is arriving and you want to know whether the hook itself is producing anything. Feed it the JSON the event expects:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
echo '{"prompt":"we need to refund the invoice"}' | base hook user-prompt-submit
echo '{}' | base hook session-start
```
