Reference·FilesIndex

Files

Every file and folder Nodecode keeps: the home, the cache, and the folder it leaves in each project.

.mdllms.txt

Nodecode keeps a home for each profile, a cache every profile shares, and an undo folder in each project it edits.

The home

The home is ~/.nodecode/. This one has had an afternoon: four turns, one key, one /backup and one profile. In it are and , of kept definitions, of memories and skills, , and .

~$ tree -a -L 2 --dirsfirst --noreport -I .git ~/.nodecode/home/you/.nodecode├── backups│   ├── nodecode-default-2026-10-08-211925.json│   └── nodecode-default-2026-10-08-211925.tar.gz├── cells│   ├── .locks│   ├── you│   └── you-memory├── generations│   ├── 1.json│   ├── 2.json│   └── 3.json├── profiles│   └── work├── auth.json├── cells-named├── composer-catalogs.sexp├── composer-history├── config.jsonc├── history.db├── history.db-shm├── history.db-wal├── history.db.lock├── history.db.owner├── history.db.stdio.log├── operator-token└── usage.jsonl

A profile has a home of its own under ~/.nodecode/profiles/<name>/, laid out the same way.

Settings

Files you or the agent write on purpose. A profile and an export carry them.

EntryHolds
config.jsoncThe settings. See Config.
AGENTS.mdYour rules for every session. See Instruction files.
SOUL.mdThe persona channel bots speak in.
themes.jsonYour own themes.
auth.jsonProvider keys, at api_keys.<id>.key. /connect writes it.
secrets/Secrets pasted into setup, one file each.
cells/Cell folders. See Cells.
cells/<you>/The layer: the definitions the agent kept, one file each. A git repository.
cells/<you>-memory/The knowledge cell: memories and skills, kept as definitions. Read by the index, never loaded.
profile.jsoncThe profile's manifest: what this profile is.

<you> is git's user.name in lowercase, each run of other characters one hyphen: Mike Smith is mike-smith. Without one it is USER, then you.

Writing a key into config.jsonc as api_key

An export and a new profile carry config.jsonc, key and all, and no mode is forced on it.

Instead: /connect. The key goes in auth.json, 0600, which an export leaves out.

Keeping ~/.nodecode in a dotfiles repository

It carries auth.json, operator-token and the store.

Instead: nodecode profile export NAME PATH: the settings and the cells, no store, no keys.

Mistake
~$ tar xzOf ~/share.tar.gz .nodecode/config.jsonc | grep api_key "api_key": "sk-demo",

The plain export, the one meant for sharing, has the key in it.

Instead
~$ nodecode profile export default ~/share2.tar.gz && tar xzf ~/share2.tar.gz -O | grep -c sk-newexported default to /home/you/share2.tar.gz0

The key /connect saved is nowhere in it.

State

Files Nodecode makes for itself. A new profile starts without them, and an export leaves them out.

EntryHolds
history.dbThe store: every session and every event. SQLite, with -wal and -shm beside it.
history.db.lockHeld by the process that owns the store, for as long as it runs.
history.db.ownerThat process's pid and gateway port, as JSON.
history.db.stdio.logThe organism's boot log and stray output.
operator-tokenThe gateway token. See Safety and trust.
usage.jsonlEach keep, view and call of a memory or skill. The index ranks by it.
generations/A manifest per sealed generation, and a restore's markers.
release-pinThe release a rollback pinned. nodecode update lifts it.
keybinds.jsonKey overrides. See The shell.
theme-selectionThe theme picked with /themes.
composer-historyPrompts you typed.
composer-catalogs.sexpThe lists @ and / complete from, as last read.
cells-namedShipped cells already named as not installed.
distribution.jsonWhere this home was installed from.
gateway-offThe background gateway's off switch.
import/The import's marker and its reports.
hub/The cell index, as last read.
cells/.locks/Write locks of the knowledge cells.
mcp/MCP servers' error logs, mcp/<name>.stderr.log.
link/state.jsonThis machine's name at its relay, and the browsers let in.
backups//backup's archives, each with a .json note.
team/, chrome-extension/, chrome-screenshots/Written by the team and chrome cells.

The store

While Nodecode runs, and . The lock names who owns them: and . Every shell you open attaches to that one.

