Project Sync
Sync the durable subset of a project's gitignored .project/ folder across your own
devices, via the orphan branch claude/state. Backlog, dashboard, seed, learnings,
archive, and feature dossiers travel with the repo without ever being tracked on a
working branch — Model A stays intact.
All procedures live in .claude/skills/shared/STATE-SYNC.md; this skill wires them to
the push / pull / status modes and reports the result.
Trigger
/project-sync [push|pull|status] — no argument → mode is chosen in PHASE 1.
Platform
Detect platform: Windows ($PSVersionTable exists) → PowerShell; macOS/Linux →
bash. Command variants for both OSes are in shared/STATE-SYNC.md.
Process
PHASE 0: Pre-flight
Follow shared/STATE-SYNC-PUSH.md § Preflight & temp-worktree hygiene. Concretely:
- Main-checkout gate — compute
main_root/current_root. Ifcurrent_root != main_root→ exit: "project-sync only runs on the main checkout. You are in worktree{current_root}. RunExitWorktree(action: keep)first, then retry." (Worktree.project/is symlinks back to main.) - Repo + remote — inside a git repo with a non-empty
git remote; else exit: "state sync requires a git remote." .project/exists — else exit: "no.project/to sync — run/core-setupfirst."- Hygiene —
git worktree prune; remove any dangling$STATE_WT. - Branch resolution — per
shared/STATE-SYNC.md § 2. Ifproject.json#team.mode == "team"and no branch is recorded in.project/session/state-sync.json, and the mode (PHASE 1) ispush→ AskUserQuestion for the branch name (first optionclaude/state-{user}= recommended). Persist the choice.
PHASE 1: Mode dispatch
Argument push / pull / status. No argument → AskUserQuestion:
- "Status (Recommended)" — show what would sync, change nothing
- "Push" — send local durable state to the state branch
- "Pull" — bring remote state into this device
PHASE 2: Execute
- status —
git fetch origin "$STATE_BRANCH"; show the resolved branch, remote SHA vsstate-sync.json#lastSyncedSha, local drift (thecollect-into-LAST-worktree check fromSTATE-SYNC.md § 7, reported as a changed-file count), and last push/pull timestamps. No writes. - push — follow
shared/STATE-SYNC-PUSH.md § Push procedure(incl. first-time orphan and push-rejected retry). Updatestate-sync.json. - pull — follow
shared/STATE-SYNC.md § 7(Pull procedure & conflict matrix). Updatestate-sync.json.
PHASE 3: Report
ASCII table:
STATE SYNC ─ {mode}
───────────────────────────────────────────
Branch claude/state[-user]
Remote SHA {shortsha} (was {last shortsha})
Pushed {n} file(s) | —
Pulled {n} file(s) | —
Merged {n} file(s) | —
Conflicts {n resolved} | —
lastSyncedSha {shortsha}
───────────────────────────────────────────
Fill only the rows relevant to the mode (status shows drift counts, no SHA change).