{
  "markdown": "# Nexus\n\nNexus decouples the **Machine Implementation** (code) from the **Human\nIntent** (narrative) by maintaining a synchronized, human-readable shadow\nbranch alongside your code. Instead of reviewing a code diff, a reviewer\nreads a short, jargon-free explanation of what changed and why.\n\n- **`main`** — your code, unchanged. Always the source of truth.\n- **`explainer`** — an orphan branch mirroring `main`'s file structure, one\n  Markdown file per code file, narrating intent instead of syntax.\n\nThis repo is the standalone `nexus` CLI: it manages the `explainer` branch\n(`nexus init`, `nexus show`, `nexus map`, ...) and ships the `narrate`\nskill that a coding agent uses to actually write the narrative. It does not\ndepend on any other project — a plain `git` repository is all it needs.\n\n## Install\n\n```bash\ngo install github.com/sunprema/nexus-cli/cmd/nexus@latest\n```\n\nThis installs `nexus` into `$(go env GOPATH)/bin` (`~/go/bin` by default). Make\nsure that directory is on your `PATH` — add this to your shell profile if\n`nexus` isn't found afterward:\n\n```bash\nexport PATH=\"$(go env GOPATH)/bin:$PATH\"\n```\n\nVerify the install:\n\n```bash\nnexus --version   # or: nexus -v\n```\n\nOr build from source:\n\n```bash\ngit clone https://github.com/sunprema/nexus-cli.git\ncd nexus-cli\ngo build -o nexus ./cmd/nexus\n```\n\nPrebuilt binaries for macOS/Linux/Windows are attached to each\n[GitHub release](https://github.com/sunprema/nexus-cli/releases).\n\n## Usage\n\n```bash\nnexus init      # create the 'explainer' branch, .nexus/ config, and the post-commit hook\nnexus sync       # list commits queued for narration\nnexus show <path>   # print a file's current explainer entry\nnexus map        # index every narrated file and guided tour\nnexus diff <path>   # diff a file's last two narrated versions\nnexus check       # report files still flagged with a desync marker\nnexus tour <slug>   # print a guided tour's stops\nnexus history [path] # incidents, decisions, and reverts recorded against a path\nnexus speak <path>  # read a file's explainer entry aloud (--summary for the gist)\n```\n\n`nexus init` installs a post-commit git hook that queues every commit for\nnarration in `.nexus/pending.json` — cheaply, with no LLM call. Narration\nitself happens later, via the `narrate` skill running inside your coding\nagent (see below): it drains that queue, writes the explainer entries, and\nverifies each one against the code with an independent pass before\ncommitting.\n\nRun `nexus <command> --help` for full flag and argument details.\n\n## Settings\n\n`nexus init` writes `.nexus/settings.json`, the repo's Nexus configuration:\n\n```json\n{\n  \"source_of_truth\": \"main\",\n  \"explainer_branch\": \"explainer\",\n  \"verifier_model\": \"\"\n}\n```\n\n- **`source_of_truth`** — always `\"main\"`. Recorded, not configurable: a\n  code/explainer disagreement is always resolved in favor of the code (see\n  [Desync markers](#desync-markers)), never by picking a different\n  authority per repo.\n- **`explainer_branch`** — always `\"explainer\"`. Recorded, not\n  configurable: the rest of Nexus's tooling assumes this name, so nothing\n  is gained by letting it drift per repo.\n- **`verifier_model`** — the only field meant to be edited. Names the model\n  the `narrate` skill's independent Verifier subagent should run on (see\n  [Desync markers](#desync-markers)). Empty (the default `nexus init`\n  writes) means \"use the coding agent's normal subagent model.\" Set it to\n  pin verification to a specific model, e.g.:\n\n  ```json\n  \"verifier_model\": \"claude-opus-5\"\n  ```\n\n`nexus init` only writes this file if it doesn't already exist — it never\noverwrites or adds fields to a `settings.json` from a previous run, so\nedit it by hand.\n\n## MCP server\n\n`nexus mcp` runs a read-only [Model Context Protocol](https://modelcontextprotocol.io)\nserver over stdio, exposing the explainer branch as five tools instead of\nrequiring an agent to shell out to `nexus` and parse its output:\n\n- **`nexus_explainer`** — a code file's current explainer entry (same data\n  as `nexus show <path> --json`). An agent should call this *before*\n  reading or editing a file: the explainer often already captures intent\n  and edge cases that would otherwise have to be re-derived from the code.\n- **`nexus_map`** — the whole-branch index of every narrated file and\n  guided tour (same data as `nexus map --json`). Meant to be called first\n  when orienting in an unfamiliar repo — the cheapest way to learn what's\n  there before reading any code.\n- **`nexus_tour`** — one guided tour's ordered stops (same data as\n  `nexus tour <slug> --json`).\n- **`nexus_history`** — the incident/decision/revert records anchored to\n  a file or directory (same data as `nexus history [path] --json`). An\n  agent should call this before changing an area it doesn't know well —\n  a record often says exactly what not to change and why. See\n  [History records](#history-records). `nexus_explainer` already embeds\n  the same records for a single file.\n- **`nexus_speak`** — reads an entry (or any text the agent composes)\n  aloud through the machine's own text-to-speech, for \"read me the\n  summary of auth.py\" (same engine as `nexus speak`; see\n  [Reading aloud](#reading-aloud)). The one tool here with a side effect:\n  it returns as soon as audio starts, and `stop: true` interrupts it.\n\nAll five share the exact same lookup code the CLI commands use, so an MCP\nclient and a shell script can never see different results. Use MCP over\nshelling out when the host doesn't want to spawn a subprocess per lookup,\nor when it can hold a longer-lived server connection across a whole\nsession instead of one CLI invocation per question.\n\n### Configuring an agent to use it\n\nAny MCP host that can launch a stdio server works. The general shape:\n\n```json\n{\n  \"mcpServers\": {\n    \"nexus\": {\n      \"command\": \"nexus\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\n- **Claude Code**: `claude mcp add nexus -- nexus mcp` (add `-s project` to\n  commit it to the repo's `.mcp.json` for the whole team, instead of just\n  your own local config).\n- **Cursor / other JSON-config hosts**: add the block above to the host's\n  MCP config file (e.g. Cursor's `.cursor/mcp.json`).\n- **Any other MCP-host agent**: point it at the `nexus mcp` command the\n  same way — it only needs to know how to launch a stdio server.\n\n`nexus` must be on `PATH` for the host to find it. Verify the server\nresponds by asking the agent to call `nexus_map`.\n\n## Reading aloud\n\n`nexus speak` reads an explainer entry through the operating system's own\ntext-to-speech engine — macOS `say`, Linux `espeak-ng`/`espeak`/`spd-say`,\nWindows `System.Speech` — so it works from a bare terminal and from any\nMCP-host agent (via `nexus_speak`) with nothing else installed. No browser,\nno editor extension.\n\n```bash\nnexus speak src/auth.py             # read the whole narrative\nnexus speak src/auth.py --summary   # just the one-sentence gist\nnexus speak --text \"Anything else\"  # arbitrary text; \"-\" reads stdin\nnexus speak src/auth.py --print     # show what would be read, silently\nnexus speak --stop                  # interrupt whatever is playing\n```\n\nMarkdown syntax, code fences and mermaid diagrams are stripped first so the\naudio is prose rather than punctuation; a desynced entry is announced as\n\"this explainer may be out of date with the code\" instead of reading the\nmarker line. Only one thing speaks at a time — a new `speak` replaces the\none in progress.\n\nPick a voice with `--voice <name>`, or set `NEXUS_SPEAK_VOICE` once for your\nmachine (a personal preference, so it's an environment variable rather than\na field in the committed `settings.json`). The names are whatever your\nengine accepts — `say -v ?` lists them on macOS.\n\nWith an agent, just ask: \"read me the summary of `src/auth.py`\", \"read me\nthe request-lifecycle tour\", \"stop reading\". The agent fetches the text via\nthe other tools where it needs to and hands it to `nexus_speak`.\n\n## The `narrate` skill\n\nNarration requires an LLM, so it isn't built into the `nexus` binary — it's\na skill (`skills/narrate/SKILL.md`) that a coding agent runs. This repo\ndoubles as a plugin source for the agents that support skill/plugin\ndiscovery:\n\n- **Claude Code**: `/plugin marketplace add sunprema/nexus-cli`, then\n  `/plugin install nexus`.\n- **Codex / Cursor**: point their plugin config at this repo\n  (`.codex-plugin/plugin.json`, `.cursor-plugin/plugin.json`).\n- **OpenCode**: see [`.opencode/INSTALL.md`](.opencode/INSTALL.md).\n- **Gemini**: `gemini-extension.json` at the repo root.\n\nOnce installed, ask your agent to \"narrate this change\" after making a\ncommit, or let it pick up `.nexus/pending.json` on its own.\n\nThe prompt/style the skill writes in is editable per-repo at\n`.nexus/skills/narrator-prompt.md` (created by `nexus init`) — tune tone,\nvocabulary, or conventions without a CLI release.\n\n### Explainer frontmatter\n\nEvery explainer file starts with a small YAML block, the same idea as a\n`SKILL.md`'s `name`/`description` frontmatter — a cheap way to know what a\nfile is about before reading the whole narrative:\n\n```yaml\n---\npath: src/auth.py\nsummary: One sentence — the gist, for scanning across many files fast.\nsource_commit: <the code commit this narrative describes>\ndesynced: false\n---\n```\n\n- **`summary`** is deliberately shorter than the body's own \"What this\n  does\" section — it's built for skimming many files quickly (`nexus map`,\n  `nexus_map` over MCP), not for understanding one file deeply.\n- **`source_commit`** ties the narrative to the exact code commit it\n  describes.\n- **`desynced`** is the machine-readable version of the desync marker\n  below — `nexus check`/`nexus show` trust this field over scanning prose\n  for the marker text whenever it's present, since prose that merely\n  *mentions* the marker text can't be confused with an actual one.\n\nA file with no frontmatter (narrated before this feature existed) still\nworks fine — commands fall back to scanning the file body directly.\n\n### Desync markers\n\nEvery time the `narrate` skill writes an explainer entry, a second,\nindependent LLM pass (the \"Verifier\") checks the drafted narrative against\nthe actual code. If they disagree — e.g. the code retries 3 times but the\nnarrative says 5 — the skill doesn't block or reject the commit; `main`\nstays authoritative no matter what. Instead it marks that one explainer\nentry as desynced:\n\n- an inline `> [!WARNING]` **Nexus desync** callout in the Markdown body,\n  so it's visible to a human just reading the file on GitHub or in an\n  editor preview, and\n- `desynced: true` in the file's frontmatter (see above), so a tool can\n  check status without scanning prose.\n\nA marker just means \"treat this explainer entry as stale/unreliable until\nit's re-narrated\" — it's informational, not blocking. It clears itself the\nnext time that file is narrated: the Verifier re-checks from scratch, and\nthe marker is only written again if the disagreement still exists. There's\nno separate `nexus resolve` command — fix the code, or hand-edit the\nnarrative, and let the next narration pass confirm agreement.\n\n`nexus check` scans the `explainer` branch and reports every file still\ncarrying an unresolved marker, so a desync doesn't require reading every\nfile to notice. `nexus show <path>` and `nexus_explainer` (MCP) surface the\nsame `desynced` status for one file at a time.\n\nBy default the Verifier runs on whatever model drafted the narrative; set\n`verifier_model` in [Settings](#settings) to pin it to a different model\ninstead.\n\n### History records\n\nAn explainer entry describes what a file *is* now. It has no memory of\nwhat *happened* to it: after a revert it reads as if nothing changed, and\n\"we tried X, it broke production, we went back\" survives only in\n`git log`. History records hold that — tiny, path-anchored notes under\n`.nexus/history/` on the explainer branch, one per event:\n\n```yaml\n---\nkind: incident          # incident | decision | revert\ntitle: \"Partial refunds timed out under load\"\ndate: 2026-03-04\nsource_commit: <the code commit>\npaths:\n  - src/payments\nref: \"INC-4471\"         # a pointer to the team's ticket/ADR — never its contents\nlink: \"https://…\"       # optional\n---\nThe ledger check retried 5 times and each retry re-locked the row. Retries\nwere cut to 3 with backoff; don't raise them again without load-testing.\n```\n\nThe `narrate` skill writes one only when the commit itself carries a\nsignal, so nothing new has to be remembered:\n\n- an `Incident: INC-4471` or `Decision: ADR-0006` git trailer in the\n  commit message (plus an optional `Link: <url>` trailer),\n- a revert (`git revert`'s own message shape), or\n- a commit that adds or changes a file under an `adr/` directory.\n\nIt never guesses from words like \"fix\" in a subject — a false record costs\nmore trust than a missed one — and every record must be anchored to at\nleast one path; that's the line between \"context for the code\" and \"a\nwiki in git\", and Nexus stays on the code side of it.\n\nRecords deliberately stay out of the explainer file, so the narrative\nreads clean. They surface where a reader is already looking:\n\n```bash\nnexus history                     # every record, newest first\nnexus history src/payments        # records for a directory (or a file, or a parent/child of one)\nnexus show src/payments/refund.go --json   # 'history' field carries the same records\n```\n\nand over MCP via `nexus_history`, or embedded in `nexus_explainer`'s\nresult — so an agent about to edit a file sees what has gone wrong there\nbefore, without a second lookup.\n\n## Editor integration\n\n[nexus-vscode](https://github.com/sunprema/nexus-vscode) is a VS Code\nextension for reading explainer entries without leaving the editor: a\nCodeLens on every file shows its narration status, and clicking it opens\nthe explainer split-screen beside the code. It shells out to this CLI\n(`nexus show`/`diff`/`map`/`tour`), so it needs `nexus` on `PATH`.\n\n## Browser viewer\n\n`docs/` is a static single-page viewer for any repo's explainer branch —\npaste `owner/repo`, get every narrated file with its summary, the\nnarrative beside the code, and the guided tours. Nothing to install: it\nreads the branch listing from GitHub's tree API once and every file from\n`raw.githubusercontent.com`, so a Nexus repo can be shown to someone from\na link:\n\n```\nhttps://<owner>.github.io/nexus-cli/?repo=sunprema/nexus-cli&file=internal/cli/show.go&view=split\n```\n\nEvery piece of state (file, line, tour stop, layout) lives in the query\nstring, so any view is shareable. Public repos only — the page holds no\ntoken. See [docs/README.md](docs/README.md) for the parameters, the\nconventions it mirrors from this CLI, and how it is deployed\n(`.github/workflows/pages.yml`, Pages source set to \"GitHub Actions\").\n\n## Development\n\n```bash\ngo build ./...\ngo vet ./...\ngo test ./...\ngolangci-lint run ./...\n```\n\nCI (`.github/workflows/ci.yml`) runs the same checks on Linux, macOS, and\nWindows. Releases are built with [goreleaser](https://goreleaser.com) on\ntag push (`.github/workflows/release.yml`).\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n",
  "bytes": 15044,
  "sha": "df34d06440d8bc454abac121527877011f6bd9cd225f2564d2f5553ccb54fd65",
  "repo_slug": "sunprema/nexus-cli",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_sunprema_nexus_cli_21a2c7c6/readme"
}