askill
claude-code-metadata

claude-code-metadataSafety 100Repository

Comprehensive guide to Claude Code's local data storage, session formats, token tracking, and metadata structures. Use when building dashboards, analytics tools, migration scripts, or any application that needs to read Claude Code's local data. Covers JSONL session format, stats-cache.json structure, settings hierarchy, file history, and all ~/.claude directory contents.

0 stars
1.2k downloads
Updated 2/9/2026

Package Files

Loading files...
SKILL.md

Claude Code Metadata & Data Formats

Complete technical reference for Claude Code's local data storage architecture. All data is stored locally in ~/.claude/.

Directory Structure Overview

~/.claude/
├── CLAUDE.md                    # User memory file (personal instructions)
├── settings.json                # User settings (global)
├── settings.json.backup         # Backup of settings
├── stats-cache.json             # Token usage statistics cache
├── history.jsonl                # Session index/metadata
│
├── projects/                    # Session transcripts by project path
│   └── -Users-name-project/     # Path encoded as directory name
│       ├── session-uuid.jsonl   # Main session files
│       └── agent-xyz.jsonl      # Agent/subagent sessions
│
├── session-env/                 # Session environment snapshots
│   └── session-uuid/            # Per-session env directory
│
├── todos/                       # Todo lists per session/agent
│   └── session-uuid-agent-uuid.json
│
├── plans/                       # Plan mode files (markdown)
│   └── adjective-verb-noun.md   # Random generated names
│
├── debug/                       # Debug logs per session
│   └── session-uuid.txt
│   └── latest                   # Symlink to most recent
│
├── file-history/                # File backup history
│   └── session-uuid/
│       └── content-hash@v1      # Versioned file backups
│
├── shell-snapshots/             # Shell state snapshots
│   └── snapshot-zsh-timestamp-random.sh
│
├── skills/                      # User skills (symlinks or dirs)
│   └── skill-name/
│       ├── SKILL.md
│       └── references/
│
├── agents/                      # Custom agent definitions
│   └── agent-name.md
│
├── plugins/                     # Plugin system
│   ├── config.json
│   ├── installed_plugins.json
│   ├── known_marketplaces.json
│   ├── cache/                   # Downloaded plugin cache
│   ├── marketplaces/            # Marketplace repos
│   └── repos/
│
├── config/                      # Additional config
│   └── notification_states.json
│
├── statsig/                     # Feature flags (Statsig)
│   ├── statsig.cached.evaluations.*
│   ├── statsig.failed_logs.*
│   ├── statsig.last_modified_time.*
│   ├── statsig.session_id.*
│   └── statsig.stable_id.*
│
├── chrome/                      # Chrome extension support
│   └── chrome-native-host
│
├── ide/                         # IDE integration (empty by default)
│
└── telemetry/                   # Telemetry data (empty by default)

Session JSONL Format

Sessions are stored as JSON Lines files. Each line is a complete JSON object representing a message or event.

Message Types

typeDescription
userUser messages
assistantClaude responses
summaryContext summaries
file-history-snapshotFile backup checkpoints

User Message Schema

{
  "parentUuid": "previous-message-uuid",
  "isSidechain": false,
  "userType": "external",
  "cwd": "/working/directory",
  "sessionId": "session-uuid",
  "version": "2.0.76",
  "gitBranch": "main",
  "type": "user",
  "message": {
    "role": "user",
    "content": "message text or array of content blocks"
  },
  "isMeta": false,
  "uuid": "unique-message-id",
  "timestamp": "2025-12-26T23:15:21.914Z"
}

Assistant Message Schema

