Five commands, install to conformance. Everything leji does ships in the package and runs offline; what reaches the network, you invoke yourself. The dependency step in leji init and leji adopt runs your own package manager when you say yes, and the federation fetches contact the repository you named: leji mounts hydrate --fetch, leji mounts update-pin --fetch, and leji conformance --federation=verify.
All three pass the same fixture suite, so flags, JSON output and exit codes are identical whichever one your CI installs.
Declaring it as a dev dependency is what makes CI, the pre-commit hook and every contributor run one pinned version. You do not have to work out the command: leji init and leji adopt detect the package manager this repository actually uses and offer to run its own add command for you, only on your explicit yes: npm, pnpm, yarn and bun; uv, poetry, pdm and pipenv; and go get -tool, which needs Go 1.24 or newer, while building the Go CLI itself needs Go 1.26.6 or newer. With pip, leji prints the line to add instead of running anything. A global install stays out of the way: inside a repository that pins its own copy, the Node and Python CLIs run that copy for every invocation (the CLI a repository pins).
$ npm install -g @leji-org/leji
02Bootstrap a new context layer, or adopt an existing repo
You get a leji.json manifest at the repository root, a boot profile, seeded category documents, a first decision record, and an onboarding brief. Two files outside the context root come with them: a pointer-only AGENTS.md when the repository has none (--no-agents skips it), and a .gitignore line at the root for .leji/, the workspace the brief lives in. None of it requires an agent.
The scaffold starts as placeholder. Accept the offer and the agent reads your repository, proposes the mapping for you to approve, then deletes the brief. Decline and you get the command to run later; --yes skips it, so CI stays unattended.
Working alone? --mode solo seeds identity and writing-style starters and points the brief at an owner interview; answers can be typed, attached, or dropped in a folder. Only the synthesis you approve becomes context, and the raw material stays in the gitignored workspace at the repository-root .leji/: init and adopt write that ignore rule, and both refuse to run at all while anything under it is tracked. The agent deletes the artifacts once the context layer is populated.
leji adopt --dry-run # the exact write plan; nothing is writtenleji adopt # adopt an existing repo (leji init for a new one) # then offers to open Claude Code or Codexleji adopt --wire-adapters # adopt over an existing CLAUDE.md / AGENTS.mdnpm create leji # or all of that in one step, nothing installed: # it reads the directory and picks adopt or init
03Validate
Schema-checked: the manifest, the index, the changelog, and agent-profile and decision-record frontmatter.
Structure and lint: boot profiles, index files and ordinary documents have no schema. Declared files must exist, and the changelog is append-only against HEAD. At indexed and above, a stale index fails hard.
After a plain adopt over an existing CLAUDE.md or AGENTS.md, expect a vendor-adapter-redirect failure for each of them until --wire-adapters runs.
leji validate # schemas + lint rulesleji validate --content # + placeholder / thin-content warningsleji index # generate the index
04Claim a level, then check it
Partial adoption is by design: start at core, and each level contains the last. The manifest declares the claim; leji conformance scores the context layer against it.
The same layer your agents read, rendered for people.
leji view # open the human-readable viewer in your browserleji viewer build # export a static folder to host behind internal auth
Keep it honest in CI
The provider is inferred from your origin remote, falling back to GitHub when the remote names none.
leji ci # generate the workflowleji ci --hooks # the same gates as a local pre-commit# what the generated job runs:leji validate # schemas + lint rulesleji index --check # stale index fails# add at indexed and above:leji changelog check # append-only
Exit codes are CI-native: 0 clean, warnings allowed; 1 a check that did not pass, whether or not it reported a finding; 2 a usage error or an internal failure, such as a refusal to overwrite.
Enter the context layer
The layer becomes the agent's first context, with no vendor file in between.
leji start # or --agent claude-code | codex to pin one
Several hosts detected? It asks. None detected, or a scripted / CI run? It prints the command to run instead of guessing. The adoption guide covers host pass-through flags and the vendor-file fallback table.
Give your agent the tools, not just the context
Entering the context layer gives your agent the context. The MCP server gives it the tooling: a local, read-only server that runs validation and conformance against the context layer on disk, so the agent never needs a shell. It reads and reports; it never writes.
init and adopt offer to register it for you: project-scoped for Claude Code, user-level for Codex. The commands above are for anyone who skipped that prompt, and swapping --scope project for --scope user registers it once for you personally rather than for this repository. Any MCP client works; the MCP server page has the full tool list.