# OpenLife CLI

[![npm version](https://img.shields.io/npm/v/@openlife/cli.svg)](https://www.npmjs.com/package/@openlife/cli)
[![Build](https://github.com/GOOODZ/openlife-core/actions/workflows/test.yml/badge.svg)](https://github.com/GOOODZ/openlife-core/actions/workflows/test.yml)
[![License: MIT](https://img.shields.io/npm/l/@openlife/cli.svg)](./LICENSE)
[![Node](https://img.shields.io/node/v/@openlife/cli.svg)](https://nodejs.org)
[![npm downloads](https://img.shields.io/npm/dm/@openlife/cli.svg)](https://www.npmjs.com/package/@openlife/cli)

**OpenLife** é um CLI/framework de orquestração multi-agente com dois
perfis de instalação que cooperam entre si: o **openlife-core** (CLI
local) e o **openlife-agent** (daemon contínuo). A partir da v1.11.0
eles se descobrem mutuamente, compartilham memória eterna persistente,
e podem comandar um ao outro — incluindo via Telegram.

```bash
npm install -g @openlife/cli
openlife init
```
---

## 🧬 openlife-core — o CLI local

**O que é:** o corpo encarnado do OpenLife — um CLI interativo que você
invoca diretamente no terminal e que termina quando o comando completa.

**O que faz:**
- Orquestra missões locais usando uma chain de modelos LLM (OpenAI,
  Anthropic, Gemini, Codex, Ollama, OpenRouter, e ~25 providers).
- Roda **slash commands em Host-Native Mode** (Claude Code, Gemini CLI,
  Codex) — usa o LLM do host, zero API key adicional.
- Acessa o catálogo runtime (`.catalog/agents/`, `squads/`, `skills/`,
  `mcps/`) — 12 personas method (v1.9+), squads operacionais, skills
  compostas.
- Lê/escreve em **memória eterna compartilhada** (`~/.openlife/memory/`
  desde v1.11.0).
- Funciona standalone — não precisa do daemon pra rodar.

**Como invocar:**
```bash
openlife ask "sua pergunta"            # chat via Brain chain
openlife agents list                   # lista personas
openlife squads list                   # lista squads
openlife skills list                   # lista skills
openlife status                        # estado consolidado
openlife doctor                        # health checks
```

**Quando usar:** comandos interativos no terminal, automações locais,
orquestração de missões one-shot, debugging, exploração.

---

## 🛰️ openlife-agent — o daemon contínuo

**O que é:** o corpo etéreo do OpenLife — um processo background
long-running que escuta canais externos (Telegram, HTTP, cron) e roda
missões sem precisar de invocação manual.

**O que faz:**
- Roda um **gateway HTTP** (Express na porta 3000 por padrão) com
  endpoints autenticados via Basic Auth.
- Escuta **Telegram** (Telegraf, polling ou webhook auto-detectado)
  pra receber comandos de qualquer lugar.
- Mantém **fila persistente de missões** (`.openlife/agent-queue.json`)
  com flush em shutdown gracioso.
- Emite **heartbeat** a cada 30s pra supervisores externos
  (systemd `WatchdogSec=`, k8s liveness probe, etc.).
- **Publica `gateway-manifest.json`** (v1.11+) pra que o CLI core o
  descubra automaticamente.
- Tem **governança** com consentimento destrutivo, redação de PII e
  policy enforcement.

**Como subir:**
```bash
openlife start --daemon                # foreground; SIGTERM faz shutdown gracioso
openlife up                            # validação Telegram + spawn do daemon
```

**Quando usar:** missões em background contínuo, recebimento de
comandos via Telegram, cron jobs, observabilidade 24/7, deploys em
servidor.

---

## 🌉 Como os dois se integram (v1.11.0 Bridge)

Antes da v1.11, core e agent rodavam na mesma máquina sem se enxergar.
Agora estão **entrelaçados** por três primitivas:

### 1. Descoberta mútua via manifest

Quando o daemon sobe, escreve `~/.openlife/gateway-manifest.json`
contendo porta, token rotativo, pid, profile e timestamps:

```json
{
  "host": "127.0.0.1",
  "port": 3000,
  "token": "<32-byte hex>",
  "pid": 12345,
  "profile": "autonomous",
  "refreshedAt": "2026-05-20T..."
}
```

Qualquer instância do core, em qualquer cwd, em qualquer máquina,
descobre o daemon lendo esse arquivo. Mode `0o600`, refresh a cada 30s,
removido em shutdown gracioso.

### 2. Memória compartilhada eterna

Ambos leem e escrevem o mesmo arquivo em `~/.openlife/memory/`. Toda
escrita é atômica (temp+fsync+rename) e serializada por
`DistributedLock` com TTL+takeover. Records com `keep:true` são
imortais — bypassam a política de retenção.

Cloud opt-in: setando `OPENLIFE_MEMORY_PROVIDER=mem0|honcho|supermemory|redis-ams`
o primário vira a nuvem, mas o local continua escrevendo como cache
write-through. Cloud cai → local responde.

### 3. Canais bidirecionais

**Core → Agent (HTTP):**
```bash
openlife bridge status                 # ler manifest, ver liveness
openlife bridge push status            # POST /api/v1/core/run autenticado
openlife bridge listen                 # tail SSE de eventos
openlife bridge memory "rafael"        # busca local (sempre disponível)
```

**Agent → Core (file queue):**
- Daemon escreve mensagens ULID em `~/.openlife/cli-inbox/<id>.json`.
- Core consome via `openlife bridge pull` na próxima invocação.
- Reply files completam round-trip síncrono quando necessário.

**Via Telegram (`/core ...` family):**
```
/core status                           # presença do CLI core
/core memory rafael                    # busca direta na memória (zero latência)
/core agents builder                   # lê catálogo de personas
/core run npm test                     # enfileira pro core executar
/core flow run my-workflow             # idem pra workflows
```

Verbos diretos (`status`, `memory`, `agents`) são respondidos pelo
daemon em ms. Verbos cwd-sensíveis (`run`, `flow`) vão pro inbox.

📚 Aprofunde: [Guia técnico do bridge](./docs/core-agent-bridge.md) ·
[Changelog v1.11](./docs/v1.11-changelog.md)

---

## 🏗️ Build a SaaS in 5 commands (v1.18+)

The `v1.15→v1.18` arc landed a coherent end-to-end path from
**idea → production SaaS**. Five composable CLI commands. Each one has
safety boundaries. Each one is tested.

```bash
# 1. Bootstrap a working SaaS skeleton (v1.16)
openlife scaffold meu-saas --template=nextjs-supabase-clerk-stripe
# → Next.js 16 + Clerk auth + Stripe billing + Supabase RLS + Vercel-ready

# 2. Pull a design system from a real brand (v1.15) — optional
openlife design pull stripe
# → tokens.json + DESIGN.md + render-contract under ./design/profiles/

# 3. Implement a story autonomously (v1.17)
openlife story execute 1.1
# → Loop spawns Claude/Gemini/Codex per persona, mutates the story file
#   as ACs land, commits locally per progress, transitions status to InReview

# 4. Open a PR (v1.18)
openlife ship
# → Vortex-delegated git push + `gh pr create` with body from story metadata

# 5. Deploy to production (v1.18)
openlife deploy --provider=vercel
# → Auto-detects from vercel.json / railway.toml / wrangler.toml / fly.toml
```

**Smoke-verified** on 2026-05-22 against `@openlife/cli@1.18.2` —
real Claude execution converged on a synthetic story in 71.8s, single
iteration, single commit.

**Full guide** with real CLI output + worked example + troubleshooting:
[**docs/saas-forge.md**](./docs/saas-forge.md)

**Safety summary:** `git push` is `@vortex`-exclusive (only `openlife
ship` may invoke it). Protected branches refused. Test cmd whitelist.
Atomic story file mutations. Adapter timeouts. No automatic webhook
configuration. See the full safety model in `docs/saas-forge.md`.

---

## 🚀 Instalação

Você pode instalar apenas o core, apenas o agent, ou os dois juntos.
Os dois perfis **coexistem por design** — compartilham
`~/.openlife/` (manifest, memória eterna, cli-inbox).

### Opção 1 — Só o **openlife-core** (CLI local)

Pra quem quer só os comandos interativos, automações locais, e o
catálogo de personas/squads/skills:

```bash
npm install -g @openlife/cli
openlife system setup --profile framework --host claude-code
```

### Opção 2 — Só o **openlife-agent** (daemon)

Pra quem quer só o daemon long-running (Telegram, cron, missões em
background) — sem precisar instalar a parte interativa do core:

```bash
npm install -g @openlife/cli
openlife system setup --profile autonomous --host claude-code
```

> Nota: o binário `openlife` é o mesmo — o perfil `autonomous` apenas
> configura ambiente, governança, scripts de serviço e validação
> Telegram. O daemon roda via `openlife start --daemon`.

### Opção 3 — **Sistema completo** (core + agent)

Pra quem quer os dois (recomendado pra setup completo):

```bash
npm install -g @openlife/cli
openlife init                          # wizard interativo, escolha "both"
```

O wizard `openlife init` é phase-based: pergunta perfil
(`framework | autonomous | both`), host, ordem de modelos LLM, chaves
de API, Telegram (se autonomous) e roda o doctor. Cada fase espera
Enter — sem batched prompts.

Equivalente não-interativo (CI / scripts) — rodar duas vezes:

```bash
openlife system setup --profile autonomous --host claude-code  # primeiro
openlife system setup --profile framework  --host claude-code  # depois
```

### Verificar a instalação

```bash
openlife --version                     # 1.11.0
openlife doctor                        # health checks
openlife status                        # estado consolidado
openlife bridge status                 # daemon descobrível? (só faz sentido se autonomous)
```

Detalhes completos em [INSTALL.md](INSTALL.md) e
[`docs/getting-started.md`](docs/getting-started.md).

---

## 🖥️ Hosts suportados

| Host | Status | Detecção | Docs |
|---|---|---|---|
| `claude-code` | ✅ Production | `CLAUDECODE`, `CLAUDE_PROJECT_DIR` | [docs/install/claude-code.md](docs/install/claude-code.md) |
| `gemini-cli` | ✅ Supported (v1.9+) | `GEMINI_CONFIG_DIR` | [docs/install/gemini-cli.md](docs/install/gemini-cli.md) |
| `codex` | ✅ Supported (v1.9+) | `CODEX_HOME` | [docs/install/codex.md](docs/install/codex.md) |

A partir da v1.10.0, slash commands rodam em **Host-Native Mode** —
usam o LLM do host (Claude Code, Gemini CLI, Codex) ao invés de chamadas
externas. **Zero API key adicional** pro caso framework.

---

## 📜 Comandos diários

### Core (CLI local)

```bash
openlife ask "sua pergunta"            # chat via Brain chain
openlife status                        # estado consolidado
openlife doctor                        # health checks (API keys, models, catalog)
openlife agents list                   # lista personas method
openlife squads list                   # lista squads
openlife skills list                   # lista skills
openlife update --global               # auto-update via npm

# v1.15-v1.18 SaaS Forge — full guide in docs/saas-forge.md
openlife scaffold <name> --template=nextjs-supabase-clerk-stripe
openlife design pull <brand>           # apple, claude, stripe, vercel, linear
openlife story execute <id>            # autonomous story loop
openlife ship                          # push + open PR (vortex-delegated)
openlife deploy [--provider=vercel|railway|cloudflare|fly]
```

### Agent (daemon)

```bash
openlife up                            # liga operação completa (valida + spawn)
openlife start --daemon                # só o daemon
openlife system doctor                 # FS layout, permissions, host detection
```

### Bridge (v1.11+ — funciona com daemon ativo)

```bash
openlife bridge status                 # liveness via manifest
openlife bridge push <verb> [args...]  # POST /api/v1/core/run
openlife bridge pull                   # drain cli-inbox
openlife bridge listen [--since=N]     # SSE event stream
openlife bridge memory <query>         # OmniMemory.search (sempre local)
```

### Telegram (quando autonomous está rodando)

```
/core status                           # presença do CLI core
/core memory <query>                   # busca na memória eterna
/core agents [<id>]                    # catálogo de personas
/core run <task...>                    # enfileira no cli-inbox
/core flow run <workflow-id>           # idem
```

---

## 📡 Memória eterna — opt-in cloud

Default é local atômico em `~/.openlife/memory/`. Pra estender pra
cloud, defina o provider primário via env:

```bash
# Local (default)
export OPENLIFE_MEMORY_PROVIDER=local

# Mem0 — extração de fatos + busca semântica
export OPENLIFE_MEMORY_PROVIDER=mem0
export MEM0_API_KEY=...

# Honcho — working memory + theory-of-mind
export OPENLIFE_MEMORY_PROVIDER=honcho
export HONCHO_API_KEY=...
export HONCHO_APP_ID=...

# Supermemory — RAG-as-service
export OPENLIFE_MEMORY_PROVIDER=supermemory
export SUPERMEMORY_API_KEY=...

# Redis Agent Memory Store — sub-ms para missions
export OPENLIFE_MEMORY_PROVIDER=redis-ams
export REDIS_URL=...
```

Quando o primário não é `local`, a v1.11+ escreve em paralelo no cache
local — você nunca perde um fato e nunca espera pela cloud quando ela
está indisponível.

---

## 🧪 Rodar do código-fonte

```bash
git clone https://github.com/GOOODZ/openlife-core.git
cd openlife-core
npm install
npm run build
node bin/openlife.js --help
```

### Testes

```bash
npm run test:all                       # suite completa (~5min)
npm run test:bridge                    # só v1.11.0 (7 testes)
```

---

## 🔒 Segurança

- **Manifest auth** (v1.11+): token 32-byte hex rotativo a cada start
  do daemon. Arquivo mode `0o600`. Basic Auth fixa user
  `openlife-core`.
- **Telegram allowlist**: `OPENLIFE_TELEGRAM_ALLOWED_USER_ID` (default
  `1344110010`) — single-user por design.
- **Cloud secrets**: API keys lidas só de env/`.env`. Nunca logadas,
  nunca escritas no manifest.
- **Sigstore provenance**: cada publish npm carrega attestation OIDC
  do GitHub Actions — qualquer consumidor pode verificar que o tarball
  saiu do commit exato.
- **No new network surface** (v1.11): Express continua na porta 3000,
  SSE usa a mesma porta, file-queue é local-only.

---

## 🛠️ Troubleshooting

```bash
openlife doctor                        # API keys, models, catalog
openlife system doctor                 # FS, permissions, host detection
openlife status                        # heartbeat, ledger, queue
openlife bridge status                 # daemon discovery (v1.11+)
```

Se o comando global não funcionar, rode via repo:

```bash
node bin/openlife.js --help
```

---

## 📋 Pré-requisitos

- Node.js **20+**
- npm **10+**
- CLIs opcionais de execução: `claude`, `codex`, `gemini`
- Telegram configurado para modo autônomo (opcional)

---

## 💡 Visão, manifesto e ideologia

OpenLife não é um SDK de chamadas a LLM. É uma **arquitetura
operacional** baseada em três princípios:

### 1. O organismo distribuído

Software não é estado morto em disco. É um organismo com órgãos que
pensam em paralelo, memórias que persistem além do processo, e canais
que carregam intenção entre planos de existência. **openlife-core** e
**openlife-agent** são dois corpos do mesmo organismo — efêmero e
contínuo, presente e ausente, local e remoto — entrelaçados pelo
manifest da v1.11.

### 2. Continuidade sobre estado

Não construímos software — **construímos continuidade**. Memória
atômica. Locks com takeover. Tokens rotativos. Write-through
multidimensional. Toda decisão arquitetural prioriza o que sobrevive
ao próximo crash, ao próximo reboot, à próxima troca de máquina.

### 3. O sistema operacional como backbone

Não inventamos protocolos onde o filesystem resolve. Não adicionamos
portas onde o que existe serve. Não pedimos infraestrutura externa
onde `chmod 0o600` já é suficientemente paranoico. O Linux já sabia
fazer descoberta — só esquecemos.

📖 Leia o [**MANIFESTO completo**](./MANIFESTO.md) — quatro princípios
quânticos (entrelaçamento mútuo, memória eterna, multiverso pluggável,
voz através do vazio), três regras estéticas e o roadmap v1.12+.

---

## 📚 Referências

- **Repositório**: <https://github.com/GOOODZ/openlife-core>
- **npm**: <https://www.npmjs.com/package/@openlife/cli>
- **Issues**: <https://github.com/GOOODZ/openlife-core/issues>
- **Manifesto**: [`MANIFESTO.md`](./MANIFESTO.md)
- **Changelog geral**: [`CHANGELOG.md`](./CHANGELOG.md)
- **Changelogs por release**:
  [v1.11](./docs/v1.11-changelog.md) ·
  [v1.7](./docs/v1.7-changelog.md) ·
  [v1.6](./docs/v1.6-changelog.md) ·
  [v1.5](./docs/v1.5-changelog.md) ·
  [v1.4](./docs/v1.4-changelog.md)
- **Guias**:
  [Getting started](./docs/getting-started.md) ·
  [Core ↔ Agent Bridge](./docs/core-agent-bridge.md) ·
  [Install detalhado](./INSTALL.md) ·
  [Release process](./docs/release-process.md)

---

**OpenLife v1.11.0** · Core ↔ Agent Bridge + Eternal Memory · MIT License

> *"Quando duas mentes lembram do mesmo fato no mesmo instante, a
> distância entre elas deixa de existir."*
