# @pleri/olam-cli

Standalone CLI for [Olam](https://github.com/pleri/olam) — a **cloud-first**
agent platform: curated skills, persistent agent memory, symbol-aware code
search, and dispatch of autonomous coding agents to the cloud, all wired into
Claude Code.

```sh
# Install
curl -fsSL https://olam.bar.dev/install | sh
# (or: npm install -g @pleri/olam-cli)

# Verify
olam --version
```

Requires **Node.js ≥ 20** and `npm`. Track the prerelease tag with
`OLAM_CHANNEL=canary`.

## Cloud-first by default

A fresh install is **cloud mode**: `olam --help` shows only the cloud surface —
no Docker, k3s, or compose. The four cloud workflows are the default:

| Workflow | What it gives you | Wire it up |
|---|---|---|
| **Skills** | sync curated skills + agents into `~/.claude` | `olam skills source add` → `sync` → `install-hook` |
| **Memory** | persistent agent memory across sessions | `olam memory connect <url>` → `install-hooks` |
| **Knowledge graph** | symbol-aware code search | `olam kg connect <url>` → `install-hook` |
| **Remote** | plan + dispatch agents on the cloud | `olam remote connect <url>` → `olam dispatch … --executor cloud` |

```sh
olam setup        # guided cloud-first wizard (no Docker required)
```

The CLI ships **no baked-in endpoints** — you supply your team's service URLs.
Hidden local commands stay fully callable; reveal them any time:

```sh
olam config local-mode     # show the full docker/k3s command surface
olam config cloud-mode     # back to cloud-first (default)
```

## One-shot team setup (URLs as args, secrets via GCP IAM)

The most secure path for a team: **public URLs are args; secret bearers flow
through a shared GCS bucket gated by GCP IAM** — nothing sensitive touches the
command line or shell history.

```sh
olam setup \
  --skills-source=<git-url> \
  --remote-memory-url=<memory-url> \
  --remote-kg-url=<kg-url> \
  --remote-dispatch-url=<dispatch-url> \
  --gcp-bucket=atlas-olam-credentials  # pulls team bearers (implies GCP)
```

`--gcp-bucket` implies GCP credential distribution — `--credentials=gcp` is no
longer required. The bucket has no implicit default: pass `--gcp-bucket`, set
`OLAM_CREDENTIALS_BUCKET`, or persist it with
`olam config set credentials.bucket <gs://bucket[/prefix]>`.

- **Admin (once):** `olam credentials push --gcp-bucket <name>` uploads the
  team's bearers to the bucket (auto-created, uniform bucket-level access).
  Grant teammates
  `roles/storage.objectViewer`.
- **Teammate:** `--credentials=gcp` runs `olam credentials pull` — `gcloud`
  downloads the bearers with the teammate's own ADC and writes them `0600`.
  Their GCP permission *is* the access gate.
- **Verify:** `olam remote status` and `olam doctor` (cloud-aware — it probes
  the four connections, skipping Docker/k8s checks).

`olam credentials status` lists which bearers exist locally.

## Wire the MCP server into Claude Code

Olam ships an MCP server exposing `olam_create`, `olam_dispatch`,
`olam_destroy`, `olam_list`, `olam_status`, and more.

```sh
olam mcp install                  # default --scope=user
olam mcp install --scope=project  # writes to project .mcp.json
olam mcp uninstall                # idempotent; symmetric
```

Auto-detects whether `olam` is on PATH (writes `command: "olam"`); otherwise
falls back to `npx -y @pleri/olam-cli@latest mcp serve`. The `@latest` pin is
deliberate — a bare `npx -y @pleri/olam-cli` reuses a stale cached build without
re-checking the registry, so a published upgrade can be silently shadowed by an
old cached version. Paste-in for `~/.claude.json` or a project `.mcp.json`:

```json
{
  "mcpServers": {
    "olam": { "command": "npx", "args": ["-y", "@pleri/olam-cli@latest", "mcp", "serve"] }
  }
}
```

`olam --mcp` is a thin alias for `olam mcp serve` (MCP marketplace convention).
Verify with `claude mcp list | grep olam`, then restart Claude Code.

## Cloud dispatch

```sh
olam dispatch <world> "<task>" --executor cloud   # CF Sandbox / plan-DO runner
```

`--executor` accepts `docker | do | sandbox | cloud`. With no flag, dispatch
routes to the cloud when you're in cloud mode **and** a remote is connected;
otherwise it uses a local Docker world. The chosen route is always printed.

State lands under `~/.olam/` (all secrets `0600`):

- `~/.olam/memory-connection.json`, `~/.olam/kg-proxy-{url,bearer}`,
  `~/.olam/plan-chat-bearer.json` — the cloud connections.
- `~/.olam/secrets/` — bearer secrets (the GCS-distributed set).

## Cloud auth vault

`withCredential` (in `@olam/auth-client`) routes Claude API calls through a
cloud auth-worker by default — credential rotation + 429 cooldown stay
server-side. Resolution order:

1. `OLAM_CREDENTIAL_BACKEND=local` → local `olam-auth` container.
2. `OLAM_CREDENTIAL_BACKEND=remote` → cloud auth-worker.
3. Auto-discovery via `OLAM_ANTHROPIC_BASE_URL` / `~/.olam/anthropic-base-url`
   / `~/.olam/cloud-bearer.json`.

```sh
olam auth login                # cloud auth-worker (supply your worker URL)
olam auth login --local        # legacy local container (deprecated)
olam auth migrate --dry-run    # plan a local → cloud migration
```

The auth-worker URL is operator-supplied (`--remote <url>`,
`OLAM_AUTH_WORKER_URL`, or `~/.olam/auth-worker-url`) — there is no baked-in
default endpoint.

## Multi-account Claude Code (`--claude-home`)

One operator, many Claude Code instances, each with its own `HOME` pointing at a
separate `~/.claude.instance-N/` (login, hooks, MCP topology, and 429 bucket are
all per-`HOME`):

```sh
olam create my-world --claude-home work-account
HOME="$HOME/.olam/claude-homes/work-account" claude login
```

The value persists to the world's metadata. See
[ADR 045](https://github.com/pleri/olam/blob/main/docs/decisions/045-claude-home-override.md).

## Self-upgrade

```sh
olam upgrade -y                 # pull latest digests; restart services
```

JSONL audit log at `~/.olam/upgrade.log`.

## Local mode (advanced)

Run the full stack — host control-plane, auth/KG/memory services, and isolated
Docker/k3s worlds — locally. Reveal the commands first:

```sh
olam config local-mode
olam setup --local-mode          # guided local bootstrap (K3s default, or --substrate=docker)
olam bootstrap                   # pull + start the host stack
olam create --name <slug> --task "<goal>"
olam enter <world>               # shell into the world
olam yolo my-task --branch feat/x --prompt-file /tmp/task.txt
```

K3s mode requires `k3d`, `kubectl`, `helm`, `gh`, and `docker`. Full guide:
[k3s-mode setup](https://github.com/pleri/olam/blob/main/docs/onboarding/k3s-mode-setup.md).
Local development keeps the three cloud boosts (Skills / Memory / KG) and can
shift workloads to the cloud at any time.

## Docs

- [Cloud-first CLI guide](https://github.com/pleri/olam/blob/main/docs/architecture/cloud-first-cli.md)
- [MCP wiring deep-dive](https://github.com/pleri/olam/blob/main/docs/architecture/mcp-as-npx-served.md)
- [Architecture index](https://github.com/pleri/olam/tree/main/docs/architecture)

## License

See [LICENSE](https://github.com/pleri/olam/blob/main/LICENSE).