~$ ls -lh ~/.nodecode/history.db*-rw-r--r-- 1 you you 4.0K Oct 8 21:18 /home/you/.nodecode/history.db-rw-r--r-- 1 you you 32K Oct 8 21:18 /home/you/.nodecode/history.db-shm-rw-r--r-- 1 you you 3.6M Oct 8 21:19 /home/you/.nodecode/history.db-wal-rw------- 1 you you 0 Oct 8 21:18 /home/you/.nodecode/history.db.lock-rw------- 1 you you 38 Oct 8 21:18 /home/you/.nodecode/history.db.owner-rw-r--r-- 1 you you 217 Oct 8 21:18 /home/you/.nodecode/history.db.stdio.log
~$ cat ~/.nodecode/history.db.owner{ "pid": 2212192, "port": 37213}

Copying history.db while Nodecode runs

You get the header and none of the sessions: no such table: events.

Instead: nodecode profile export NAME PATH --whole, or /backup. Both take a whole copy of the store while it runs.

Deleting history.db.lock

A second organism takes the same store on another port. When it stops it deletes history.db.owner, and the shells lose the first.

Instead: Nothing to clear. The lock goes with the process that holds it, crash or not. nodecode profile list shows who holds it.

Mistake
~$ cp ~/.nodecode/history.db ~/copy.db && sqlite3 -list ~/copy.db 'select count(*) from events'Parse error in 3rd command line argument: no such table: events
~$ rm ~/.nodecode/history.db.lock && timeout 6 nodecode serve; echo "exit $?"; cat ~/.nodecode/history.db.ownercell you: layer, 2 definitions, generation 3cell you-memory: knowledge, 1 definition[CP-ISSUE-20260912-001] gateway readyserving store /home/you/.nodecode/history.db on port 36563 (session "s-U1LGSL8W")[CP-ISSUE-20260912-002] gateway heartbeatexit 124cat: /home/you/.nodecode/history.db.owner: No such file or directory

The copy has no tables. The second organism served on its own port, then took the owner file with it.

Instead
~$ nodecode profile export default ~/home.tar.gz --whole && mkdir -p ~/check && tar xzf ~/home.tar.gz -C ~/check && sqlite3 -list ~/check/.nodecode/history.db 'select count(*) from events'exported default to /home/you/home.tar.gz, its store and keys with it: keep it where you keep passwords78
~$ nodecode profile list* default /home/you/.nodecode serving pid 2212192 port 37213 boots by default also carrying cells-named, composer-catalogs.sexp work /home/you/.nodecode/profiles/work shares auth.json, cells/you-memory with default

The archive's store answers 78 events. The list names the process that holds the lock.

The layer

Each definition the agent keeps is a file in cells/<you>/ and , and each keep seals . To go back, roll back to one.

~$ git -C ~/.nodecode/cells/you log --onelineb453153 (HEAD -> master) word-count — session s-8ZRLUFP812d29ea count-lines — session s-8ZRLUFP8
~$ nodecode generationsgeneration 3 current 2026-10-09T04:19:20.188Z nodecode 0.0.1+370099410 you layer own b453153 +1 keep since 2generation 2 2026-10-09T04:18:49.964Z nodecode 0.0.1+370099410 you layer own 12d29ea added since 1: yougeneration 1 2026-10-09T04:18:44.853Z nodecode 0.0.1+370099410

Deleting a kept file to take a definition back

The folder now has an edit nothing versions, and a rollback refuses until it is gone.

Instead: nodecode rollback N to the generation before it. The layer takes one commit forward, and its history stays.

Mistake
~$ rm ~/.nodecode/cells/you/word-count.lisp && nodecode rollback 2nodecode: generation 2 cannot be restored: you has uncommitted edits; keep or discard them first
Instead
~$ nodecode rollback 2generation 2 restored: you at 12d29ea; the next launch runs it
~$ git -C ~/.nodecode/cells/you log --oneline && ls ~/.nodecode/cells/you854f3fa (HEAD -> master) restored generation 2 -- session s-GATEWAYb453153 word-count — session s-8ZRLUFP812d29ea count-lines — session s-8ZRLUFP8count-lines.lisp you.asd

Profiles

A new profile copies the settings and : auth.json, secrets/ and every knowledge cell. It gets a fresh store and a fresh layer. --clone-all copies the keys and clones the layer instead. See Profiles.

