Skip to main content
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.
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.

base install

Install base on this machine: build it, put it on your path, create ~/.base-gbl/, wire the hooks, and write the manifest.
A new install writes [devmode] enabled = false into ~/.base-gbl/base.toml, with a comment naming base config set devmode.enabled true. On a terminal, base install (and base scaffold) asks once whether to add the CORRECTED line, unless your CLAUDE.md already asks for a marker like it; see Corrections and tuning. The hooks it wires now include Claude Code’s SessionEnd event. 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 0ace1ba, the commit the shipped 0.15.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.
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.

base getting-started

What to read once base is installed.

base activate

Retired. Kept parseable so a scripted base activate <key> is not an error; it prints one line and exits 0.
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.
--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.
--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.

base scaffold

Set a directory up as a workspace: create .base/, write the initial configuration files, and register it globally.
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.
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.

base operator show

Print the current profile.

Configuration

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

base config get

base config set

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

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.
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.
This never prints a full secret.

base secret rm

Destructive, no preview. Remove a stored secret.

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.
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. --restore takes only a file base made, so it can never overwrite something else; every line an update prints carries the exact --restore command for its own backup. --fix repairs what doctor reports: records that belong to another workspace move to that workspace’s graph (or, when it cannot be found, to .base/foreign-<name>.nq beside this one); a correction that names exactly one record is linked to it, and the rest stay corrections; a record marked superseded with no replacement link, or the reverse, is settled; the old [signal] max_chars setting is removed (a value you chose moves to [budget] memory_chars); each graph is compacted and its backups cut to [graph] keep_backups (3). Nothing is deleted. An update runs the same repair once by itself. What doctor reports, beyond the health verdict, all as advice that never changes the verdict:
  • what each hook printed: the last run and the largest recent one against its budget, and the blocks it held back;
  • whether [budget] measured_on matches the Claude Code you run, with base doctor --measure when it does not;
  • broad path triggers (a folder holding other projects) and relative ones, with base domain paths --suggest;
  • project next steps that are undated or older than [doctor] stale_next_days (14);
  • your rules, from the match log: rules not served in [doctor] dead_days (30), domains whose keywords fire on more than [tune] broad_share of your prompts, rules served and then corrected at least [doctor] ignored_after (3) times and twice as often as the average, decisions served [doctor] review_served (20) times but unchanged for [doctor] review_days (60), how many corrections the detector caught and missed, the rules held back for space most often, and the longest rules, each with what to do;
  • for 14 days after an update turned developer mode off, how to turn it back on.
A workspace whose folder was renamed after base wrote its data stays UNHEALTHY with the reason: doctor will not move that data by itself, because only you can say whose it is.

base dashboard

Launch the Command Center, a local web interface over the graph.
base dash is the short alias.

Extensions

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

base extension list

base extension validate

Check an extension manifest before you trust it.
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.
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.
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.
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.
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.

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.
The event type is positional, and those six are the ones Claude Code sends. session-end only marks the session as ended for the rule pass. base also starts base hook upgrade itself, in the background, at the first session start after an update.
base help hook names only three of them. The binary handles the rest as well; verified from source at a37b9a8, where the dispatcher has an arm for each. The help string is out of date, not the command.
A hook started by base’s own headless Claude calls (base graph extract, base graph query, base doctor --measure, base tune) sees BASE_HEADLESS=1 and exits at once, printing and logging nothing. 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:

base hooks manifest

Print the hook command table as JSON, for an installer outside base.

base hooks show

Print one block of this session’s last prompt-hook output, exactly as the hook built it.
The prompt hook fits what it adds to [budget] prompt_bytes by dropping whole blocks, least important first. Each dropped block leaves one line naming it and this command, and rules held back leave their titles under it. With no block, it lists the last prompt’s blocks. The blocks are kept per session in .base/hook-output/<session id>/prompt-blocks.json.