diff --git a/README.md b/README.md
index 0d4a5d9f61..7cdac83bf1 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[](https://github.com/DeusData/codebase-memory-mcp/releases/latest)
[](LICENSE)
[](https://github.com/DeusData/codebase-memory-mcp/actions/workflows/release.yml)
-[](#tests)
+[](#tests)
[](#mcp-tools)
[](https://github.com/DeusData/codebase-memory-mcp)
[](#hybrid-lsp)
@@ -26,16 +26,16 @@ The native C backend exposes **17 MCP tools**, parses [languages and file format
> **Local processing:** Source analysis and graph storage run on your machine. CBM Lens can optionally download a model for browser AI after you enable it; inference stays on the device. The installer writes agent configuration for the clients you select. See [Security](#security) for release verification and [SECURITY.md](SECURITY.md) for reporting issues.
-**See the graph with CBM Lens (open beta v0.0.1).** Folders become nested platforms, files and symbols become selectable blocks, and arrows show indexed relationships. The recording zooms into the map of this repository, selects `src/pipeline`, opens the area, selects `artifact.c` and opens its source. Height can show source size; hotspot gravity reflects static fan-in. [Still image](docs/images/lens-architecture.png).
+**See the graph with CBM Lens (open beta v0.0.1).** Folders become nested platforms, files and symbols become selectable blocks, and arrows show indexed relationships. The recording opens `src/foundation` in the map of this repository, selects `arena.c` and opens its source. Height can show source size; hotspot gravity reflects static fan-in. [Still image](docs/images/lens-architecture.png).
-
+
-**Galaxy.** Explore the code knowledge graph in 3D. The recording searches `cbm_pipeline_run`, follows its outgoing calls one layer further, switches to the hierarchy and shows the path to `cbm_store_check_integrity`. Edge pulses show relationship direction; they do not represent live execution. [Current still: two dependency layers around `cbm_max_file_bytes`](docs/images/lens-galaxy.jpg).
+**Galaxy.** Explore the code knowledge graph in 3D. The recording follows the outgoing relationships of `cbm_arena_alloc` one layer further, switches to the hierarchy and shows the two-hop call path to `cbm_alloc`. Edge pulses show relationship direction; they do not represent live execution. [Still: two dependency layers around `cbm_max_file_bytes`](docs/images/lens-galaxy.jpg).
-
+
**Explore.** Browse files in an IDE-style workspace, read syntax-highlighted source in Monaco, and keep the code graph alongside it. File impact shows what depends on the open file, and Code details shows the callers and calls of the symbol under the caret. Select code to [ask the local chat about it](#chat-with-your-codebase-locally).
@@ -53,7 +53,7 @@ The native C backend exposes **17 MCP tools**, parses [languages and file format
-These captures show CBM Lens Beta on 12–13 October 2026, using public source from this repository. See [capture details](docs/images/README.md) for each capture's build, indexed scope and recording setup.
+The high-resolution GIFs show CBM Lens Beta on 20 October 2026; the still images were captured on 12–13 October. All show public source from this repository. See [capture details](docs/images/README.md) for each capture's build, indexed scope and recording setup.
## Why codebase-memory-mcp
@@ -161,15 +161,15 @@ Thin frontends still write immediate startup and session-specific errors to thei
All active CBM processes must run the exact same version, executable build, coordination ABI, and canonical cache root. Equivalent `CBM_CACHE_DIR` aliases resolve to the same root; a genuinely different root is rejected while any CBM process is active. MCP servers, hooks, one-shot CLI commands, temporary index workers, and the daemon share a crash-safe OS admission barrier; starting an ordinary conflicting process fails before doing work and records an explicit conflict in `${CBM_CACHE_DIR}/logs/daemon-conflicts.ndjson`.
-The native `install`, `update`, and `uninstall` commands are the deliberate exception to that conflict rule. Download, verification, and private same-filesystem staging happen first so a bad candidate never disrupts active work. Activation then publishes account-wide maintenance intent, asks the daemon and every temporary local operation to cancel, and waits to a finite deadline for all coordinated CBM processes to exit. It holds the admission and lifetime barriers exclusively while changing the active binary, configuration, PATH, or indexes. New CBM work cannot enter during this window. Activation progress and results are recorded in `${CBM_CACHE_DIR}/logs/activation-events.ndjson`, and a successful command tells you to restart open coding-agent sessions so they launch the activated build.
+The native `install` and `uninstall` commands are the deliberate exception to that conflict rule. For installation, download, verification, and private same-filesystem staging finish before activation so a bad candidate never disrupts active work. The native `update` command prints the installer command that performs the update. Activation then publishes account-wide maintenance intent, asks the daemon and every temporary local operation to cancel, and waits to a finite deadline for all coordinated CBM processes to exit. It holds the admission and lifetime barriers exclusively while changing the active binary, configuration, PATH, or indexes. New CBM work cannot enter during this window. Activation progress and results are recorded in `${CBM_CACHE_DIR}/logs/activation-events.ndjson`, and a successful command tells you to restart open coding-agent sessions so they launch the activated build.
Package-manager setup (npm, PyPI, or Go) verifies and caches the native executable for that package. It does not replace the active native installation and therefore does not stop running CBM sessions. When that cached binary is executed, it still enters the same exact-build admission barrier. The shell and PowerShell installers invoke the verified candidate's native `install` command, so they do receive the full account-wide activation guarantee.
-The ordinary `cli` mode runs one command locally, but it is not disconnected from the daemon above: it connects to the shared coordination daemon (starting one if none is already running) for that same admission barrier plus per-project locks on graph mutations. Its connection is a `cli_session`: it never registers with the background watcher and never starts a UI, and it holds the admission lease only for the command's lifetime. If the command's own connection is what started the daemon, that daemon exits again once the command closes and no other session is attached; if a daemon was already running, the command simply joins and leaves it exactly as found. While the command is running, a temporary monitor separately lets activation cancel that operation and its supervised worker safely; the monitor exits with the command and never becomes a standing daemon. See [CLI Mode](#cli-mode) for details.
+The ordinary `cli` mode runs one command locally, but it is not disconnected from the daemon above: it connects to the shared coordination daemon (starting one if none is already running) for that same admission barrier plus per-project locks on graph mutations. Its connection is a `cli_session`: it does not register a project watcher or open a browser, and it holds the admission lease only for the command's lifetime. The shared daemon may serve Lens according to its UI configuration and available assets. If the command's own connection is what started the daemon, that daemon exits again once the command closes and no other session is attached; if a daemon was already running, the command simply joins and leaves it exactly as found. While the command is running, a temporary monitor separately lets activation cancel that operation and its supervised worker safely; the monitor exits with the command and never becomes a standing daemon. See [CLI Mode](#cli-mode) for details.
### CBM Lens Beta: code visualization and source navigation
-**CBM Lens is an optional visual companion to the MCP server, currently in open beta (v0.0.1).** Its browser interface is included in standard native releases and UI-enabled source builds. It builds on [CodeAtlasWeb](graph-ui/README.md) by [Bernhard Jackiewicz](https://github.com/BernhardJackiewicz) (design and tracking in #1964). Lens is served on loopback. Browser AI downloads its optional model only after you enable it; inference stays on-device. Each panel names where its facts come from, and what the index did not record is shown as a gap. Start the local server:
+**CBM Lens is an optional visual companion to the MCP server, currently in open beta (v0.0.1).** Standard native releases include its browser interface, so you can launch Lens directly after installation; UI-enabled source builds include it too. It builds on [CodeAtlasWeb](graph-ui/README.md) by [Bernhard Jackiewicz](https://github.com/BernhardJackiewicz) (design and tracking in #1964). Lens is served on loopback. Browser AI downloads its optional model only after you enable it; inference stays on-device. Each panel names where its facts come from, and what the index did not record is shown as a gap. Start the local server:
```bash
codebase-memory-mcp daemon start --open --port=9749
@@ -216,9 +216,9 @@ Open **Chat** with the panel button at the top right to ask about the code you a
Questions about callers and callees, such as "Who calls cbm_pipeline_run?", are answered from the loaded graph without the model, and the answer says so. When you select a symbol, the chat lists its indexed facts and the lines of its code, and the model adds one sentence; that sentence is left out when it claims something the source does not show. Text written by the model is labelled as such.
-The recording shows a question about callers answered from the indexed graph, next to the automatic explanation of the selected symbol. [Still image](docs/images/lens-chat.png).
+The recording asks who calls `arena_grow` and what it calls, with both answers listed directly from the indexed graph beside the selected symbol. [Still image of a model explanation and graph answer](docs/images/lens-chat.png).
-
+
The chat history is kept for 24 hours in this browser, per project. Each new message uses the source currently open in the reader; earlier source snapshots are not silently accumulated, and messages about another file or selection are not sent along. If a prompt is too long for the model, older messages are left out first; if it still does not fit, CBM Lens asks you to select less code instead of cutting the code. This chat explains the context you give it; it cannot edit files or run tools. Check its answers against the source. The small default model words things loosely, especially in languages other than English.
@@ -239,7 +239,7 @@ The Agents workspace and activity overlays are hidden in normal builds. To inclu
VITE_EXPERIMENTAL_AGENTS=true scripts/build.sh --with-ui
```
-Activity comes from explicitly configured tool hooks. The bundled adapter supports Claude Code PostToolUse; other clients need their own adapter. Recorded events go to the local daemon, and the reader must enable activity before the browser polls them. This does not automatically observe every agent. See the [frontend setup guide](graph-ui/README.md#die-agentenebene-was-live-arbeitende-agenten-auf-dem-graphen-zeigen).
+Activity comes from explicitly configured tool hooks. The bundled adapter supports Claude Code PostToolUse; other clients need their own adapter. Recorded events go to the local daemon, and the reader must enable activity before the browser polls them. This does not automatically observe every agent. See the [frontend setup guide](graph-ui/README.md#experimental-agent-activity).
@@ -274,7 +274,7 @@ bash "/install.sh"
```powershell
# Windows
-powershell -ExecutionPolicy Bypass -File "\install.ps1"
+powershell -File "\install.ps1"
```
The install script is placed next to the binary at install time, so the printed path resolves beside the executable. It is idempotent, so re-running it *is* the update: it stops the daemon, retires the running binary, installs the new one, and cleans up.
@@ -468,7 +468,7 @@ Published backend benchmarks on Apple M3 Pro. These are separate from the CBM Le
| Dead code detection | ~150ms | Full graph scan with degree filtering |
| Trace call path (depth=5) | <10ms | BFS traversal |
-**RAM-first pipeline**: All indexing runs in memory (LZ4 HC compressed read, in-memory SQLite, single dump at end). Memory is released back to the OS after indexing completes.
+**Memory-aware pipeline**: Indexing keeps hot data in memory and can spill extraction results to disk when needed. Memory is released back to the OS after indexing completes.
**More focused context, fewer tokens**: The project's [31-repository preprint](https://arxiv.org/html/2603.27277v1#S4.SS1) reports **10× lower token use** and **2.1× fewer tool calls** compared with file-by-file exploration. These March 2026 backend measurements cover the study's workloads and agent setup; the paper documents the full evaluation. An earlier [five-query comparison](https://github.com/DeusData/codebase-memory-mcp/blob/4ff6feeab639c4668da0f491930326ed5ec63093/README.md#performance) reported ~3,400 versus ~412,000 tokens for structural queries. The study's [system-performance measurements](https://arxiv.org/html/2603.27277v1#S4.SS3) include the Linux indexing and Cypher timings above.
@@ -476,7 +476,7 @@ Explore the [measurement guide](docs/MEASURING_SAVINGS.md) to evaluate quality,
## Troubleshooting & Diagnostics
-codebase-memory-mcp runs **100% locally and collects no telemetry**: your code, queries, environment, and usage never leave your machine. That privacy guarantee also means that when you hit something we can't reproduce on our side (a slow memory climb over hours, a performance regression, a leak that only appears after days of real use), **we have no data at all unless you choose to send it.** Here is how to capture it yourself.
+codebase-memory-mcp **indexes and queries locally and collects no telemetry**. When you hit something we can't reproduce on our side (a slow memory climb over hours, a performance regression, a leak that only appears after days of real use), **we have no diagnostic data unless you choose to send it.** Here is how to capture it yourself.
### Capture a diagnostics log
@@ -615,7 +615,7 @@ Counts on `main` at `4d9592b5`, where CBM Lens arrived. Native and Go counts use
| npm package wrapper | 24 tests | Counted in the source |
| Python package wrapper | 43 tests | Counted in the source |
-Run the test suite (9,388 tests across 189 suites):
+Run the native test suite:
```bash
scripts/test.sh # full: clean sanitizer build + all suites + guards
@@ -865,7 +865,7 @@ codebase-memory-mcp cli search_graph --project my-project --label Function --for
codebase-memory-mcp cli list_projects --format json --detail stats | jq '.projects[].name'
```
-JSON arguments can also be piped on stdin, for tools that take arguments. A tool whose input schema declares none; `list_projects`; never reads stdin, so it stays responsive when it inherits a pipe the caller never closes (the default for `child_process.spawn` and similar wrappers). Inline JSON remains accepted for backward compatibility but is deprecated in favor of flags, `--args-file`, or stdin.
+Tools requiring arguments accept JSON piped on stdin. Tools with only optional arguments, such as `list_projects`, accept flags, `--args-file`, or redirected JSON files without waiting on an inherited pipe. Inline JSON remains accepted for backward compatibility but is deprecated in favor of flags, `--args-file`, or stdin.
## MCP Tools
@@ -874,7 +874,7 @@ JSON arguments can also be piped on stdin, for tools that take arguments. A tool
| Tool | Description |
|------|-------------|
| `index_repository` | Index a repository into the graph. Auto-sync keeps it fresh only while it is the project of an open MCP session; repos indexed from the CLI or from another project's session need a re-run (`index_status` shows `watch`). Waits for the whole index by default; pass `async: true` to start it in the daemon and return at once, then poll with `status: true` (see below). |
-| `list_projects` | List all indexed projects with node/edge counts. |
+| `list_projects` | List indexed projects with paging; use `detail: "stats"` for node/edge counts and database sizes. |
| `delete_project` | Remove a project and all its graph data. |
| `index_status` | Check indexing status of a project. |
| `check_index_coverage` | Check whether exact paths or a scope are indexed and fresh. A clean result means no recorded gap, not proof of completeness. |
@@ -990,7 +990,7 @@ is preserved. See [Index resource limits](docs/INDEX_RESOURCE_LIMITS.md).
| `CBM_DOWNLOAD_URL` | *(GitHub releases)* | Override the download URL for updates. Used for testing or self-hosted deployments. |
| `CBM_LOG_LEVEL` | role-aware | Set the minimum log level. Thin MCP/CLI/hook frontends default to `warn`; the detached daemon and its supervised index workers default to `info` so lifecycle and liveness records remain available. Accepted values (case-insensitive): `debug`, `info`, `warn`, `error`, `none`; or their numeric equivalents `0` to `4`. A physical worker retains INFO liveness records even under a stricter override because its private log drives the supervisor's no-progress timeout. Frontend messages go to that session's stderr; detached daemon events go to `${CBM_CACHE_DIR}/logs/cbm-daemon.log`. Stdout is reserved for MCP JSON-RPC. |
| `CBM_WORKERS` | *(detected)* | Override the parallel-indexing worker count returned by `cbm_default_worker_count`. Useful inside containers where `sysconf(_SC_NPROCESSORS_ONLN)` reports host CPUs rather than the cgroup's effective quota. Range 1 to 256; invalid values are ignored with a warning. |
-| `CBM_MEM_BUDGET_MB` | *(detected)* | Override the in-memory graph budget with an explicit cap in MiB, taking precedence over the `ram_fraction × total_RAM` default. Useful on bare-metal hosts without a cgroup limit, or to pin a budget *below* the cgroup limit so headroom is left for sibling processes. Must be a positive integer; it is clamped to detected total RAM (logged as `mem.budget.clamped`), and non-numeric or non-positive values are ignored with a warning (`mem.budget.env.invalid`). |
+| `CBM_MEM_BUDGET_MB` | *(detected)* | Override the in-memory graph budget with an explicit cap in MiB, taking precedence over the derived default (`ram_fraction × total_RAM`, adjusted for available memory and daemon worker caps). Useful on bare-metal hosts without a cgroup limit, or to pin a budget *below* the cgroup limit so headroom is left for sibling processes. Must be a positive integer; it is clamped to detected total RAM (logged as `mem.budget.clamped`), and non-numeric or non-positive values are ignored with a warning (`mem.budget.env.invalid`). |
| `CBM_DUMP_VERIFY_MIN_RATIO` | `0.5` | After indexing, compare persisted SQLite node count to the in-memory dump count. When persisted nodes fall below this fraction of committed nodes (and committed > 50), `index_repository` returns `status:"degraded"` instead of silent `indexed`. Range 0 to 1; set `0` to disable. Invalid values are ignored with a warning. |
Environment used by daemon-owned components (such as diagnostics, daemon logging, and process-wide indexing resource limits) is captured from the first daemon-backed session that starts the daemon. Later sessions join that process and cannot replace those values. To change them, close all daemon-backed sessions, update the relevant agent configurations consistently, and restart a session. `CBM_ALLOWED_ROOT` remains session-specific, a conflicting `CBM_CACHE_DIR` is rejected, and a one-shot CLI command is not exempt from the rule above: it connects to the coordination daemon like any other session, starting one if none is running. Its own environment becomes the captured daemon-owned environment only when its invocation is the one that starts the daemon; joining an already-running daemon, it inherits that daemon's already-captured values instead.
@@ -1020,9 +1020,9 @@ Need the full config-file reference? See [docs/CONFIGURATION.md](docs/CONFIGURAT
Each entry maps an extension (which **must** start with `.`) to a language name. Language names are matched **case-insensitively**. Accepted values (aliases in parentheses) are:
-`bash` (`sh`), `c`, `c++` (`cpp`), `c#` (`csharp`), `clojure`, `cmake`, `cobol`, `common lisp` (`commonlisp`, `lisp`), `css`, `cuda`, `dart`, `dockerfile`, `elixir`, `elm`, `emacs lisp` (`emacslisp`), `erlang`, `f#` (`fsharp`), `form`, `fortran`, `glsl`, `go`, `graphql`, `groovy`, `haskell`, `hcl` (`terraform`), `html`, `ini`, `java`, `javascript`, `json`, `julia`, `kotlin`, `lean`, `lua`, `magma`, `makefile`, `markdown`, `matlab`, `meson`, `nix`, `objective-c` (`objc`), `ocaml`, `perl`, `php`, `protobuf`, `python`, `r`, `ruby`, `rust`, `scala`, `scss`, `sql`, `svelte`, `swift`, `toml`, `tsx`, `typescript`, `verilog`, `vimscript`, `vue`, `wolfram`, `xml`, `yaml`, `zig`.
+`arkts`, `asciidoc`, `bash` (`sh`), `c`, `c++` (`cpp`), `c#` (`csharp`), `chialisp`, `clojure`, `cmake`, `cobol`, `common lisp` (`commonlisp`, `lisp`), `css`, `cuda`, `dart`, `diagram`, `dockerfile`, `elixir`, `elm`, `emacs lisp` (`emacslisp`), `erlang`, `f#` (`fsharp`), `form`, `fortran`, `glsl`, `go`, `graphql`, `groovy`, `haskell`, `hcl` (`terraform`), `html`, `ini`, `java`, `javascript`, `jinja2` (`jinja`), `json`, `julia`, `kotlin`, `lean`, `lua`, `magma`, `makefile`, `markdown`, `matlab`, `meson`, `mojo`, `nix`, `objective-c` (`objc`), `ocaml`, `openapi`, `pdf`, `perl`, `php`, `plsql`, `protobuf`, `python`, `r`, `ruby`, `rust`, `scala`, `scss`, `sql`, `svelte`, `swift`, `toml`, `tsx`, `typescript`, `verilog`, `vimscript`, `vue`, `wolfram`, `xml`, `yaml`, `zig`.
-Project config overrides global for conflicting extensions. An entry whose language name is unknown, or whose extension does not start with `.`, is skipped and a warning is logged to stderr (shown at the default `info` log level). Missing config files are ignored.
+Project config overrides global for conflicting extensions. An entry whose language name is unknown, or whose extension does not start with `.`, is skipped and logged as a warning. Missing config files are ignored.
## Persistence
@@ -1112,7 +1112,7 @@ Every release is verified through a multi-layer pipeline before publication:
- **Sigstore cosign**: keyless signatures on all artifacts; bundles included in every release
- **SHA-256 checksums**: `checksums.txt` published with every release; verified by both install scripts before extraction
- **CodeQL SAST**: blocks release pipeline if any open alerts remain
-- **No language-runtime dependency chain**: the native backend uses libraries vendored at compile time, and the frontend is embedded by the UI build
+- **No language-runtime dependency chain**: the native backend needs no language-runtime environment; UI builds embed the frontend
### VirusTotal release scans
diff --git a/docs/images/README.md b/docs/images/README.md
index 1c1ecc96db..89f811c375 100644
--- a/docs/images/README.md
+++ b/docs/images/README.md
@@ -1,49 +1,53 @@
# CBM Lens Beta README captures
-These are screenshots and browser recordings of the application, captured on 12–13 October 2026. The application data and text were not retouched. Bernhard Jackiewicz captured the recordings and PNG stills on 12 October. The Explorer and Galaxy JPEG stills were refreshed on 13 October. One addition is drawn on top of the recordings: a small mouse pointer and click ring, because a headless browser shows no pointer of its own.
+These are screenshots and browser recordings of the real application using public source from this repository. The application data and text were not retouched. The GIFs were refreshed on 20 October 2026; the still images preserve the earlier captures from 12–13 October.
-## Original captures: 12 October
+## High-resolution recordings: 20 October
- Repository: [DeusData/codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)
-- Branch: `main`, after [PR #2068](https://github.com/DeusData/codebase-memory-mcp/pull/2068) brought CBM Lens Beta in
-- Commit: `4d9592b5`
-- Build: `scripts/build.sh --with-ui`
-- Browser: headless Chromium (Playwright) on macOS, English locale, viewport 1440 × 900, device scale factor 1
-- Agents: standard build, experimental agent activity disabled
+- Source commit: `4cf44147e639ae070ee44d9230244bfb9d9676e0`
+- Build: `make -f Makefile.cbm cbm-with-ui`, with the standard frontend and experimental agent activity disabled
+- Capture: built-in browser screenshots on macOS, English locale, native viewport **1600 × 1000**, **12 frames per second**
+- Encoding: JPEG screenshot frames converted to GIF with one 256-color palette per recording, no dithering, infinite looping; no upscaling, sharpening or pointer overlays
-The `v0.0.1` label in the application is the frontend package version. It is not the backend release version.
+The `v0.0.1` label is the frontend package version, not the backend release version. Standard native releases include Lens; using a source build for these recordings is a capture-provenance detail, not an installation requirement.
-### Data shown
+### Data and interaction
-The project `codebase-memory-mcp` is an export of the same public commit (`git archive`), indexed in `full` mode into an isolated local cache. No private repository was used. Because the export has no `.git` folder, Explore reports "Git unavailable" in its file impact line.
+The project `codebase-memory-mcp` is a clean `git archive` export of the source commit, indexed in `full` mode into an isolated local cache. No private repository was used. Because the export has no `.git` folder, the interface reports "Git unavailable" where applicable.
-The index reported 75,037 nodes and 361,349 edges. These are properties of this source scope, not a benchmark. The interface keeps its coverage and display-limit notices.
+The index reported 81,190 nodes and 411,072 edges. These counts describe this source scope, not a benchmark or proof of complete repository coverage. The interface retains its coverage and display-limit notices. The clips join recorded interaction segments with pauses shortened between them; their displayed application states and answers are unchanged. Directional pulses represent indexed relationships, not observed execution.
-## Refreshed stills: 13 October
+| Recording | Duration | What it shows |
+|-----------|----------|---------------|
+| [lens-overview.gif](lens-overview.gif) | 12.5 seconds | Architecture overview, opening `src/foundation`, browsing its files, selecting `arena.c` and reading its source beside the map. |
+| [lens-galaxy.gif](lens-galaxy.gif) | 12 seconds | Expanding outgoing relationships around `cbm_arena_alloc`, switching to the hierarchy and tracing the two-hop call path `cbm_arena_alloc → arena_grow → cbm_alloc`. |
+| [lens-chat.gif](lens-chat.gif) | 11.5 seconds | `arena_grow` selected in Galaxy, with caller and callee questions answered directly from the indexed graph. |
-`lens-explore.jpg` and `lens-galaxy.jpg` are unedited browser captures at 1280 × 720 from the locally served CBM Lens Beta UI. The running binary reports `dev`; its exact build commit is unavailable, so these captures do not certify an exact source revision. The local project is named `cbm-triage-main-20260919`; the screenshots show public CBM source and indexed relationships.
+All three GIFs are 1600 × 1000. Their frames and playback duration were decoded and checked after export. README and website use these same files.
+
+### Local chat check
+
+The optional Qwen2.5 Coder 0.5B model was downloaded and loaded through the application's own setup. Automatic explanations were disabled for this recording. Both displayed answers are deterministic graph answers, labelled "Listed from the indexed graph; not generated by the model." The clip shows one incoming `CALLS` relationship from `cbm_arena_alloc` and two outgoing `CALLS` relationships to `cbm_alloc` and `cbm_free`, alongside the other indexed relationship types. It does not demonstrate model-generated prose.
-- **Explore:** `src/foundation/limits.c`, its compact file impact summary and direct dependencies (24 nodes, 26 edges). The UI's freshness, sampling and coverage caveats remain visible.
-- **Galaxy:** `cbm_max_file_bytes`, both directions, all edge types, two layers (160 nodes, 218 edges).
+## Original still images: 12 October
-These counts describe the displayed index snapshot, not a benchmark or proof of complete repository coverage. The original recordings and other stills are unchanged.
+Bernhard Jackiewicz captured the PNG stills on 12 October 2026, from commit `4d9592b5` on `main` after [PR #2068](https://github.com/DeusData/codebase-memory-mcp/pull/2068). The build used `scripts/build.sh --with-ui`; headless Chromium on macOS used English locale, a 1440 × 900 viewport and device scale factor 1. Experimental agent activity was disabled.
-## Media
+The indexed project was a public `git archive` export of that commit in `full` mode, with 75,037 nodes and 361,349 edges. The PNG stills are 1440 × 900, except the chat still at 1440 × 1200 so the explanation and answer fit together. These are historical application views, also used as reduced-motion alternatives on the website; they are not extracted from the new GIFs.
-| File | What it shows |
-|------|---------------|
-| [lens-overview.gif](lens-overview.gif) | Architecture overview of the repository: zoom and a small orbit, selecting `src/pipeline`, opening that area, selecting `artifact.c` and opening its source. |
-| [lens-architecture.png](lens-architecture.png) | Still image of the whole repository on the architecture map. |
-| [lens-galaxy.gif](lens-galaxy.gif) | Galaxy: searching `cbm_pipeline_run`, following its outgoing calls one layer further, the hierarchy view and the path to `cbm_store_check_integrity`. |
-| [lens-galaxy.jpg](lens-galaxy.jpg) | Two dependency layers around `cbm_max_file_bytes`, with direction and edge-type controls. |
-| [lens-explore.jpg](lens-explore.jpg) | `src/foundation/limits.c` in the reader with its file impact summary, file tree and direct graph dependencies. |
-| [lens-chat.gif](lens-chat.gif) | The chat with the local Qwen2.5 Coder 0.5B model: the explanation of `cbm_pipeline_pass_doclinks` and "Who calls cbm_pipeline_pass_doclinks?" answered from the graph. |
-| [lens-chat.png](lens-chat.png) | Still image of the same explanation and listed answer. |
-| [lens-system-structure.png](lens-system-structure.png) | Component groups and their dependencies in System structure, `src` selected. |
+| Still | What it shows |
+|-------|---------------|
+| [lens-architecture.png](lens-architecture.png) | The whole repository on the architecture map. |
+| [lens-chat.png](lens-chat.png) | A local model explanation of `cbm_pipeline_pass_doclinks` and a caller answer listed from the graph. |
+| [lens-system-structure.png](lens-system-structure.png) | Component groups and their dependencies in System structure, with `src` selected. |
| [lens-behavior.png](lens-behavior.png) | Possible direct calls of `compileCards`, with its declaration. |
-The recordings were captured as browser video, then encoded as GIF at 960 pixels wide and 10 frames per second with a palette per recording. While a search is typed, the Galaxy briefly shows "No matching indexed nodes." until the index search answers; those frames (under one second) were cut. The original PNG stills are 1440 × 900, the chat still 1440 × 1200 so that the explanation and the answer fit together. The refreshed JPEG stills are 1280 × 720. Directional pulses represent indexed relationships, not observed execution.
+## Refreshed still images: 13 October
+
+`lens-explore.jpg` and `lens-galaxy.jpg` are unedited browser captures at 1280 × 720 from the locally served CBM Lens Beta UI. The running binary reports `dev`; its exact build commit is unavailable, so these captures do not certify an exact source revision. The local project is named `cbm-triage-main-20260919`; the screenshots show public CBM source and indexed relationships.
-## Local chat check
+- **[Explore](lens-explore.jpg):** `src/foundation/limits.c`, its compact file impact summary and direct dependencies (24 nodes, 26 edges). The UI's freshness, sampling and coverage notices remain visible.
+- **[Galaxy](lens-galaxy.jpg):** `cbm_max_file_bytes`, both directions, all edge types, two layers (160 nodes, 218 edges).
-The chat recording uses the actual browser model, downloaded through the application's own setup. The explanation lists the indexed facts and the declaration of the selected function; the one sentence after them was written by the model and is labelled as such. The caller answer is listed from the indexed graph without the model.
+These counts describe the displayed index snapshot, not a benchmark or proof of complete repository coverage.
diff --git a/docs/images/lens-chat.gif b/docs/images/lens-chat.gif
index 1eaaecb86c..946f777e7f 100644
Binary files a/docs/images/lens-chat.gif and b/docs/images/lens-chat.gif differ
diff --git a/docs/images/lens-galaxy.gif b/docs/images/lens-galaxy.gif
index 1aa8899e32..3c906eea12 100644
Binary files a/docs/images/lens-galaxy.gif and b/docs/images/lens-galaxy.gif differ
diff --git a/docs/images/lens-overview.gif b/docs/images/lens-overview.gif
index 7338335539..058397d1e3 100644
Binary files a/docs/images/lens-overview.gif and b/docs/images/lens-overview.gif differ
diff --git a/docs/index.html b/docs/index.html
index 1718b3dd27..fac7e3b5b1 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -357,7 +357,7 @@
Understand the whole repository.
CBM LENS · OPEN BETA v0.0.1codebase-memory-mcp / architectureLOCAL WORKSPACE
-
+ See the MCP server’s graph through CBM Lens, its optional visual companion. Open beta v0.0.1, captured in October 2026. Capture details ↗
@@ -453,9 +453,9 @@
Understand the whole repository.
- Follow the connectionsSearch, expand connections and follow paths.
+ Follow the connectionsExpand relationships and trace a call path.Inspect system structureSee source groups and dependencies.
- Ask about selected codeOptional browser AI, with on-device inference.
+ Ask about selected codeCaller and callee answers from the indexed graph.
Lens is served on loopback. Browser AI downloads its optional model after you enable it. Its explanations should be checked against the displayed source.