~$ ls -l ~/.nodecode/profiles/work ~/.nodecode/profiles/work/cells/home/you/.nodecode/profiles/work:total 8lrwxrwxrwx 1 you you 29 Oct 8 21:19 auth.json -> /home/you/.nodecode/auth.jsondrwxr-xr-x 2 you you 60 Oct 8 21:19 cells-rw-r--r-- 1 you you 548 Oct 8 21:19 config.jsonc-rw-r--r-- 1 you you 193 Oct 8 21:19 profile.jsonc /home/you/.nodecode/profiles/work/cells:total 0lrwxrwxrwx 1 you you 37 Oct 8 21:19 you-memory -> /home/you/.nodecode/cells/you-memory/
Only in the default homeHolds
profiles/<name>/The home of each named profile.
active-profileThe profile a bare nodecode boots. nodecode profile use writes it.

/connect inside a profile to change the shared key

The save puts a file where the link was. That profile keeps the new key, every other one keeps the old, and profile list still says it shares.

Instead: /connect in the default home. Every profile that links auth.json reads the new key.

Mistake
~$ ls -l ~/.nodecode/profiles/work/auth.json; grep -h "\"key\"" ~/.nodecode/auth.json ~/.nodecode/profiles/work/auth.json-rw------- 1 you you 111 Oct 8 21:20 /home/you/.nodecode/profiles/work/auth.json "key": "sk-demo-4f1c9a2e7b" "key": "sk-work-90b3e1d55a"
~$ nodecode profile list* default /home/you/.nodecode serving pid 2212192 port 37213 boots by default also carrying cells-named, composer-catalogs.sexp work /home/you/.nodecode/profiles/work serving pid 2225020 port 46507 shares auth.json, cells/you-memory with default also carrying composer-catalogs.sexp

After /connect in work: a plain file, two keys, and the list unchanged.

Instead
~$ ls -l ~/.nodecode/profiles/work/auth.json; grep -h "\"key\"" ~/.nodecode/auth.json ~/.nodecode/profiles/work/auth.jsonlrwxrwxrwx 1 you you 29 Oct 8 21:23 /home/you/.nodecode/profiles/work/auth.json -> /home/you/.nodecode/auth.json "key": "sk-new-77d0c4e1aa" "key": "sk-new-77d0c4e1aa"

After /connect in the default home: still a link, one key.

Outside the home

PathHolds
<project>/.nodecode/workspace_snapshotsSnapshots for undo, in each folder a session edits. Never in your home folder or /. See Sessions and undo.
~/.local/share/nodecode/The installed releases. On Windows, %LOCALAPPDATA%\Programs\nodecode. See Install.
~/.local/bin/<profile>The command profile create writes for a profile.
nodecode-gateway.serviceThe background gateway, in ~/.config/systemd/user/. On macOS, a plist in ~/Library/LaunchAgents/.
nodecode-ephemeral-<pid>.dbThe store of an --ephemeral run, in the temp folder.

Nodecode does not add .nodecode/ to your project's ignore list. Until you do, .

~/project$ git status --short && du -sh .nodecode M src/main.rs?? .nodecode/128K .nodecode

git add -A in a project Nodecode has edited

The snapshot repository goes into your commit: 30 files after one edit.

Instead: Add .nodecode/ to .gitignore, or to .git/info/exclude to keep it to yourself.

Mistake
~/project$ git add -A && git status --short | head -6 && git status --short | wc -lA .nodecode/workspace_snapshots/HEADA .nodecode/workspace_snapshots/capture-countA .nodecode/workspace_snapshots/configA .nodecode/workspace_snapshots/descriptionA .nodecode/workspace_snapshots/hooks/applypatch-msg.sampleA .nodecode/workspace_snapshots/hooks/commit-msg.sample31
Instead
~/project$ echo .nodecode/ >> .git/info/exclude && git status --short M src/main.rs

Cache

What Nodecode can fetch or build again. Every profile shares it. Most of it is ; the home itself is .

