Skip to content

Review Claude Code config syncing #6

@rowan

Description

@rowan

Context

Claude Code stores its config under ~/.claude/. The dotfiles currently handle this via apps/claude/install.zsh, which copies CLAUDE.md and skills/ from the repo on first setup and never touches them again (previous symlink-based approach was explicitly migrated to copies).

This works for a single machine but creates friction when syncing config between my Mac Studio and Mac Air laptop.

What lives in ~/.claude/

Path Contents Currently managed?
CLAUDE.md Global user instructions (master prompt) Seeded once from apps/claude/CLAUDE.md, never re-synced
skills/ User-defined skills Seeded once from apps/claude/skills/, never re-synced
settings.json Hooks, permissions, env vars, enabled plugins Not managed at all
plugins/ Plugins installed via claude plugin install Re-installed on every dot run
projects/, sessions/, history.jsonl, todos/, tasks/, cache/, debug/ Per-machine session state, transcripts, memory Should stay local

Problem

  1. No round-trip: edits to ~/.claude/CLAUDE.md on the Studio don't flow back to the repo, so the Air never sees them.
  2. Source drift: if I improve apps/claude/CLAUDE.md in the repo, machines that already ran install.zsh don't pick it up.
  3. settings.json is unmanaged: enabled plugins, hooks, and permission preferences live only on whichever machine I set them on.
  4. Skills: same issue as CLAUDE.md — personal edits don't sync.

Things to decide

  • What's shared vs per-machine?
    • Shared: CLAUDE.md, skills/, settings.json (probably)
    • Per-machine: session state, history, caches, plugin cache, logs
  • Sync strategy options:
    1. Symlink approach (revert to pre-migration behaviour): live files point to the repo, edits are committed. Risk: Claude Code may write to some of these files (e.g. memory), causing noisy git diffs.
    2. Copy + manual sync: keep copies, add a dot claude-sync command to push local changes back to the repo for committing.
    3. Two-way sync via iCloud / Dropbox: mount ~/.claude/CLAUDE.md etc. from shared storage. Simpler but opaque to git history.
    4. Hybrid: symlink static files (CLAUDE.md, skills/, settings.json), keep dynamic ones (projects/, history.jsonl) local.
  • Memory files: auto-memory writes to ~/.claude/projects/*/memory/. These are per-project and per-machine — probably should stay local, but worth confirming.
  • Plugins: currently re-installed every dot run — is that the intended behaviour, or should we track installed plugins in a manifest file checked into the repo?

Proposed next step

Before implementing anything, agree on the scope:

  • Which files sync across machines?
  • Symlinks vs copy+sync script vs hybrid?
  • Does settings.json need secrets handling (it currently doesn't contain any, but future hooks might)?

Related

  • apps/claude/install.zsh — current setup logic
  • apps/claude/CLAUDE.md — repo source-of-truth for global prompt
  • apps/claude/skills/ — repo source-of-truth for skills

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions