--- name: cc-internals description: 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. --- # 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 └── / # One dir per project cwd ├── sessions-index.json # Session metadata index ├── .jsonl # Session transcripts └── agent-.jsonl # Subagent transcripts ``` ## Project Path Encoding Project directories are cwd paths with slashes replaced by dashes: | cwd | Encoded directory name | |-----|------------------------| | `/Users/me/projects/foo` | `-Users-me-projects-foo` | | `/Users/me/foo/.worktrees/bar` | `-Users-me-foo--worktrees-bar` | **Decode:** `echo "-Users-me-foo" | sed 's/^-/\//; s/-/\//g'` ## Sessions Index (`sessions-index.json`) Each project has one index tracking all sessions in that project. ```json { "version": 1, "entries": [ { "sessionId": "027b253b-7743-4cd7-8c7b-96740e0a3cf8", "fullPath": "/Users/.../.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 | |-------|-------------| | `sessionId` | UUID, matches `.jsonl` filename | | `summary` | Auto-generated by CC | | `customTitle` | User-set via `/rename` (null if unset) | | `firstPrompt` | First user message (truncated) | | `gitBranch` | Branch at session creation | | `projectPath` | Absolute cwd path | | `messageCount` | Total messages in session | | `isSidechain` | Whether session is a sidechain | | `created` / `modified` | ISO timestamps | | `fileMtime` | 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 `.jsonl` transcript | | **Persistence** | Survives session end, stored in index | ### Finding Named Sessions ```bash # 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`) Each line is a JSON object. See `cc-thread-search` for search patterns. ```json {"type": "user", "timestamp": "", "message": {...}, "sessionId": ""} {"type": "assistant", "timestamp": "", "message": {...}, "sessionId": ""} {"type": "summary", ...} ``` ## Related Skills | Topic | Skill | |-------|-------| | Searching transcripts | `cc-thread-search` | | Permission config | `cc-configuring-permissions` | | Hook config | `cc-writing-hooks` | | MCP config | `cc-configuring-mcp` |