~$ du -sh ~/.cache/nodecode/* ~/.nodecode16K /home/you/.cache/nodecode/layers7.5M /home/you/.cache/nodecode/models.dev158M /home/you/.cache/nodecode/warm4.0M /home/you/.nodecode
PlatformCache root
Linux, macOS$XDG_CACHE_HOME/nodecode/, else ~/.cache/nodecode/
Windows%LOCALAPPDATA%\nodecode\, unless XDG_CACHE_HOME is set
EntryHolds
models.dev/api.jsonThe models.dev catalog.
provider-models.jsonModel lists fetched from providers.
layers/, peripherals/The compiled layer and cells, per build.
warm/Launch images. Linux and macOS.
previews/Images converted for the prompt.
profile-import/, profile-install/Where a profile is unpacked before it moves in.
leases/One lock per bot token, so two organisms never run one bot.
channel-files/, channel-images/Channel attachments and images.
card-pictures/Pictures for Discord cards. Gone after a day.
libdave/, speaker/, transcriber/Discord's voice encryption, and the local voice and speech engines.
prs/Scratch clones for the prs cell.
open-url.logOutput of the last link opener.

Deleting ~/.nodecode to free space

That is the agent: its store, its layer, its keys. Here it is 4 MB.

Instead: Clear the cache. rm -rf ~/.cache/nodecode/warm is always safe; the next launch builds it again.

Permissions

The home is , and so is . .

~$ stat -c "%A %n" ~/.nodecode ~/.nodecode/auth.json ~/.nodecode/operator-token ~/.nodecode/history.db.owner ~/.nodecode/backups ~/.nodecode/backups/* ~/.nodecode/config.jsoncdrwx------ /home/you/.nodecode-rw------- /home/you/.nodecode/auth.json-rw------- /home/you/.nodecode/operator-token-rw------- /home/you/.nodecode/history.db.ownerdrwx------ /home/you/.nodecode/backups-rw------- /home/you/.nodecode/backups/nodecode-default-2026-10-08-211925.json-rw------- /home/you/.nodecode/backups/nodecode-default-2026-10-08-211925.tar.gz-rw-r--r-- /home/you/.nodecode/config.jsonc
PathMode
~/.nodecode/0700. Set when the store opens, and again at every write of a key.
auth.json, operator-token0600, at every write.
Files in secrets/0600, in a 0700 folder.
history.db.owner, history.db.lock0600
link/state.json0600, in a 0700 folder.
backups/0700. Each archive and note: 0600.
An export --whole archive0600
config.jsoncNo mode is forced. A write keeps the file's mode.

Backups and exports

Three ways to take a home with you, and only one is for sharing.

The shell after /backup
EntryNew profile--clone-allExport--whole/backup
config.jsonc, AGENTS.md, SOUL.md, themes.jsonCopiedCopiedCopiedCopiedCopied
auth.json, secrets/LinkedCopiedNoCopiedCopied
cells/<you>/, the layerNewClonedCopiedCopiedCopied
cells/<you>-memory/LinkedClonedCopiedCopiedCopied
history.db, the storeNewNewNoCopiedCopied
operator-token and the rest of StateNoNoNoNoNo

Linked is one file for both homes. nodecode profile import PATH brings either export back as a profile.

Sending someone a backup to share your setup

It holds auth.json and every session you had.

Instead: nodecode profile export NAME PATH, without --whole.

Mistake
~$ tar tzf ~/.nodecode/backups/*.tar.gz | grep -v /.git/.nodecode/history.db.nodecode/config.jsonc.nodecode/cells/.nodecode/cells/you-memory/.nodecode/cells/you-memory/you-memory.asd.nodecode/cells/you-memory/one-change-per-commit.lisp.nodecode/cells/.locks/.nodecode/cells/.locks/you-memory.lock.nodecode/cells/you/.nodecode/cells/you/you.asd.nodecode/cells/you/word-count.lisp.nodecode/cells/you/count-lines.lisp.nodecode/auth.json
Instead
~$ nodecode profile export default ~/share.tar.gz && tar tzf ~/share.tar.gz | grep -v /.git/exported default to /home/you/share.tar.gz.nodecode/config.jsonc.nodecode/cells/.nodecode/cells/you-memory/.nodecode/cells/you-memory/you-memory.asd.nodecode/cells/you-memory/one-change-per-commit.lisp.nodecode/cells/.locks/.nodecode/cells/.locks/you-memory.lock.nodecode/cells/you/.nodecode/cells/you/you.asd.nodecode/cells/you/word-count.lisp.nodecode/cells/you/count-lines.lisp
Esc

    Loading the index…

    ↑↓ moveEnter openEsc close