spec 1.0 · referencia
Referencia de la CLI
Traducción asistida por agentes de IA. Ante cualquier diferencia, prevalece la página en inglés. Si encuentra algún problema en el texto, abra un issue o envíe un pull request.
Reference CLI for the Leji specification: validate, index, changelog, freshness, conformance, badge, status, route, mounts, export, viewer/view, detect, adopt, init, start, ci, and agent for a shared context layer.
Instálela en el runtime que utilice su cadena de herramientas o su integración continua; la interfaz de comandos es idéntica en los tres. Todos los comandos aceptan --root <dir> para apuntar a una capa existente; init y adopt crean una nueva, por lo que indican su destino con --dir <path>. Los comandos que informan emiten además --json legible por máquinas. La misma especificación genera esta referencia y leji --help. ¿Trabaja a través de un agente? La misma validación y conformidad están disponibles como herramientas MCP.
Instalación
npm install -g @leji-org/leji¿Es la primera vez que usa Leji? El inicio rápido explica la instalación y, después, el andamiaje o la adopción de su primera capa de contexto.
leji <command> [options]Get started
init | Bootstrap a new context layer from the templates. |
adopt | Adopt Leji into an existing repository. |
start | Open a coding agent in this context layer, booted from the boot profile. |
agent | Bind an additional named agent into an existing context layer. |
detect | Detect the coding-agent hosts available on this machine. |
ci | Add a CI workflow that runs leji validate and index --check on every change. |
Every day
validate | Validate the context layer: manifest, artifacts, frontmatter, and lint rules. |
index | Generate the context index at the declared path, or verify it is current. |
status | Report unindexed, dangling, and stale documents in the context layer. |
conformance | Score the context layer against its claimed conformance level. |
badge | Write the self-attested conformance badge for this repository. |
freshness | Report review horizons across category documents and agent profiles. |
route | Show the governed context a task's scope routes to. |
changelog check | Verify the machine changelog: schema and append-only discipline. |
changelog compact | Fold the oldest changelog entries into a single compaction entry. |
Federation
mounts hydrate | Materialize declared federation mounts into the resolver cache. |
mounts status | Report each mount's availability, integrity, and pin ancestry. |
mounts locate | Print resolver state for one mount: projection path, pin, verification. |
mounts update-pin | Move a declared mount's pin forward to a witnessed commit, showing the comparison first. |
Viewer and export
viewer | Generate the static viewer for the context layer. |
viewer serve | Generate the viewer and serve it locally. |
view | alias de viewer serve |
export | Export the context layer as a self-contained static site. |
viewer build | alias de export |
Códigos de salida
| Código | Significado |
|---|---|
0 | Clean. No errors; warnings are allowed. |
1 | A check did not pass. Usually an error finding was reported; some commands also use it for a negative result with no finding, such as status --strict flagging an entry, mounts locate finding no hydrated projection, or start finding no boot profile. |
2 | Usage error, or an internal failure (e.g. init refusing to overwrite). |
Opciones globales
--root <dir> | Repository root to operate on (default: the current directory). With the Node and Python CLIs, a root that declares and installs the Leji CLI for that runtime, meeting the layer's minimum, runs that copy. |
--json | Machine-readable JSON output instead of human-readable text. |
-v, --version | Print the Leji version and exit. |
-h, --help | Show help and exit. |
Cuando se ejecuta desde una copia de trabajo del código fuente de Leji, en vez de desde un paquete instalado, la CLI añade un marcador de compilación a la versión que muestra: un sufijo +dev. con la revisión corta en la que está esa copia, o un +dev a secas cuando la revisión no se puede leer. Una copia instalada imprime la versión a secas.
La CLI que fija un repositorio
Dentro de un repositorio que declara directamente la CLI de Leji y la tiene instalada, con una copia que cumple el mínimo de la capa, el leji instalado ejecuta esa copia en cada invocación, incluidas --version y --help. Node la encuentra bajo node_modules; Python la encuentra en un entorno de proyecto dentro del repositorio (.venv, o el UV_PROJECT_ENVIRONMENT de uv). Así, quien teclea leji, el hook de git, la integración continua y todos los compañeros de equipo ejecutan una misma versión de la herramienta, sea cual sea la que cada uno instaló de forma global. Fuera de esos casos, la CLI global se ejecuta exactamente igual que antes.
Defina LEJI_NO_LOCAL con cualquier valor para ejecutar la copia global en su lugar. La CLI de Go no delega la ejecución en otra copia, porque la copia declarada de un repositorio de Go la construye la cadena de herramientas cuando hace falta en vez de instalarse como ejecutable: ejecute la copia fijada con go tool leji. ¿Actualiza la CLI de Python? Un script de consola ya instalado adquiere la capacidad de delegar la ejecución en la copia local tras una reinstalación, que vuelve a generar el punto de entrada.
leji init
Scaffolds a new context layer from the templates.
- Writes
leji.json, a boot profile, a pointer-onlyAGENTS.md(the portable entrypoint many agent hosts read, redirecting to the boot profile;--no-agentsskips it), seeded category documents, a first decision record, an agent onboarding brief, and a generated index, so the scaffold is ready for the CI jobleji ciwrites. At the indexed level it also writes the machine changelog. The index is a requirement ofindexed, not ofcore; a hand-authored core context layer without one still conforms. --mode solo(a team of one) also seeds identity and writing-style starters, maps the practice category, routes identity and writing work in the boot profile, and points the onboarding brief at the owner interview (answer in text or with dropped files).- Refuses to overwrite an existing
leji.json, and refuses when the git tree has uncommitted changes; never overwrites individual files. - Reports the repository's dependency ecosystem (its package manager, from the manifest and lockfiles present) and how to declare the Leji CLI as a dev dependency there, so a clean install brings
leji; on a real terminal it offers to run that manager's own add command, and only on your explicit yes.--yes, a non-TTY and--jsonprint the command instead of running it, and leji never edits a manifest or lockfile itself. --dry-runprints the write plan without writing.- Also backs
npm create leji.
leji init [--dir <path>] [--yes] [--mode <solo|team>] [--level <core|indexed>] [--name <name>] [--agent <name>] [--no-agents] [--dry-run] [--json]--dir <path> | Target directory (default: the current directory). |
--yes, -y | Accept all defaults; run non-interactively. |
--mode <mode> | Working mode: solo (team of one; seeds identity + writing-style starters) or team (default). |
--level <level> | Conformance level to claim: core or indexed (default: core). |
--name <name> | Context layer name (default: derived from the directory). |
--agent <name> | Host to open in the context layer after the command (claude-code or codex). Selects the handoff host; the interactive flow may separately offer to register the MCP server or install the approval guard, each disclosed and consented to. |
--no-agents | Skip generating the portable AGENTS.md pointer (default: written when absent). |
--dry-run | Print the write plan and exit without creating any files. |
Ejemplos
leji init
leji init --dry-run
leji init --mode solo
leji init --agent claude-codeleji adopt
Brings Leji into a repository that already has docs and agent config.
- Reuses an existing
docs/root, migrates any vendor entrypoints (CLAUDE.md,AGENTS.md, and so on) into the context layer without modifying the originals, and seeds the scaffold. - Writes a generated index, so the adopted context layer is ready for the CI job
leji ciwrites. The index is a requirement ofindexed, not ofcore; a hand-authored core context layer without one still conforms. --wire-adaptersconverts those entrypoints to one-line redirects, after migrating their content.- When no
AGENTS.mdexists, writes a pointer-only one (the portable entrypoint many agent hosts read) redirecting to the boot profile;--no-agentsskips it, and an existing file is never touched unless--wire-adaptersis requested, which converts it with the other entrypoints. --mode solo(a team of one) also seeds identity and writing-style starters and points the onboarding brief at the owner interview; existing files are never overwritten.- Refuses when a
leji.jsonexists,--dry-runincluded: a repository that already has a context layer has nothing to adopt.--wire-adaptersis the exception, because an existing context layer is exactly what it finishes. Also refuses when the git tree has uncommitted changes, which--dry-runis exempt from because it writes nothing, and--wire-adaptersbecause the adopt run it finishes is what left the tree dirty. - Reports the repository's dependency ecosystem (its package manager, from the manifest and lockfiles present) and how to declare the Leji CLI as a dev dependency there, so a clean install brings
leji; on a real terminal it offers to run that manager's own add command, and only on your explicit yes.--yes, a non-TTY and--jsonprint the command instead of running it, and leji never edits a manifest or lockfile itself. - Also backs
npm create lejion a repository that already carries docs or an agent entrypoint.
leji adopt [--dir <path>] [--yes] [--mode <solo|team>] [--agent <name>] [--wire-adapters] [--no-agents] [--dry-run] [--json]--dir <path> | Target directory (default: the current directory). |
--yes, -y | Accept all defaults; run non-interactively. |
--mode <mode> | Working mode: solo (team of one; seeds identity + writing-style starters) or team (default). |
--agent <name> | Host to open in the context layer after the command (claude-code or codex). Selects the handoff host; the interactive flow may separately offer to register the MCP server or install the approval guard, each disclosed and consented to. |
--wire-adapters | Convert present vendor entrypoints to redirects (consented; content migrated first). |
--no-agents | Skip generating the portable AGENTS.md pointer (default: written when absent). |
--dry-run | Print the write plan and exit without changing anything. |
Ejemplos
leji adopt
leji adopt --dry-run
leji adopt --mode solo
leji adopt --wire-adaptersleji start
Detects an installed agent (or use --agent), launches it from the repository root, and points it at the boot profile so it loads the team's context first. The agent-facing counterpart to leji view. Several detected agents prompt for which; with none detected or in a non-interactive shell, it prints the command to run. Everything after a literal -- passes verbatim to the launched host binary, before the boot prompt. Host-specific flags ride with a pinned host: leji start --agent claude-code -- --chrome, never bare -- --chrome, which could hand the flag to whichever host gets picked.
- Before the agent starts, prints a Setup block for this clone: whether the Leji CLI this repository declares resolves here and meets the minimum version for the layer's spec line, whether the MCP server is registered for the selected host, whether the shared
.mcp.jsonis committed, and whether the pre-commit hook is installed. - Each row is personal or shared. Personal state (your host's MCP registration, this clone's
.githook) is offered on a real terminal and printed as an exact command otherwise; shared state (the dependency declaration, a committed.mcp.json, a hooks directory inside the working tree) is only ever reported, with the command a maintainer runs and commits. A gap never blocks entry: the agent still boots. --jsonmakes it report-only: one document withreadyand the same checks, no prompts and no launch, exit 0 even whenreadyis false. The launch-selection arguments are accepted and have no effect there; an--agentnaming no launchable host is still a usage error.
leji start [--agent <name>] [--root <dir>] [--json] [-- <host flags…>]--agent <name> | Launch a specific host (claude-code or codex) instead of auto-detecting. |
-- <host flags…> | Pass the remaining arguments verbatim to the launched host binary; pin --agent when they are host-specific. |
Ejemplos
leji start
leji start --agent codex
leji start --agent claude-code -- --chromeleji agent
Adds a second (or third) agent to a context layer that already has a leji.json.
- Writes a starter agent profile under the agent-profiles path and binds it in the manifest's agents map via an in-place edit that preserves the rest of the file.
- Never writes an agent-host entrypoint file. The portable
AGENTS.mdpointer is written byinitandadopt(unless--no-agents); single-vendor files likeCLAUDE.mdare only ever converted from an existing one byadopt --wire-adapters. --hostis optional: a host pins the profile to a specific external CLI; with none, it's a host-agnostic resident agent any host can run.- The role defaults to reviewer; pass
--rolefor a different one. - Binding the
defaultkey prints a note:agents.defaultselects a role profile, it does not load it, so instructions that must apply before every task belong in the boot profile rather than that profile. This note prints once, when the binding is written. - Idempotent: an existing profile or binding is left untouched. Requires an existing context layer.
leji agent --name <name> [--host <host>] [--role <role>] [--root <dir>] [--json]--name <name> | Name for the agent; also its profile id and agents-map key (kebab-case). |
--host <host> | Optional. Pin the profile to a host (claude-code, codex, copilot, gemini, cursor, windsurf; aliases ok); omit for a host-agnostic resident agent. |
--role <role> | Role the agent fills (default: reviewer). |
Ejemplos
leji agent --name porter --role porter
leji agent --host codex --name reviewer
leji agent --host claude-code --name thought-partner --role advisorleji detect
Best-effort, read-only detection of installed agent hosts (Claude Code, Codex, Copilot, Gemini, Cursor, Windsurf), ranked by signal strength: a runnable binary, a config file in the repository, or a user-level config directory. Writes nothing; use it to decide which host to open with leji start --agent <name> (launchable hosts today: claude-code and codex; other detected hosts enter the context layer through their vendor-file redirect). Also reports the repository's own dependency ecosystem: the package manager its manifest and lockfiles name, whether the Leji CLI is already declared as a dev dependency there, and the command that would declare it.
leji detect [--root <dir>] [--json]Ejemplos
leji detect
leji detect --jsonleji ci
Adds a CI job that runs leji validate and leji index --check on every change, so your context layer stays honest in CI (the same two gates the --hooks pre-commit runs locally). Idempotent: a Leji workflow already in place is left untouched.
- The provider is inferred from the
originremote (a github.com host selects GitHub, any gitlab host GitLab, an Azure DevOps host Azure Pipelines) and falls back to GitHub when the remote names none;--provideroverrides the inference, and CircleCI is never inferred. - GitHub: writes its own workflow at
.github/workflows/leji.yml. - GitLab: merges a managed block into
.gitlab-ci.yml, creating the file if it's absent. - CircleCI: writes
.circleci/config.ymlif absent; when a config already exists that leji did not generate, prints a snippet to add by hand instead of editing it. - Azure DevOps: writes
.azure-pipelines/leji.yml. ADO does not auto-discover it, so activation is manual: create a pipeline that points at the file (e.g.az pipelines create --yml-path .azure-pipelines/leji.yml), then add a build-validation branch policy onmainfor pull-request checks. This activation note prints once, on first creation. - Local hook (
--hooks): writes a managed pre-commit runningleji validateandleji index --checkthrough the same detected runner the CI job uses ('pnpm' 'exec' 'leji' validate, and so on), each argument single-quoted for the shell; a repository that does not declare the CLI runs thelejion PATH.core.hooksPathis detected, so a husky repo gets a managed block merged into.husky/pre-commitrather than a dead.git/hooksfile; an existing unmanaged hook is never touched, its snippet printed to add by hand. - Local-first, through the package manager this repository actually uses:
leji cidetects it from the manifest and lockfiles present, and when the repository DECLARES the Leji CLI and carries that manager's lock evidence the generated job installs its locked dependencies and runs the local binary (corepack enable && pnpm install --frozen-lockfilethenpnpm exec leji,uv sync --lockedthenuv run leji,go mod downloadthengo tool leji, and so on). Everything else takes a fallback that needs no manifest:npx @leji-org/leji@1for Node, several ecosystems and none;pip install 'leji>=1,<2'for Python;go install .../cmd/leji@latestfor Go. A bootstrap tool the job installs unpinned (poetry, pdm, pipenv, uv outside GitHub) is disclosed in one comment line. - Generated files carry the marker
# generated by leji ci (managed) v2. A re-run replaces a whole file (GitHub, CircleCI, Azure) only when its bytes are ones leji generated, in this release or an earlier one, so a manager change or an upgrade refreshes the job; a generated file you edited, and any file you wrote yourself, are left untouched with a snippet to add by hand. Editing the file, or deleting the marker, is the opt-out. GitLab owns only its marker-delimited block inside.gitlab-ci.yml.
leji ci [--provider <github|gitlab|circleci|azure>] [--hooks] [--root <dir>] [--json]--hooks | Write a managed local pre-commit running validate + index --check; core.hooksPath is detected, so a husky repo gets a managed block in .husky/pre-commit, and an existing unmanaged hook is left untouched with the snippet printed. |
--provider <name> | CI provider: github (default when no remote is recognizable), gitlab, circleci, or azure. Without this flag the provider is inferred from the origin remote. |
Ejemplos
leji ci
leji ci --provider gitlab
leji ci --provider azure
leji ci --hooksleji validate
Loads leji.json and checks it against the schemas and the lint rules: declared files exist, categories are populated, vendor entrypoints redirect to the boot profile, frontmatter is valid, every markdown link in a governed document resolves inside the layer, and (per the claimed conformance level) the index is current and the changelog is append-only. One of the two gates the generated CI runs, beside leji index --check. With --content it also runs a warning-only content lint (placeholder text, generic boot identity, thin categories) that never errors and never affects a conformance level.
leji validate [--content] [--federation <available|required> [--paths <a,b,...>]] [--root <dir>] [--json]--content | Also run the warning-only content lint (placeholders, generic identity, thin categories). |
--federation <mode> | Opt-in federation enforcement: available fails on any unhydrated or unverified mount; required fails only for mounts the --paths task scope routes to. Run leji mounts hydrate first; ordinary validate never fails on availability. |
--paths <a,b,...> | Task scope for --federation=required: comma-separated repository paths; the routing algorithm decides which mounts the task touches. |
Ejemplos
leji validate
leji validate --content
leji validate --root . --jsonleji index
Resolves the category index files to the documents they list and writes the context index to machine.indexPath. Ids are carried across a move when the move is unambiguous: a document whose path changes keeps its id if its content is unchanged and that content is unique in the context layer. A move that also edits the content, or that moves one of several byte-identical documents, cannot be carried and mints a fresh id. Declare a frontmatter id to make a document's id survive any move; that is the only unconditional guarantee. With --check it writes nothing and instead fails when the stored index no longer matches what the index files resolve to (a stale index is a hard failure).
leji index [--check] [--root <dir>] [--json]--check | Verify the stored index is current with the tree; write nothing. |
Ejemplos
leji index
leji index --checkleji status
Informational health report: markdown under the context root that no category index lists (reference content), index entries whose listed path does not resolve (dangling), and stored-index paths the index files no longer resolve to (stale). It also reports shadowed entries and skipped READMEs, which are informational only, and whether the context layer at HEAD would project completely if a host mounted it (the closure enumerated, the failure detail, or no commit to judge). Report-only by default; exit 0. With --strict, exits nonzero when an unindexed, dangling, stale, or pending document is flagged (shadowed and skipped-README entries never fail the run), for CI use.
leji status [--strict] [--root <dir>] [--json]--strict | Exit nonzero when an unindexed, dangling, stale, or pending document is flagged, for CI. |
Ejemplos
leji status
leji status --strict --jsonleji conformance
Runs the core, indexed, governed, and federated checklists. Machine-checkable items pass or fail; process items (review gate, CI, external consumers) are reported as manual. A machine failure at or below the claimed level is an error; evidence this run could not obtain reports unknown, which caps the verified level without refuting the claim. With --explain it also prints what it would take to reach the next level.
leji conformance [--explain] [--federation verify] [--root <dir>] [--json]--explain | Print actionable guidance for reaching the next conformance level. |
--federation verify | Run the networked pin-reachability probe against each mount's source (git ls-remote + witness-ref ancestry). Without it the pin-reachable item reports unknown, which never awards the federated level. |
Ejemplos
leji conformance
leji conformance --explain
leji conformance --jsonleji badge
Writes one SVG (default: leji-badge.svg at the repository root) and prints the markdown line that embeds it. Self-attested: the badge states the level leji conformance verified in this offline run, never more than the layer claims and possibly less, and a claim this run could not confirm is named beside it. Nothing is sent anywhere and no service or registry is involved; the bytes are constants, and the file is yours to commit. A run with an error finding, or one that verified no level at all, writes nothing and exits 1. An existing target is replaced only when its bytes are a badge this command wrote, which is how a level change regenerates; any other file is left untouched and the run refuses.
leji badge [--root <dir>] [--out <path>] [--json]--out <path> | Where to write the badge (default: leji-badge.svg). A repository-relative POSIX path over [A-Za-z0-9._/-] with no ".." segment, ending .svg, resolving inside the repository and never inside .leji/. |
Ejemplos
leji badge
leji badge --out docs/badge.svg
leji badge --jsonleji freshness
Lists documents whose freshness.reviewAfter horizon has passed (expired) or falls within the next 30 days (upcoming). Report-only by default; expired horizons are warnings.
leji freshness [--strict] [--root <dir>] [--json]--strict | Treat expired horizons as errors instead of warnings. |
Ejemplos
leji freshness
leji freshness --strict --jsonleji route
Read-only: given a task's scope (repository-relative paths it reads or changes, plus any categories and topics it names), print the slice of governed context that scope selects per the Task routing algorithm. Paths select the governed entries that contain them or are contained by them, and a path that is itself a governed document signals that document's category for decision and mount matching without expanding it; only a category the task explicitly names expands that category's intent documents and record candidates. Topics select sibling mounts and nothing else. Prints the expanded categories and the signalled ones, the governed documents (with each document's review horizon and whether it has expired), the record candidates a reader loads by judgment, the live decision records routed to the task, and the sibling mounts the supplied category and topic signals match. It computes the scope-dependent portion only: the boot profile's unconditional load set and the active agent profile's requiredRead are the caller's baseline and are never emitted here. Reads and reports context; it never executes a task.
- --paths and --categories take comma-separated values; either or both may be given.
- --topics is repeatable and each occurrence is one whole topic: values are never comma-split and never trimmed, all occurrences accumulate, exact duplicates count once, and an empty occurrence is an error.
- A topic matches a mount's declared topics by exact string equality, with no case conversion, normalization, locale, or fuzzy matching. A topic match selects the mount only: it never expands or signals a category, loads no document or record, and routes no decision.
- Document expiry is evaluated against --as-of (defaults to today); decisions carry no horizon.
- An empty path scope contributes no path matching and notes that path-scoped routing was not evaluated; categories named with --categories are still honored and still expand, and topics named with --topics are still matched. An empty whole scope, no paths, no categories, and no topics, routes only the org-wide unscoped live decisions.
leji route [--paths <a,b,...>] [--categories <a,b,...>] [--topics <topic>]... [--as-of <YYYY-MM-DD>] [--root <dir>] [--json]--paths <a,b,...> | Repository-relative paths the task reads or changes. Selects the entries they reach; signals a category without expanding it. |
--categories <a,b,...> | Content categories the task explicitly names. Only these expand a category's documents and record candidates. |
--topics <topic> | A topic the task explicitly names, matched against a mount's declared topics by exact equality. Repeatable, one whole topic per occurrence; selects mounts only. |
--as-of <YYYY-MM-DD> | Reference date for document expiry (default: today). |
Ejemplos
leji route --paths src/payments/billing.ts
leji route --categories domain,system --json
leji route --topics "product surface" --topics billing --json
leji route --paths docs/system/invariants.md --as-of 2026-06-27 --jsonleji changelog check
Validates the declared changelog against its schema and checks append-only discipline against the committed state of the file at HEAD: surviving entries are immutable, and entries may be removed only from the oldest end and only alongside a compaction entry. The comparison is against HEAD, so it catches an uncommitted rewrite (which is what the pre-commit hook uses it for); in a CI checkout the working tree is HEAD, so it does not by itself detect a rewrite that arrives already committed. Reviewing the diff covers that. Without git the discipline is unverifiable and reported as a warning.
leji changelog check [--strict] [--root <dir>] [--json]--strict | Treat an unverifiable append-only check (no git baseline) as an error. |
Ejemplos
leji changelog check
leji changelog check --strictleji changelog compact
Compacts the oldest end of the machine changelog, folding entries into a single compaction entry that records how many were folded and the id range removed.
- Selection:
--keep <n>folds every entry except the newest n;--before <date>folds entries dated before the given day. With both, an entry folds only if it satisfies both (the intersection). - At least one of
--keepor--beforeis required. - The folded set is always a contiguous run from the oldest end, so the result still satisfies the append-only discipline that
leji changelog checkenforces.
leji changelog compact [--keep <n>] [--before <YYYY-MM-DD>] [--root <dir>] [--json]--keep <n> | Keep the newest n entries; fold everything older. Must be a positive integer. |
--before <date> | Fold entries dated strictly before this YYYY-MM-DD day. |
Ejemplos
leji changelog compact --keep 50
leji changelog compact --before 2026-01-01
leji changelog compact --keep 50 --before 2026-01-01leji mounts hydrate
For each declared federation mount, resolves the pinned commit from a local object store (an explicit hint in .leji/mounts.local.json, the resolver-managed store, or a unique matching submodule's object database) and extracts the sibling's layer projection into the gitignored cache under .leji/mounts/. The projection is the deduplicated union of everything the sibling's own manifest makes readable at the pin: the root leji.json, the tree under its declared context root, its boot profile, its machine index and changelog files when present, its agent-profiles and decision-records trees when present, every agent profile its agents map binds, every category index file, and every governed path its pinned generated index lists, wherever those live. The failure boundary follows the same line: a referenced or schema-required file absent at the pin (the boot profile, a category index, a bound agent profile, an indexed governed path) fails the projection naming the declaring artifact and the missing path, while an absent directory or an absent machine artifact contributes nothing and fails nothing. Offline by default: --fetch establishes the resolver-managed store for every declared mount, including one a hint already resolves, fetching the pin from the declared source, retaining it under refs/leji-pin/v1/, and refreshing the managed witness under refs/leji-witness/v1/ (mounts status never fetches, so it refreshes no witness of its own). Best-effort: an unavailable mount is reported and skipped (degraded knowledge, never a failed run); the exit code reflects declaration, safety, or projection errors only.
leji mounts hydrate [--fetch] [--root <dir>] [--json]--fetch | Establish the resolver-managed store for every declared mount: fetch and retain the pin, and refresh the managed witness ref. |
Ejemplos
leji mounts hydrate
leji mounts hydrate --fetchleji mounts status
Read-only diagnostics for the declared federation mounts: whether the pinned projection is present in the cache, and an ancestry-aware pin report against the declared witness ref (trackingRef) computed from a reachable local object store: up-to-date, behind N, ahead, diverged, unrelated, or unknown, always naming the compared ref, the category of repository the comparison ran in (comparisonRepository: managed-store, hint, or submodule), whether the witness was the resolver's own ref or one it does not own (witnessProvenance), the observation time, and ancestry completeness. --check-integrity additionally re-derives the projection from the object store and compares it byte-for-byte (paths, modes, symlinks) against the cache. Never mutates and never touches the network.
leji mounts status [--check-integrity] [--root <dir>] [--json]--check-integrity | Verify the cached projection byte-for-byte against a reachable object store. |
Ejemplos
leji mounts status
leji mounts status --check-integrity --jsonleji mounts locate
Resolves a declared mount's hydrated projection through resolver state (never by inferring cache paths): the projection directory, the pin, whether the bytes are present, and whether they verified this run. Readers obtain the mounted content's location from this command; a projection that cannot be verified is reported as present but unverified, which includes the case where a verification prerequisite (a reachable object store, a resolvable pin, a writable temp dir) is unavailable. Exits 0 when the projection is present, 1 otherwise.
leji mounts locate <name> [--root <dir>] [--json]Ejemplos
leji mounts locate product-context
leji mounts locate product-context --jsonleji mounts update-pin
Rewrites one declared federation mount's pin in leji.json, after printing where that pin stands against its tracking ref. Offline by default: the target is the last successfully observed witness in a reachable object store (the resolver-managed store first, then a hint or a unique matching submodule holding both the pin and the ref), never a claim that the source was looked at during this run. --fetch observes the declared source and nothing else, in three acts: retain the current pin in the resolver-managed store, refresh the managed witness ref once, and retain the target once the comparison has passed; any of them failing refuses the move with a stable reason and leaves leji.json untouched, though objects and refs already fetched stay in the managed store. With no trackingRef declared the run refuses offline, and under --fetch resolves the source's advertised default branch for this run and reports it as the compared ref. The pin moves forward only: a target that is not a descendant of the current pin is refused unless BOTH --to <oid> and --allow-non-fast-forward are given, which is recorded as a warning and as override in --json; neither flag bypasses a repository whose ancestry is incomplete. --to takes a full 40- or 64-character lowercase hex commit id the comparison repository already holds. --dry-run computes and prints everything and writes no manifest byte; combined with --fetch it still performs that flag's store and network acts, so fetched objects and refs land in the managed store. Only the pin's own bytes are replaced, so field order, formatting and unmodeled keys survive. Hydration is a separate step: the run prints the leji mounts hydrate command that materializes the new pin, and the cache entry for the old pin is left in place for you to remove by hand. Exit 0 when the pin was updated, was already the target, or the run was a dry run; 1 when the move was refused with a stable reason; 2 for a usage error, or when the addressed pin cannot be located in leji.json.
leji mounts update-pin <name> [--to <oid>] [--allow-non-fast-forward] [--fetch] [--dry-run] [--root <dir>] [--json]--to <oid> | Move to this exact commit instead of the witness tip; it must already be held by the comparison repository. |
--allow-non-fast-forward | Permit a target that is not a descendant of the current pin. Valid only with --to, and always warned. |
--fetch | Observe the declared source: retain the current pin, refresh the managed witness ref, and retain the target. |
--dry-run | Show the comparison and what would change; write no manifest byte. With --fetch, the store and network acts still happen. |
Ejemplos
leji mounts update-pin product-context
leji mounts update-pin product-context --fetch --dry-run
leji mounts update-pin product-context --to 7d3f2a19c4e8b6a0d5f1c2e9b8a7f6d5c4b3a2e1leji viewer
Projects the context index into a browsable Docsify viewer: writes a frontmatter-stripping index.html, a deterministic _sidebar.md, and the vendored viewer assets into the context layer's contained viewer directory. Presentation is non-normative; this is the reference projection. Generates only; use leji viewer serve (or leji view) to preview it locally, and leji export (spelled leji viewer build inside the viewer subsystem) to write a self-contained static site.
leji viewer [--root <dir>] [--json]Ejemplos
leji viewer
leji viewer --jsonleji viewer serve
Generates the viewer, then serves it on localhost (a local preview, never hosting) at the web root. With --open it also opens your default browser at the viewer.
leji viewer serve [--port <n>] [--open] [--root <dir>] [--json]--open | Open the viewer in your default browser after serving. |
--port <n> | Port to serve on. Overrides the manifest viewer.port; default 5354 (LEJI on a phone keypad); 0 picks a free port. |
Ejemplos
leji viewer serve
leji viewer serve --open
leji viewer serve --port 0leji view
One-word shortcut to browse the context layer: generates the viewer, serves it on localhost, and opens your default browser. Equivalent to leji viewer serve --open.
leji view [--port <n>] [--root <dir>]--port <n> | Port to serve on. Overrides the manifest viewer.port; default 5354; 0 picks a free port. |
Ejemplos
leji view
leji view --port 0leji export
Regenerates the viewer chrome, then writes the static site from the layer on disk (default: .leji/dist/, kept out of git), complete on its own and servable as-is, including under a subpath. Everything the site needs travels with it: nothing is read from anywhere but the layer when it is written, and nothing is read from anywhere but the site's own files when it is opened. leji viewer build is the viewer subsystem's name for this same operation, beside leji viewer serve; both names are permanently supported and behave identically. A custom --out must resolve inside the repository, and never inside .leji/ except exactly .leji/dist. The exported index.html warns that a context layer is sensitive and belongs behind internal authentication, not in a public bucket.
leji export [--out <dir>] [--strict] [--root <dir>] [--json]--out <dir> | Output directory for the export (default: .leji/dist; must resolve inside the repository, and never inside .leji/ except exactly .leji/dist). |
--strict | Fail the export on any lint finding and leave the export destination untouched (the viewer chrome is regenerated before the lint runs). Without it, lint findings are reported as warnings and the export is still written. |
Ejemplos
leji export
leji export --out site
leji export --strict --jsonleji viewer build
The same operation as leji export, under the viewer subsystem's own name beside leji viewer serve: one code path, identical output, identical exits. Both names are permanently supported; leji export is the name the documentation leads with. Run leji export --help for the full description.
leji viewer build [--out <dir>] [--strict] [--root <dir>] [--json]--out <dir> | Output directory for the export (default: .leji/dist; must resolve inside the repository, and never inside .leji/ except exactly .leji/dist). |
--strict | Fail the export on any lint finding and leave the export destination untouched (the viewer chrome is regenerated before the lint runs). Without it, lint findings are reported as warnings and the export is still written. |
Ejemplos
leji viewer build
leji viewer build --out site