Install
$ agentstack add skill-veekunth217-claude-scaffold-skill-sync ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Context Sync — Cross-Device + Cross-Tool
Two problems, one canonical source of truth:
- Cross-device — Claude Code identifies projects by a hash of the absolute path, so context is lost between machines (
/home/alice/myapp→-home-alice-myapp≠/Users/john/myapp→-Users-john-myapp). Solved byexport/import.
- Cross-tool — You use Claude Code, Cursor, Codex CLI, Roo, Cline, Aider, or Windsurf — each has its own instruction/memory file (
CLAUDE.md,.cursorrules,AGENTS.md, ...). You re-explain your project to every one. Solved bytools push— one canonical memory file → adapter files for every detected tool.
The shared truth: .claude-context/MEMORY.md (+ memory/*.md), committed to git. Every tool reads from a locally-generated adapter file pointing at that truth. No SaaS. No proprietary memory broker. No vendor lock-in.
Commands
/sync export
Export current project context to .claude-context/ and commit.
Run:
python scripts/sync-export.py
What it does:
- Calculates the Claude path hash for the current directory
- Finds
~/.claude/projects//— reads all.mdcontext files - Copies them to
.claude-context/in the project - Creates
.claude-context/sync-manifest.jsonwith device metadata - Runs
git add .claude-context/ && git commit -m "context-sync: export " - Prints: push reminder
Then push:
git push
What gets exported:
MEMORY.md— your project memory indexmemory/*.md— individual memory filesproject_*.md,feedback_*.md,user_*.md,reference_*.md— all context docs
What stays private (never exported):
*.jsonl— conversation history (too large, private)*.json— may contain API keys or settings
/sync import
Restore project context on this device from .claude-context/.
Run:
python scripts/sync-import.py
What it does:
- Runs
git pullto get latest.claude-context/ - Reads the manifest to confirm what was exported
- Calculates the path hash for this device
- Creates
~/.claude/projects//if needed - Copies all files from
.claude-context/to the correct local target - Prints a summary of restored files
After import: restart Claude Code or open the project. Claude immediately has full context.
/sync status
Show what has changed between the exported context and the current local context.
Check manually:
# What's in the local Claude folder
ls -la ~/.claude/projects/$(python3 -c "import os; print(os.path.abspath('.').replace('/', '-').replace('\\\\', '-').replace(':', '-'))")/
# What's been exported
ls -la .claude-context/
# Diff a specific file
diff .claude-context/MEMORY.md ~/.claude/projects/$(python3 -c "import os; print(os.path.abspath('.').replace('/', '-').replace('\\\\', '-').replace(':', '-'))")/MEMORY.md
Or ask Claude directly to compare them and summarize what's new, changed, or missing.
/sync clean
Remove large files from the local Claude project folder to reduce size before export.
Run:
# Show what's in your Claude project folder
python3 -c "
import os
from pathlib import Path
key = os.path.abspath('.').replace('/', '-').replace('\\\\', '-').replace(':', '-')
folder = Path.home() / '.claude' / 'projects' / key
if folder.exists():
for f in sorted(folder.iterdir()):
print(f'{f.stat().st_size:>10,} {f.name}')
else:
print('No Claude project folder found')
"
# Remove conversation history (*.jsonl) to free space
python3 -c "
import os
from pathlib import Path
key = os.path.abspath('.').replace('/', '-').replace('\\\\', '-').replace(':', '-')
folder = Path.home() / '.claude' / 'projects' / key
removed = 0
for f in folder.glob('*.jsonl'):
size = f.stat().st_size
f.unlink()
print(f'Removed {f.name} ({size:,} bytes)')
removed += size
print(f'Freed {removed:,} bytes')
"
/sync tools detect
List which AI dev tools are present in this project — shows what tools push would write.
Run:
python scripts/sync-tools.py detect
Detection (no false positives — we only write where the tool already lives):
| Tool | Output adapter file | Detected by | |---|---|---| | Claude Code | CLAUDE.md | always written (universal) | | Cursor | .cursor/rules/memory.mdc | .cursor/ or .cursorrules exists | | Roo Code | .roo/rules/memory.md | .roo/ or .rooignore exists | | Cline | .clinerules/memory.md | .clinerules exists | | Codex CLI | AGENTS.md | .codex/ or AGENTS.md exists | | Aider | CONVENTIONS.md | .aider/, CONVENTIONS.md, or .aider.conf.yml | | Windsurf | .windsurfrules | .windsurfrules or .windsurf/ exists |
/sync tools push
Generate adapter files from .claude-context/MEMORY.md for every detected tool.
Run:
python scripts/sync-tools.py push # write them
python scripts/sync-tools.py push --dry-run # show diff without writing
python scripts/sync-tools.py push --only cursor,claude # subset
What it does:
- Assembles the canonical memory (
MEMORY.md+ everymemory/*.md) into one block - For each detected tool, wraps it in the right format (e.g. Cursor
.mdcgets YAML frontmatter) with a clear "AUTO-GENERATED" header pointing back to the source - Writes
.claude-context/sync-tools-manifest.jsonlisting what was written
Why this is better than commercial cross-AI memory tools (Vilix, Mem0):
- No SaaS subscription
- Memory lives in your git repo, not a third-party DB
- One canonical file you can
git blame, diff, and review like code - New devs run
python scripts/sync-tools.py pushaftergit clone— every AI tool they use immediately has the project context - When you update
.claude-context/MEMORY.md, re-run push and every adapter regenerates
Why most adapter files are gitignored: They're per-machine projections of the canonical source. Committing them would create merge conflicts every time someone with a different tool stack syncs. The source-of-truth (.claude-context/) is what's committed; the adapters are local rebuilds.
Phase 2 — live MCP sync (planned, contributions welcome): See [PHASE2-MCP.md](PHASE2-MCP.md) for the full spec. Adds a small MCP server alongside the file adapters so edits flow between tools without re-running push. Covers every MCP-capable tool (Claude Code, Cursor, Codex CLI, Windsurf, Roo, Cline). The file-based Phase 1 stays as the universal fallback and the source of truth.
How the Path Hash Works
Claude Code generates the project key from the absolute path:
abs_path = os.path.abspath('.')
# /home/alice/myapp
# → replace '/' with '-'
# → -home-alice-myapp
claude_key = abs_path.replace('/', '-').replace('\\', '-').replace(':', '-')
source = f"~/.claude/projects/{claude_key}/"
| Device | Path | Hash | |--------|------|------| | Linux VPS | /home/alice/myapp | -home-alice-myapp | | Mac | /Users/john/myapp | -Users-john-myapp | | Windows | C:\Users\john\myapp | -C--Users-john-myapp |
These are all the same project but Claude sees three different contexts. sync-import.py handles this automatically — it always installs to the correct hash for the current device, regardless of where it was exported from.
Full Cross-Device Workflow
Device A (VPS):
1. Open project in Claude Code
2. Work — Claude builds up memory, project context
3. /sync export → git push
Device B (Mac / laptop):
1. git clone (or git pull)
2. /sync import
3. Open project in Claude Code
4. Claude remembers everything from Device A
Keep in sync:
Device A: /sync export → git push (after significant sessions)
Device B: /sync import (after git pull)
Setup (one-time)
The .claude-context/ folder is already part of the repo (committed). The scripts are in scripts/. No dependencies — pure Python stdlib.
Make sure .claude-context/ is not in .gitignore (this is intentional — it's the sync mechanism). The *.jsonl exclusion in .gitignore prevents conversation history from being committed.
What Gets Synced
| File type | Synced | Why | |-----------|--------|-----| | MEMORY.md | ✅ | Project memory index | | memory/*.md | ✅ | Individual memory entries | | project_*.md | ✅ | Project context docs | | feedback_*.md | ✅ | Behavioral feedback | | user_*.md | ✅ | User profile context | | reference_*.md | ✅ | Reference links | | *.jsonl | ❌ | Conversation history — private, too large | | *.json | ❌ | Settings — may contain keys |
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: veekunth217
- Source: veekunth217/claude-scaffold-skill
- License: MIT
- Homepage: https://github.com/veekunth217/claude-scaffold-skill
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.