Estelle
by uqeu
README.md
# Estelle CLI
**The software factory under your AI coding agents.** Team memory, code review, QA, CI, security and
Atlas, grounded in your real codebase.
It is not another agent. It runs underneath the agents you already use and gives them three things they do
not have on their own: memory of your repository, grounded code review, and push protection on every write. Model-agnostic, bring your own key.
This repository holds the Rust CLI. Plugins, hooks and MCP connection setup now ship from
[estelle-plugins](https://github.com/uqeu/estelle-plugins), with their own releases. The hosted server
is separate.
## Install
```sh
curl --proto '=https' --tlsv1.2 -fsSL \
https://github.com/uqeu/estelle-cli/releases/latest/download/install.sh | sh
```
That is the whole install. It detects your platform, downloads from this repository's latest release,
verifies the archive against the release's `SHA256SUMS`, rejects archives with unexpected members, and
atomically installs `estelle` into `~/.local/bin`. macOS or Linux, arm64 or x86_64. `install.sh` is a
POSIX installer; on Windows (x64, releases after v0.4.2) install through npm below.
The same binary is on npm for machines that are already npm-based:
```sh
npm install -g @fatelabs/estelle
```
## Plugins and hooks
For Claude Code, Codex, Kimi Code, Grok Build and Cursor, use
[estelle-plugins](https://github.com/uqeu/estelle-plugins). Each host has its own folder and a copy/paste
setup prompt. These packages require Node.js 22 or later; they do not require the Rust CLI.
Already using this repository's plugin or `estelle install-hooks`? Follow the
[migration instructions](https://github.com/uqeu/estelle-plugins/blob/main/docs/migration/from-cli.md).
Replace only the old Estelle hooks and connection, preserve unrelated settings, then approve the new
plugin through your host and start a fresh session. Existing installations are not changed by this move.
The MCP endpoint stays at `https://api.fatelabs.ca/mcp`. A direct connection is also available:
```sh
claude mcp add --transport http estelle https://api.fatelabs.ca/mcp
```
A direct MCP connection does not install hooks or capture your local session. Use the host package above
for hooks; conversation capture support is listed in the
[host support matrix](https://github.com/uqeu/estelle-plugins/blob/main/docs/SUPPORT.md).
## What the CLI does
```sh
estelle sweep # index this repo into your memory
estelle ask "how does billing retry a failed charge?"
estelle verify src/http/headers.rs # resolve every symbol against the repo's real symbol graph
estelle gate # retired 2026-10-29: prints a notice, exits 0
estelle mcp-server # Estelle's tools over MCP, for any agent
estelle acp # Agent Client Protocol, over stdio
estelle sessions import --dry-run # what earlier sessions on this machine would be added to your timeline
estelle sessions import # add them (Claude Code + Codex transcripts, real timestamps, idempotent)
```
Answers cite the files and lines they came from. When Estelle cannot ground an answer, it says so instead
of inventing one. `estelle --help` lists all thirty-two commands.
The session timeline on the dashboard is fed by the stream hook from the moment it is installed, so sessions
that ran before it are not on it. `estelle sessions import` sends the transcripts Claude Code
(`~/.claude/projects`) and Codex (`$CODEX_HOME/sessions`) still hold on this machine, through the hook's own
mapping and secret redaction, under the hook's own session and event ids, so a re-run or a later live stream sends
nothing twice. It deletes nothing. It can only import what the host kept: Claude Code prunes old transcripts.
`estelle setup` mentions it when this machine holds sessions the timeline does not have.
To bypass credential storage, set `ESTELLE_API_KEY` in the process environment. It takes precedence over
`~/.estelle/auth.json` and is never persisted by Estelle.
To point the CLI and its hooks at a different Estelle API (a local or self-hosted server), set
`ESTELLE_API_URL`, for example `ESTELLE_API_URL=http://localhost:8787`. It must be `https`, or plain `http`
only for `localhost`, `127.0.0.1` or `[::1]`; an invalid value is refused rather than silently replaced by
`https://api.fatelabs.ca`. The credential is sent to that host, so use a key that server issued.
## What is measured
Estelle's grounding gate caught **38,153 of 38,153 invented APIs**, with **0 false positives on 6,933 real
symbols**, over 45,086 labelled cases. It makes no model call: it parses the change and resolves each
symbol against the repository's indexed symbol graph, so the verdict is a property of the artifact rather
than a score that moves between runs.
Read the limit in the same breath, because it is the part that decides whether the number applies to you:
- **That measures invented repository APIs, in Python.** A case is one code reference naming a repository
symbol or import the codebase does not define.
- **Twelve of twenty-three supported languages block** at some rung. Python is the only one with the full
guarantee of existence, arity, type, and member calls on any receiver. The other eleven are navigated,
not gated: their references are excluded from the rate rather than counted as passes.
- **It is not a correctness claim.** Code can be perfectly grounded and still wrong.
- The eval harness is not in this public repository, so you cannot re-run it from here. What you can check
from here is the behaviour, on your own code, with `estelle verify` and `estelle gate`.
Fixes are proposed, not merged. The default writes to a sandbox and opens a pull request a human reviews.
Auto-merge is opt-in, off by default, and gated on the fix being proved green in a sandbox first. There is
no auto-deploy step.
The component boundaries, trust model, release path, measurements, provenance inventory, and named limits
live in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md), [`docs/SCORECARD.md`](docs/SCORECARD.md), and
[`docs/WHAT-WE-BUILT.md`](docs/WHAT-WE-BUILT.md).
## How a release is verified
Public releases are cut by [`.github/workflows/release.yml`](.github/workflows/release.yml) and carry five
checksummed binaries: macOS and Linux, arm64 and x86_64, plus Windows x86_64 (from the first release after
v0.4.2). The workflow refuses a tag that disagrees with the
version in `Cargo.toml`, `npm-shim/package.json`, `estelle-plugin/.claude-plugin/plugin.json`, or
`.claude-plugin/marketplace.json`, builds from the lockfile with warnings denied, and requests a
GitHub-signed SLSA build provenance attestation for every published artifact.
Neither installer checks that attestation for you, so verify it yourself if you want the stronger
guarantee:
```sh
gh attestation verify estelle-<target>.tar.gz --repo uqeu/estelle-cli
```
`ESTELLE_RELEASE_REPOSITORY` is an explicit operator and test override that changes the installer's trust
root. Normal installs must leave it unset.
## Provenance
Forked from OpenAI Codex at commit `582569998181aad08a88bacc151a94b2048a5d1f`. The fork boundary and the
egress census are enforced by `scripts/check-fork-audit.py` and `fork-manifest.yaml` on every release.
---
[fatelabs.ca](https://www.fatelabs.ca) · [docs](https://www.fatelabs.ca/docs) ·
[install guide](https://www.fatelabs.ca/docs/install) · Apache-2.0
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessOutdated data