Directory layout (~/.claude/)
~/.claude/
├── projects/ 862 MB ← main artifact store, per-project dirs
│ └── -Users-mirek-Work-...-<project-path>/
│ ├── <sessionId>.jsonl full conversation transcript
│ ├── <sessionId>/ per-session subdirs
│ │ ├── subagents/ sub-agent JSONL + meta files
│ │ └── tool-results/ (sometimes present)
│ └── memory/ project-scoped CLAUDE.md memory (shared)
├── file-history/ 8 MB per-session file snapshots (content-addressed)
│ └── <sessionId>/
│ └── <fileHash>@v<N> file content before edits (undo history)
├── todos/ 72 KB per-session to-do lists
│ └── <sessionId>-agent-<agentId>.json
├── tasks/ 700 KB per-session task tracking
│ └── <sessionId>/
│ └── <N>.json
├── sessions/ 8 KB running process registry (PID files)
│ └── <pid>.json {pid, sessionId, cwd, status, ...}
├── session-env/ 0 B per-session env dirs (appear empty, ephemeral)
│ └── <sessionId>/
├── shell-snapshots/ 20 KB zsh env snapshots (NOT per-session, global)
├── backups/ 280 KB rolling .claude.json backups (max 5, auto-rotate)
├── history.jsonl 886 KB global CLI input history (not per-session)
├── stats-cache.json 14 KB global usage stats
├── settings.json 2 KB global user settings
├── paste-cache/ 344 KB content-addressed paste blobs (not per-session)
├── cache/ 264 KB changelog, closed-issues cache (global)
└── telemetry/ 9.8 MB telemetry data (global)
Per-conversation artifacts
The project directory name is the workspace path with / replaced by -, prefixed with -:
/Users/mirek/Work/foo/bar → -Users-mirek-Work-foo-bar
| Path pattern | Description | Identifies | Safe to delete on close? |
|---|---|---|---|
~/.claude/projects/<enc-path>/<sessionId>.jsonl | Full conversation transcript (NDJSON). Main artifact, can be 500 KB–16 MB. | sessionId + project | Yes — deleting stops --resume from working for that session. No effect on other sessions in same project. |
~/.claude/projects/<enc-path>/<sessionId>/subagents/ | Sub-agent JSONL transcripts + .meta.json files spawned during session. | sessionId | Yes — bundled with parent session, safe to delete together. |
~/.claude/projects/<enc-path>/<sessionId>/tool-results/ | Cached tool call results for session (not always present). | sessionId | Yes — ephemeral cache, safe to delete. |
~/.claude/file-history/<sessionId>/ | Versioned snapshots of files edited during session (undo history). Content-addressed hashes inside. | sessionId | Yes — only needed for /undo within the session. Deleting only affects that session’s undo history. |
~/.claude/todos/<sessionId>-agent-<agentId>.json | To-do list state for the session. | sessionId prefix | Yes — stale after session closes. |
~/.claude/tasks/<sessionId>/ | Task tracking JSON files for the session. | sessionId | Yes — stale after session closes. |
~/.claude/session-env/<sessionId>/ | Ephemeral env directory, always empty after session ends. | sessionId | Yes — empty, trivial to delete. |
Shared / global artifacts — DO NOT delete
| Path | Why not per-session |
|---|---|
~/.claude/projects/<enc-path>/memory/ | Project-scoped CLAUDE.md memory shared across all sessions for that project path. Delete only when purging the entire project. |
~/.claude/shell-snapshots/ | Global zsh snapshots, not tied to any session. |
~/.claude/history.jsonl | Global CLI input history. |
~/.claude/paste-cache/ | Content-addressed blobs, potentially shared. |
~/.claude/backups/ | Rolling .claude.json backups (auto-rotated, max 5). |
~/.claude/sessions/<pid>.json | PID registry for running processes — delete only if process is confirmed dead. |
~/.claude/settings.json, stats-cache.json, telemetry/, cache/ | Global config and stats. |
Server-side delete
No explicit per-session delete API exists. Anthropic’s Messages API neukládá perzistentní conversation state per-request — lokální .jsonl transcript je zdrojem pravdy a CLI ho re-posílá při resumování. Nicméně:
- Anthropic má vlastní 30-day retention na server-side artefaktech (logs, training opt-out data atd.) — data nejsou okamžitě zapomenuta.
- Lokální
~/.claude/artefakty Claude CLI také podléhají 30-day auto-cleanup mechanismu (CLI samo maže staré soubory). - Žádný explicit per-session delete API neexistuje. Otevřený community request: https://github.com/anthropics/claude-code/issues/24126
Confirmed: claude --help has no --delete-session or similar flag. The only relevant CLI command is:
claude project purge [path] # deletes projects/<enc-path>/ dir, tasks/, file-history/ for that path
claude project purge --all # purges all projects
claude project purge --dry-run # preview without deleting
project purge covers: project transcripts (all sessions), tasks, file-history, config entry in .claude.json. It does NOT delete todos or session-env (those are tiny and self-clean).
Sessions are referenced via --resume <sessionId> which simply re-opens the .jsonl file. No remote lookup.
Recommended cleanup procedure for closeConversation(projectId, sessionId, projectWorkspacePath)
Given we have (sessionId: UUID, projectWorkspacePath: String):
-
Delete conversation transcript:
rm -f ~/.claude/projects/<encode(projectWorkspacePath)>/<sessionId>.jsonl -
Delete per-session subdirectory (subagents, tool-results):
rm -rf ~/.claude/projects/<encode(projectWorkspacePath)>/<sessionId>/ -
Delete file-history for session:
rm -rf ~/.claude/file-history/<sessionId>/ -
Delete todos for session:
rm -f ~/.claude/todos/<sessionId>-agent-*.json -
Delete tasks for session:
rm -rf ~/.claude/tasks/<sessionId>/ -
Delete session-env dir (empty but tidy):
rm -rf ~/.claude/session-env/<sessionId>/ -
If closing the entire project (all conversations): use
claude project purge --yes <projectWorkspacePath>— this is the official CLI command and handles the project directory atomically, including thememory/folder and.claude.jsonconfig entry.
Path encoding: Replace every / in the absolute path with -. The encoded name starts with - (because the path starts with /).
Example: /Users/mirek/Work/foo → -Users-mirek-Work-foo
Session registry (~/.claude/sessions/<pid>.json): Only present for running sessions. No cleanup needed on conversation close — the CLI removes it when the process exits.
Why we still clean up explicitly
Even though Claude CLI auto-cleans local artifacts after 30 days and Anthropic enforces 30-day retention server-side, TalkIDE still performs explicit cleanup on conversation close because:
- Privacy-sensitive data — explicit close (user clicks “End conversation”) should remove the transcript immediately, not wait 30 days. Real incident driver: fiscal/PII data leaking into a session and the user wants it gone now.
- DB synchronization — TalkIDE’s
conversationtable is the source of truth for our app, separate from Claude’s local files. Our scheduler closes staleconversationrows so the app state stays consistent regardless of CLI’s own cleanup. - In-memory state —
ClaudeCliServicekeeps in-memory maps (parent refs, tool tracking) that need explicit teardown viastopProcess().
Reference for future explicit-delete API: https://github.com/anthropics/claude-code/issues/24126
Open questions / risks
todos/naming pattern: Files use<sessionId>-agent-<agentId>.json. TheagentIdcan be the same as the sessionId (main agent) or a short hash (sub-agent). Glob<sessionId>-agent-*.jsonto catch all variants. Verify the glob doesn’t accidentally match other sessions with a shared prefix (UUIDs are unique, so prefix collision is negligible but use exact UUID match:<sessionId>-agent-not just<sessionId>).paste-cache/: Content-addressed, potentially shared across sessions. Do not delete per-session — it compresses naturally over time. No known cleanup mechanism.backups/: Contains.claude.json.backup.*files with project config entries. These auto-rotate (max 5 kept). Afterproject purge, old backups may still reference the purged project’s config. This is benign — the config entry is just permissions/onboarding flags, not conversation data.file-history/cross-session sharing: Content-addressed hashes inside session dirs could theoretically be referenced from another session if the same file version appears. In practice each session dir is independent. Safe to delete.- No official per-session delete command: We must delete files directly. This is stable as long as Claude CLI doesn’t change its storage layout — which it has in the past. Pin CLI version in TalkIDE’s deployment to avoid surprises.
FEEDBACK
The main missing piece was documentation — Anthropic publishes no official spec for the ~/.claude/ directory layout, so everything above is derived by inspection. A claude session list or claude session delete <id> command would have made Q2 trivial. It would also have been useful to have the Claude CLI source (it’s a compiled binary) or changelog to know which dirs are guaranteed stable vs. internal implementation details.
Thanks for the feedback.