{
  "parentUuid": "user-message-uuid",
  "isSidechain": false,
  "userType": "external",
  "cwd": "/working/directory",
  "sessionId": "session-uuid",
  "version": "2.0.76",
  "gitBranch": "main",
  "slug": "adjective-verb-noun",
  "message": {
    "model": "claude-opus-4-5-20251101",
    "id": "msg_01XYZ...",
    "type": "message",
    "role": "assistant",
    "content": [
      {
        "type": "thinking",
        "thinking": "internal reasoning...",
        "signature": "base64-signature..."
      },
      {
        "type": "text",
        "text": "response text"
      },
      {
        "type": "tool_use",
        "id": "toolu_01ABC...",
        "name": "ToolName",
        "input": { "param": "value" }
      }
    ],
    "stop_reason": "end_turn",
    "stop_sequence": null,
    "usage": {
      "input_tokens": 100,
      "cache_creation_input_tokens": 5000,
      "cache_read_input_tokens": 20000,
      "cache_creation": {
        "ephemeral_5m_input_tokens": 5000,
        "ephemeral_1h_input_tokens": 0
      },
      "output_tokens": 500,
      "service_tier": "standard"
    }
  },
  "requestId": "req_01XYZ...",
  "type": "assistant",
  "uuid": "message-uuid",
  "timestamp": "2025-12-26T23:16:04.923Z"
}

Tool Result Message Schema

{
  "parentUuid": "tool-use-message-uuid",
  "isSidechain": false,
  "userType": "external",
  "cwd": "/working/directory",
  "sessionId": "session-uuid",
  "version": "2.0.76",
  "gitBranch": "main",
  "slug": "adjective-verb-noun",
  "type": "user",
  "message": {
    "role": "user",
    "content": [
      {
        "tool_use_id": "toolu_01ABC...",
        "type": "tool_result",
        "content": "tool output text"
      }
    ]
  },
  "uuid": "result-uuid",
  "timestamp": "2025-12-26T23:16:05.510Z",
  "toolUseResult": {
    "mode": "files_with_matches",
    "filenames": ["file1.go", "file2.go"],
    "numFiles": 2
  }
}

File History Snapshot Schema

{
  "type": "file-history-snapshot",
  "messageId": "associated-message-uuid",
  "snapshot": {
    "messageId": "associated-message-uuid",
    "trackedFileBackups": {
      "/path/to/file": "content-hash"
    },
    "timestamp": "2025-12-26T23:15:21.917Z"
  },
  "isSnapshotUpdate": false
}

Content Types in Messages

Messages can have content as:

  • String: Plain text content
  • Array: Multiple content blocks

Content block types:

  • text: Plain text { "type": "text", "text": "..." }
  • image: Base64 image { "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": "..." } }
  • thinking: Model reasoning { "type": "thinking", "thinking": "...", "signature": "..." }
  • tool_use: Tool invocation { "type": "tool_use", "id": "...", "name": "...", "input": {...} }
  • tool_result: Tool output { "type": "tool_result", "tool_use_id": "...", "content": "..." }

Stats Cache Format (stats-cache.json)

Aggregated usage statistics cached locally.

{
  "version": 1,
  "lastComputedDate": "2025-12-25",
  "totalSessions": 766,
  "totalMessages": 58731,
  "firstSessionDate": "2025-11-12T06:27:12.809Z",

  "dailyActivity": [
    {
      "date": "2025-12-24",
      "messageCount": 4800,
      "sessionCount": 16,
      "toolCallCount": 1464
    }
  ],

  "dailyModelTokens": [
    {
      "date": "2025-12-24",
      "tokensByModel": {
        "claude-opus-4-5-20251101": 33212,
        "claude-sonnet-4-5-20250929": 103056,
        "claude-haiku-4-5-20251001": 272249
      }
    }
  ],

  "modelUsage": {
    "claude-opus-4-5-20251101": {
      "inputTokens": 1640347,
      "outputTokens": 2475769,
      "cacheReadInputTokens": 1242320484,
      "cacheCreationInputTokens": 66151371,
      "webSearchRequests": 0,
      "costUSD": 0,
      "contextWindow": 0
    }
  },

  "hourCounts": {
    "9": 58,
    "10": 43,
    "17": 59,
    "18": 94
  },

  "longestSession": {
    "sessionId": "uuid",
    "duration": 96242264,
    "messageCount": 4,
    "timestamp": "2025-11-17T02:12:38.105Z"
  }
}

