This page documents the configuration and persisted runtime files used by codebase-memory-cli.
| Purpose | Path | Format | Notes |
|---|---|---|---|
| Global custom extension mapping | $XDG_CONFIG_HOME/codebase-memory-cli/config.json |
JSON | Falls back to ~/.config/codebase-memory-cli/config.json when XDG_CONFIG_HOME is unset. |
| Per-project custom extension mapping | {repo_root}/.codebase-memory.json |
JSON | Overrides conflicting global extra_extensions entries. |
| CLI-managed runtime settings | ${CBM_CACHE_DIR:-~/.cache/codebase-memory-cli}/_config.db |
SQLite | Written by codebase-memory-cli config set/reset. |
| UI settings | ${CBM_CACHE_DIR:-~/.cache/codebase-memory-cli}/config.json |
JSON | Stores ui_enabled and ui_port. |
| Daemon operation log | ${CBM_CACHE_DIR:-~/.cache/codebase-memory-cli}/logs/cbm-daemon.log |
Structured log | Durable daemon lifecycle, watcher/indexing, UI, resource, and error events. |
| Admission conflict log | ${CBM_CACHE_DIR:-~/.cache/codebase-memory-cli}/logs/daemon-conflicts.ndjson |
NDJSON | Exact-build, ABI, and canonical-cache conflicts. |
| Activation log | ${CBM_CACHE_DIR:-~/.cache/codebase-memory-cli}/logs/activation-events.ndjson |
NDJSON | Install/update/uninstall activation progress and outcomes. |
CBM resolves CBM_CACHE_DIR to a canonical per-account path before using any of these locations. The log directory and files are private to the account.
Two optional JSON files let you map additional file extensions to built-in languages.
Default path:
$XDG_CONFIG_HOME/codebase-memory-cli/config.json
Fallback when XDG_CONFIG_HOME is unset:
~/.config/codebase-memory-cli/config.json
Place this file in the repository root:
.codebase-memory.json
{
"extra_extensions": {
".blade.php": "php",
".mjs": "javascript",
".twig": "html"
}
}Notes:
- Extension keys must include the leading dot.
- Language names are case-insensitive.
- Unknown language names are skipped.
- Missing files are ignored.
- If the same extension appears in both files, the per-project file wins.
The config subcommand stores runtime settings in a small SQLite database:
${CBM_CACHE_DIR:-~/.cache/codebase-memory-cli}/_config.db
Inspect or change values with the CLI:
codebase-memory-cli config list
codebase-memory-cli config get auto_index
codebase-memory-cli config set auto_index true
codebase-memory-cli config set auto_index_limit 50000
codebase-memory-cli config set watcher_enabled false
codebase-memory-cli config set ignore_worktrees true
codebase-memory-cli config set doc_candidates false
codebase-memory-cli config reset doc_candidates
codebase-memory-cli config get install_hooksdoc_candidates is auto by default: unset, the index mode decides. A single
codebase-memory-cli index --doc-candidates true|false also overrides it for
that index only. With ignore_worktrees on, codebase-memory-cli index --index-worktree indexes a linked git worktree for that one call.
Current keys:
| Key | Default | Meaning |
|---|---|---|
auto_index |
false |
Permit the retained warm runtime to auto-index newly encountered projects. Canonical CLI usage can always index explicitly with codebase-memory-cli index. |
auto_index_limit |
50000 |
Maximum file count allowed for automatic indexing of a new project. |
auto_watch |
true |
Register an active project with the retained background watcher when a warm runtime/hook integration supplies project context. A daemon-started watcher can retain registered projects after the initiating session ends until daemon shutdown, project deletion/root disappearance, or this setting is disabled. The ordinary one-shot CLI does not require this. |
doc_candidates |
auto |
Score documentation sections against code to store doc<->code candidates (the possible targets of a section, and the sections that may describe a function or file, each with a judged probability). Unset (auto), the index mode decides: on for full indexes (the default mode), off for moderate and fast. Set true or false to choose for every mode; config reset doc_candidates returns to auto. The scoring grows with sections x functions: under a second up to ~100k functions, ~15 s at ~400k, ~3 minutes on the Linux kernel. Off stores no candidates and leaves the rest of the graph unchanged; on in fast mode stores candidates without adding fast's skipped SIMILAR_TO / SEMANTICALLY_RELATED edges. `codebase-memory-cli index --doc-candidates true |
ignore_worktrees |
false |
Skip linked git worktrees when indexing automatically, and refuse an explicit codebase-memory-cli index of one unless --index-worktree is passed. See ignore_worktrees. |
watch_non_git |
false |
Poll non-Git roots with the indexer discovery rules and an adaptive file-tree scan. Skipped paths, including .codebase-memory/, do not trigger indexing. The first poll after daemon startup reindexes once; later changes trigger one reindex. This walks the whole tree each poll and is read when the daemon starts. |
watcher_enabled |
true |
Master switch for the retained background watcher subsystem. Set false to stop its poll thread/project registration. Reindex manually with codebase-memory-cli index when disabled. |
index_max_files |
off |
Optional maximum number of accepted source files in one discovery run. |
index_max_source_mb |
off |
Optional maximum accepted source size in MiB in one discovery run. |
index_max_rss_mb |
off |
Optional maximum charged memory in MiB for the complete contained index-worker process tree (64..1048576). On macOS this is phys_footprint, not resident size. |
index_max_duration_seconds |
off |
Optional maximum wall-clock duration in seconds for the whole index request, including crash/hang recovery (1..86400). Like index_max_rss_mb, it stops a worker only before it starts to publish the new index; see INDEX_RESOURCE_LIMITS.md. |
install_hooks |
true |
Whether CLI-owned client hooks may be installed. install --no-hooks removes CLI-owned hooks and persists false; install --hooks restores true. |
While install_hooks is false, install, update, and install-hooks leave CLI-owned hooks off (install and update re-remove them); user-owned hook entries are never touched. install --hooks only clears the opt-out; run install-hooks afterwards to add hooks. Skills and instructions are unaffected.
watcher_enabledvsauto_watch.watcher_enabledcontrols whether the retained watcher subsystem starts at all.auto_watchis narrower: it controls whether an active project is registered with an already-running watcher. One-shot canonical CLI commands do not require a watcher or warm runtime.
watcher_enabledis read when the retained runtime starts. If you change it while that runtime is active, retire it so the next runtime observes the new value. Disabling the watcher does not disable explicitindex,search,trace,snippet, orcoveragecommands.
The four index_max_* settings are independent and disabled by default. They
apply to explicit indexing, automatic indexing, and watcher re-indexing, but not
to cross-repo-intelligence, which does not scan repository source files.
Equality is allowed; exceeding any setting fails the complete index request and
preserves any previously serving database. Worker RSS covers descendants and is
not the same as the internal CBM_MEM_BUDGET_MB allocation budget. Total
duration is independent of the existing 15-minute no-log-progress timeout. See
Index resource limits for counting, validation, and
error-response details.
Every indexed project is registered under its own absolute root path, so each
linked worktree becomes a separate permanent index. On machines that create many
short-lived worktrees, the automatic paths (auto_index, and the session hook's
"index this project first" guidance) turn every throwaway checkout into another
stored index of what is largely the same repository.
Enable the key to keep those checkouts out of the index:
codebase-memory-cli config set ignore_worktrees trueWith it enabled:
- automatic indexing skips a session whose root is a linked worktree;
- the
hook-augmentcontext says the worktree is unindexed on purpose instead of telling the agent to runcodebase-memory-cli index; - an explicit
codebase-memory-cli indexof a linked worktree is refused with an error that names both ways forward: pass--index-worktreefor that one call, or runcodebase-memory-cli config set ignore_worktrees false.
The main checkout of the same repository is unaffected, as are ordinary clones
and submodules. Detection is git plumbing only: a linked worktree's .git is a
file pointing at a gitdir that contains a commondir entry.
A subdirectory counts as the worktree it sits in. Detection walks up from the
given path to the nearest .git entry, so codebase-memory-cli index on any
subdirectory of a linked worktree is refused the same way, and a session root or
hook working directory inside one is treated as that worktree. The walk stops at
the first .git it finds; a main checkout or a submodule ends it as "not a
worktree". A path outside any git checkout is checked one directory at a time up
to the filesystem root and is never treated as a worktree. None of this runs
while the key is off.
The default is false, so indexing behavior is unchanged unless you opt in.
The optional built-in graph UI stores its settings in:
${CBM_CACHE_DIR:-~/.cache/codebase-memory-cli}/config.json
Current format:
{
"ui_enabled": false,
"ui_port": 9749
}Notes:
- If a UI-enabled binary finds its verified external asset pack and no UI config file exists yet, the UI auto-enables on first run. Missing or invalid assets keep the optional UI disabled; ordinary CLI commands remain available.
CBM_CACHE_DIRchanges both the UI config location and the runtime settings database location.- CBM resolves
CBM_CACHE_DIRto one canonical per-account cache root. A process configured with a different root fails while any CBM session or command is active; close them before switching roots.
These environment variables affect runtime behavior:
| Variable | Default | Description |
|---|---|---|
CBM_ALLOWED_ROOT |
(unset) | Confine index_repository to paths within this directory. When set, a repo_path that resolves (after symlink / .. resolution) outside this root is refused, and the same check now applies to the graph UI's POST /api/index route rather than only to one request path. Unset imposes no containment restriction — but see the always-on limits below, which apply whether or not this is set. Useful when agentic callers operate in a repository and indexing scope must remain human-controlled. |
CBM_CACHE_DIR |
~/.cache/codebase-memory-cli |
Override the cache directory used for indexes, _config.db, and UI config.json. |
CBM_DIAGNOSTICS |
false |
Enable periodic snapshot.json and retained trajectory.ndjson below a fresh owner-private directory in the system temp directory. The daemon records the randomized paths in the diagnostics.start discovery record (a single JSON line) in ${CBM_CACHE_DIR}/logs/cbm-daemon.log; that one record is emitted even when CBM_LOG_LEVEL suppresses ordinary logging, so the paths always remain discoverable. |
CBM_DOWNLOAD_URL |
GitHub releases | Override the update download URL. |
CBM_LOG_LEVEL |
role-aware | Set the log level to debug, info, warn, error, or none (or 0-4). Thin CLI/hook frontends default to warn; the detached daemon and supervised index workers default to info. Physical workers retain INFO liveness records because their private logs drive the supervisor's no-progress timeout. Frontend messages use that command's stderr; detached daemon events use ${CBM_CACHE_DIR}/logs/cbm-daemon.log. |
CBM_RUNTIME_DIR |
%LOCALAPPDATA% (Windows), /private/tmp (macOS), /tmp (other) |
Parent directory for the daemon/CLI rendezvous directory, which CBM creates inside it as cbm-daemon-<uid> (cbm-daemon-<key> on Windows). When an explicitly configured parent is missing, CBM creates it owner-private before use; existing parents are never modified and must pass the private-directory check. Set it when the default ancestry cannot pass that check — see below. CBM_CACHE_DIR does not move the rendezvous. |
CBM_WORKERS |
auto-detected | Override the indexing worker count. |
Before it is used, the rendezvous directory and every ancestor of it are checked:
each ancestor must be owned by you or by root, must not be world-writable (unless
it is the standard root-owned sticky directory such as /tmp), and must carry no
allow-ACL — on Windows, no ACE granting mutation rights to another identity. The
rendezvous directory itself is then forced to owner-only (0700, no extended ACL
/ an owner-only DACL).
That ancestry is not always acceptable in the default location. A Windows profile
that has acquired a capability-SID ACE with WRITE_DAC / WRITE_OWNER / DELETE
on %LOCALAPPDATA% — something an installed packaged app can add — fails the walk,
and so can an unusual /tmp or home directory on POSIX. When that happens every
command fails, config list included, so the settings surface cannot be reached
either:
codebase-memory-cli: secure daemon endpoint could not be created
CBM_RUNTIME_DIR points the rendezvous at an ancestry you choose:
export CBM_RUNTIME_DIR="$HOME/cbm-runtime" # any directory you own$env:CBM_RUNTIME_DIR = "D:\cbm-runtime"The check is not relaxed for the directory you name: it goes through exactly the same validation as the default, and a value that fails it is refused rather than silently ignored. Because the rendezvous is how sessions find each other, every process that should share one daemon must see the same value — set it consistently for any shells or agent processes that should share the same retained runtime coordination.
WSL2 and Windows drives (/mnt/c, /mnt/e, ...). CBM_CACHE_DIR goes through
the same private-directory check. With WSL's default automount options, DrvFs
reports every directory as 0777 and ignores chmod, so a cache under
/mnt/<drive> is refused, and the refusal names this remedy. Either turn on
permission metadata in /etc/wsl.conf, then run wsl --shutdown and reopen WSL:
[automount]
options = "metadata,umask=22,fmask=11"or keep the cache on the Linux filesystem (the default ~/.cache/codebase-memory-cli),
which is also much faster than a 9p-mounted Windows drive.
Environment used by retained runtime-owned components—such as diagnostics, logging, and process-wide indexing resource limits—is captured when that runtime starts. Later participants cannot replace those values. CBM_ALLOWED_ROOT remains caller-specific, a conflicting CBM_CACHE_DIR is rejected, and one-shot CLI commands use their own current environment.
Independently of CBM_ALLOWED_ROOT, some directories are refused as an indexing
root because they are too broad or too sensitive to index as a unit:
- a filesystem root, a Windows drive root, or a UNC share root;
- a top-level system tree —
/etc,/var,/usr,/home,/Users, and on WindowsC:\Windows,C:\Users,C:\ProgramData,C:\Program Files; - your home directory itself (directories below it are fine);
- a credential directory at any depth —
.ssh,.aws,.gnupg,.kube,.docker,.netrc,.git-credentials,.password-store, macOSKeychains.
A single top-level directory can still be indexed as one root on purpose, for
example a container or build machine that keeps its project in /work, /app or
/src, by approving that exact path in a terminal:
codebase-memory-cli allow-root --approve-broad /work. The approval is recorded
like any other allowed root, listed as (approved broad) by allow-root --list,
and covers no other top-level directory; as with any recorded root, indexing is
then confined to the recorded roots. Filesystem, drive and share roots cannot be
approved.
Two limits are worth stating plainly. This constrains scope, not sensitivity: inside a root that is allowed, every file the process can read may be indexed and later returned. And the credential list is a denylist, so it raises the cost of a mistake rather than closing the class — a directory it does not name is permitted.
The CLI-first install path can write Codebase Memory skills and durable CLI instructions for detected agents. Hooks are a separate explicit opt-in via codebase-memory-cli install-hooks. Neither lifecycle surface creates, migrates, adopts, or removes MCP registrations or MCP-owned assets; existing MCP state is treated as foreign for side-by-side safety. Both install and uninstall warn when an instruction file still contains a legacy codebase-memory-mcp managed block from the upstream MCP tool, but they leave that block in place for you to remove by hand.
Those target paths vary by tool and platform, so the easiest way to inspect the exact files for your machine is:
codebase-memory-cli install --dry-runThat prints the specific config files the installer would modify without writing anything.