Claude-skill-registry cc-internals
How Claude Code works internally. Use for ANY question about CC behavior, architecture, or "how does CC do X". Covers session storage, /rename scope, project organization, file locations, and internal data structures.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/cc-internals" ~/.claude/skills/majiayu000-claude-skill-registry-cc-internals && rm -rf "$T"
manifest:
skills/data/cc-internals/SKILL.mdsource content
Claude Code Internals
Facts about how Claude Code organizes and stores data.
Storage Layout
~/.claude/ ├── settings.json # User config (see cc-configuring-permissions) ├── skills/ # User-level skills ├── session-env/ # Session environment cache └── projects/ # All session data, per-project └── <encoded-path>/ # One dir per project cwd ├── sessions-index.json # Session metadata index ├── <uuid>.jsonl # Session transcripts └── agent-<hash>.jsonl # Subagent transcripts
Project Path Encoding
Project directories are cwd paths with slashes replaced by dashes:
| cwd | Encoded directory name |
|---|---|
| |
| |
Decode:
echo "-Users-me-foo" | sed 's/^-/\//; s/-/\//g'
Sessions Index (sessions-index.json
)
sessions-index.jsonEach project has one index tracking all sessions in that project.
{ "version": 1, "entries": [ { "sessionId": "027b253b-7743-4cd7-8c7b-96740e0a3cf8", "fullPath": "/Users/.../<uuid>.jsonl", "firstPrompt": "user's first message...", "summary": "Auto-generated summary", "customTitle": "user-set via /rename", "messageCount": 28, "created": "2026-01-17T00:22:31.447Z", "modified": "2026-01-17T00:44:18.038Z", "gitBranch": "main", "projectPath": "/Users/me/projects/foo", "isSidechain": false, "fileMtime": 1769006749607 } ] }
Session Entry Fields
| Field | Description |
|---|---|
| UUID, matches filename |
| Auto-generated by CC |
| User-set via (null if unset) |
| First user message (truncated) |
| Branch at session creation |
| Absolute cwd path |
| Total messages in session |
| Whether session is a sidechain |
/ | ISO timestamps |
| File modification time (epoch ms) |
/rename Command
Sets
customTitle field in sessions-index.json.
| Aspect | Behavior |
|---|---|
| Scope | Per-project (cwd-specific) |
| Collision | Same name can exist in different projects |
| Storage | Only in index, not in transcript |
| Persistence | Survives session end, stored in index |
Finding Named Sessions
# All named sessions across all projects for dir in ~/.claude/projects/*/; do jq -r '.entries[] | select(.customTitle != null) | "\(.customTitle) | \(.projectPath)"' \ "$dir/sessions-index.json" 2>/dev/null done # Named sessions in current project jq -r '.entries[] | select(.customTitle != null) | "\(.customTitle): \(.sessionId)"' \ ~/.claude/projects/-Users-me-projects-foo/sessions-index.json
Session Transcripts (.jsonl
)
.jsonlEach line is a JSON object. See
cc-thread-search for search patterns.
{"type": "user", "timestamp": "<ISO>", "message": {...}, "sessionId": "<uuid>"} {"type": "assistant", "timestamp": "<ISO>", "message": {...}, "sessionId": "<uuid>"} {"type": "summary", ...}
Related Skills
| Topic | Skill |
|---|---|
| Searching transcripts | |
| Permission config | |
| Hook config | |
| MCP config | |