Settings Format (settings.json)

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "model": "opus",
  "alwaysThinkingEnabled": true,

  "hooks": {
    "PreCompact": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'hook output'"
          }
        ]
      }
    ],
    "SessionStart": []
  },

  "statusLine": {
    "type": "command",
    "command": "shell command for status line"
  },

  "enabledPlugins": {
    "plugin-name@marketplace": true
  },

  "feedbackSurveyState": {
    "lastShownTime": 1754025174206
  }
}

Hook Event Types

  • SessionStart: When a new session begins
  • PreCompact: Before context compaction
  • SubagentStart: When a subagent is spawned

History Index (history.jsonl)

Each line contains session metadata:

{
  "display": "user message preview",
  "pastedContents": {},
  "timestamp": 1766792756159,
  "project": "/Users/name/code/project",
  "sessionId": "session-uuid"
}

Todo Format (todos/*.json)

[
  {
    "content": "Task description",
    "status": "in_progress",
    "activeForm": "Working on task"
  }
]

Status values: pending, in_progress, completed

Installed Plugins Format

{
  "version": 2,
  "plugins": {
    "plugin-name@marketplace-name": [
      {
        "scope": "user",
        "installPath": "/path/to/plugin",
        "version": "1.0.0",
        "installedAt": "2025-12-04T02:42:33.270Z",
        "lastUpdated": "2025-12-04T02:42:33.270Z",
        "gitCommitSha": "abc123...",
        "isLocal": true
      }
    ]
  }
}

Agent Definition Format

Markdown file with YAML frontmatter:

---
name: agent-name
description: When to use this agent
model: sonnet
color: green
---

Agent system prompt instructions here...

Memory File Hierarchy

Priority order (highest to lowest):

PriorityLocationScope
1/Library/Application Support/ClaudeCode/CLAUDE.md (macOS)Enterprise
2./CLAUDE.md or ./.claude/CLAUDE.mdProject (team)
3./.claude/rules/*.mdProject rules
4~/.claude/CLAUDE.mdUser (all projects)
4b./CLAUDE.local.mdProject local

Import Syntax

See @README for project overview.
@docs/instructions.md
@~/.claude/custom-rules.md

File History Backup Format

Files in file-history/session-uuid/:

  • Filename: content-hash@vN (e.g., 89a91e02ba2f0439@v1)
  • Content: Raw file contents at that version

Debug Log Format

Plain text with timestamps:

2025-11-25T19:05:43.547Z [DEBUG] Message here...

Shell Snapshot Format

Shell script capturing environment:

# Snapshot file
# Unset all aliases to avoid conflicts with functions
unalias -a 2>/dev/null || true
# Functions
function_name () { ... }
# Environment variables
export VAR=value

Notification States (config/notification_states.json)

{
  "switch_to_custom": {
    "triggered": false,
    "timestamp": null
  },
  "exceed_max_limit": {
    "triggered": true,
    "timestamp": "2025-09-27T19:00:38.269745"
  },
  "tokens_will_run_out": {
    "triggered": false,
    "timestamp": null
  },
  "cost_will_exceed": {
    "triggered": true,
    "timestamp": "2025-09-27T16:56:18.406988"
  }
}

Statsig Feature Flags

Files in statsig/:

  • statsig.cached.evaluations.*: Feature flag cache
  • statsig.failed_logs.*: Failed telemetry
  • statsig.stable_id.*: User identifier
  • statsig.session_id.*: Session identifier

Project Path Encoding

Project paths become directory names by replacing / with -:

  • /Users/name/code/project -> -Users-name-code-project

Token Usage Calculation

IMPORTANT: Usage data is nested at message.usage, NOT at the top level of a JSONL line.

From assistant messages (type: "assistant"), extract from message.usage:

  • message.usage.input_tokens: Direct input tokens
  • message.usage.output_tokens: Response tokens
  • message.usage.cache_creation_input_tokens: New cache entries
  • message.usage.cache_read_input_tokens: Cache hits

Field names use snake_case (input_tokens, not inputTokens).

Cache efficiency = cache_read_input_tokens / (cache_read_input_tokens + input_tokens)

What dailyModelTokens tracks

The dailyModelTokens field in stats-cache.json tracks a proprietary aggregate computed by Claude Code. It does NOT equal the sum of per-message usage.input_tokens + usage.output_tokens from JSONL files. Empirically, dailyModelTokens values are ~0.04x–0.39x of the JSONL-derived input_tokens + output_tokens sum for the same day. The exact formula is internal to Claude Code.

Key implication: If your tool is calibrated against dailyModelTokens (e.g., by correlating it with scraped usage percentages), you MUST continue using dailyModelTokens for consistency. Switching to JSONL-summed tokens will produce values ~3-25x larger, breaking any calibration.

stats-cache.json Volatility Warning

stats-cache.json values can change retroactively. Claude Code rebuilds this file by scanning JSONL session files. Key issues:

  1. Retroactive rewriting: When sessions are deleted (30-day retention cleanup), the cache is rebuilt and historical daily totals can drop.
  2. Timezone uncertainty: The date bucketing in the cache may use a different timezone than expected.
  3. Race conditions: If Claude Code is running when you read the cache, values may include in-progress data.

Direct JSONL Scanning

For per-message ground truth, scan JSONL session files directly. Filter .jsonl files by os.FileInfo.ModTime() for performance (skip files not modified in your date range), then parse message.usage from type: "assistant" lines. Note that the per-message totals will NOT match dailyModelTokens from stats-cache.

Session Retention

Default: 30 days. Configure with cleanupPeriodDays setting.

Key UUIDs

All UUIDs follow RFC 4122 format:

  • Session IDs: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  • Message UUIDs: Same format, linked via parentUuid
  • Request IDs: req_ prefix
  • Tool IDs: toolu_ prefix
  • Message IDs: msg_ prefix

Model Identifiers

Common model IDs:

  • claude-opus-4-6 (latest)
  • claude-opus-4-5-20251101
  • claude-sonnet-4-5-20250929
  • claude-haiku-4-5-20251001

Cost Calculation Reference

Per-million tokens (approximate):

  • Haiku: $0.25 input / $1.25 output
  • Sonnet: $3.00 input / $15.00 output
  • Opus: $5.00 input / $25.00 output
  • Cache read: 90% discount
  • Batch: 50% discount

Useful Queries

Count total tokens per session

Parse JSONL, sum message.usage.input_tokens + message.usage.output_tokens for type: "assistant" lines.

Find all sessions for a project

List files in projects/-path-to-project/.

Get session timeline

Sort messages by timestamp field.

Reconstruct conversation tree

Follow parentUuid chains to build message tree.

Third-Party Tools

  • ccusage: CLI for analyzing usage from JSONL files
  • Claude Code Usage Monitor: Real-time terminal dashboard
  • LiteLLM: Proxy for tracking enterprise usage

References

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

88/100Analyzed 2/18/2026

High-quality technical reference document covering Claude Code's local data storage comprehensively. Provides detailed schemas for JSONL sessions, stats-cache, settings, and other data structures. Well-organized with tables and code examples. Missing a dedicated "when to use" section and the final token usage section appears truncated. However, it serves as an excellent reference for building analytics tools, dashboards, or migration scripts. Tags help discoverability but could be more specific.

100
90
95
88
80

Metadata

Licenseunknown
Version-
Updated2/9/2026
Publishermarcus

Tags

apici-cdllmprompting