Move per-session runtime state out of workspace `.claude/` into `~/.claude/projects/<encoded>/`
Summary
Claude Code drops per-session runtime state files into the workspace's .claude/ directory (e.g. .claude/scheduled_tasks.lock). Because .claude/ is also where users keep shared, committed project config (settings.json, agents/, commands/, skills/, hooks/), every Claude Code user ends up needing fine-grained gitignore entries to avoid accidentally committing machine/session-specific lockfiles.
This feels inconsistent with Claude Code's own conventions: project-scoped state like the auto-memory store already lives under ~/.claude/projects/<encoded-workspace-path>/.... Moving the scheduler lock (and any future ephemeral state) next to it would solve the problem without users needing to know about it.
Concrete example
After running /rev5 (a personal skill that uses ScheduleWakeup), the workspace gains:
.claude/scheduled_tasks.lock
Contents are intrinsically per-machine:
{"sessionId":"...","pid":92776,"procStart":"Tue Apr 28 18:34:21 2026","acquiredAt":1777409137527}
Two failure modes:
- Accidental commit —
git add .from a developer who's not paying attention bakes a stalesessionId/PID into the repo. Anyone who later checks out the repo could have a Claude Code session think the lock is held by a process that doesn't exist. - Gitignore tax — every project that uses Claude Code has to figure out the right surgical gitignore (a blanket
/.claude/over-ignores the shared config; you have to enumerate each runtime path). This is a paper cut that scales linearly with the number of repos a user works in.
Proposed fix
Store ephemeral, per-session state under ~/.claude/projects/<encoded-workspace-path>/ alongside the existing memory directory. The encoded-path scheme already in use (e.g. ~/.claude/projects/-Users-gigi-git-prplx-space/memory/) gives you the per-workspace key without polluting the workspace itself.
Files I'd expect to move:
scheduled_tasks.lock(and any pending-task state forScheduleWakeup/CronCreate)- Anything else currently written into workspace
.claude/that isn't user-authored config
Files that should stay in workspace .claude/:
settings.json(shared project settings)settings.local.json(per-developer overrides — already gitignored by convention)agents/,commands/,skills/,hooks/— explicitly-authored project assets
Why this matters
The user-facing fix is one-line gitignore entries per repo, but the upstream fix is a one-time path change in Claude Code that benefits every user forever. Strongly preferred to externalize this paper cut once rather than have N teams each rediscover and document it.
Environment
- Claude Code: latest (Opus 4.7 1M)
- macOS Darwin 24.5.0
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