AI Setup Sync

One repo. Every project. Always in sync.
Every AI coding tool needs its own config files in every repo. AI Setup Sync keeps one GitHub repo
as the source of truth and pulls them into every project automatically: agents, skills, commands,
MCP configs, and anything else your tools read.
Claude Code, GitHub Copilot, Cursor, Codex, Antigravity — and anything else that reads config from
your project. No copy-pasting.
How it works
Put your shared AI config files in one GitHub repo (.claude/, CLAUDE.md,
.github/copilot-instructions.md, .cursor/rules/, …). Point the extension at that repo, and it
pulls the latest files into each project on open and window focus.
Sync flows one way: repo → projects. You can still edit files locally — the extension detects
those edits and lets you choose what to keep, so no work is ever silently overwritten.
Features
- Your AI setup never touches a client's codebase — agents, skills, commands, MCP configs, and anything else your tools read stay in your own setup repository. Synced files are added to
.git/info/exclude, so they never show up in the project's pending changes.
- Syncs automatically — pulls from your GitHub repo on project open and window focus. No manual steps.
- Works with any file-based AI config — Claude Code, Copilot, Cursor, Codex, and Antigravity out of the box. Path mappings translate any repo path to the local path a tool expects (e.g.
Claude/ → .claude/), or map a whole subfolder to your project root.
- Never loses your work — local edits are detected and prompted per file, with a built-in diff, before anything is overwritten. Deletions propagate the same way: silently when a file is untouched, with a prompt when you've edited it.
- Works across parallel agent sessions — synced configs are automatically available in every Claude Code and Codex worktree, so AI tools have your setup no matter which isolated session they run in.
- Supports private, SSO, and Enterprise Server repos — GitHub token stored securely in the OS keychain (VS Code SecretStorage).
- Runs your build step — an optional post-sync command turns synced templates into finished configs (generate, inject secrets, merge), only in trusted workspaces.
Requirements
- VS Code 1.125 or later.
- A GitHub repository containing your shared AI setup files — personal or org, public or private, including SAML SSO orgs and repos hosted on GitHub Enterprise Server.
- For private, SSO-protected, or Enterprise Server repos: a GitHub classic personal access token with the
repo scope.
Quick start
- Install AI Setup Sync from the VS Code Marketplace (or the Install button on this page).
- Set
aiSetupSync.repository to your GitHub repository URL in VS Code user settings.
- Open a project — sync runs automatically.
That's it for public repos. For private repos, SSO-protected orgs, or Enterprise Server, add a token (see below).
New here? Open a project before configuring anything and AI Setup Sync prompts you, with a shortcut to the repository setting.
Contents
Everything below is reference — jump to what you need:
Setting up your repository
The extension syncs from any GitHub repository you can read — your own, your org's, or any public
one. This section is the full version of Quick start; if you've already set
aiSetupSync.repository, skip to step 3.
1. Create a repository and add your setup files on your default branch (main or master).
Any combination of tools works — just place files where each tool expects them.
your-setup-repo/
├── CLAUDE.md # Claude Code root instructions
├── AGENTS.md # Cross-tool instructions (Antigravity, Cursor, Claude Code)
├── .claude/
│ ├── instructions/
│ │ └── coding-style.md
│ └── skills/
│ └── code-review/
│ └── SKILL.md
├── .github/
│ └── copilot-instructions.md # GitHub Copilot instructions
├── .cursor/
│ └── rules/
│ └── coding-style.mdc # Cursor rules
├── .cursorignore # Cursor: files the AI can't access
├── .agents/
│ └── skills/
│ └── code-review.md # Google Antigravity skills
├── .antigravity.md # Google Antigravity workspace context
└── .codex/
└── config.toml # OpenAI Codex config
2. Point the extension at it — set aiSetupSync.repository to your repository URL in VS Code
user settings.
3. Map paths if needed. If your repo organises files under different names (e.g. Claude/
instead of .claude/), configure aiSetupSync.pathMappings — keys are repo paths, values are
local destinations:
"aiSetupSync.pathMappings": {
"Claude": ".claude",
"Copilot": ".github",
"Cursor": ".cursor",
"Codex": ".codex"
}
Claude/instructions/style.md then syncs to .claude/instructions/style.md, and so on.
4. Add a token for private repos, SSO orgs, or Enterprise Server. Run AI Setup Sync: Set GitHub Token from the
command palette. Create a classic personal access token
with the repo scope (fine-grained tokens don't support this scope). For SAML SSO orgs, also
authorize it for your org (Settings → Personal access tokens → Configure SSO → Authorize).
5. Set the branch if it isn't main — set aiSetupSync.branch to match (e.g. master).
6. Push and you're done. Every project picks up the change the next time it's opened or refocused.
Shared vs project-specific files: Add shared instructions to the central repo and open a PR —
on merge they sync to every project. Keep project-specific files in your project repo; the
extension only touches files it synced and leaves everything else alone.
Default synced paths
By default, the extension syncs these paths from the main branch (configurable via
aiSetupSync.branch). .cursorrules is not included — use .cursor/rules/ instead.
| Path |
Tool |
.claude |
Claude Code |
CLAUDE.md |
Claude Code |
.mcp.json |
Claude Code (project-scoped MCP servers) |
.github |
GitHub Copilot |
.vscode/mcp.json |
GitHub Copilot / VS Code (MCP servers) |
.cursor |
Cursor |
.cursorignore |
Cursor (blocks AI access) |
.cursorindexingignore |
Cursor (excludes from indexing) |
.agents |
Google Antigravity |
AGENTS.md |
Google Antigravity (also read by Cursor and Claude Code) |
.antigravity.md |
Google Antigravity (Antigravity-specific context) |
.codex |
OpenAI Codex |
Configure via aiSetupSync.targetFolders — toggle defaults on or off, or add custom paths.
Settings
| Setting |
Default |
Purpose |
aiSetupSync.repository |
(required) |
GitHub repository URL to sync from, e.g. https://github.com/your-org/your-repo. GitHub Enterprise Server is also supported (e.g. https://github.company.com/your-org/your-repo). Private repos, SAML SSO orgs, and Enterprise Server repos need a token — see Setting up your repository. Set in workspace settings, it's only used in trusted workspaces; set it in user settings to sync regardless of trust. |
aiSetupSync.branch |
main |
Branch to sync from. Set to master or any other branch if your repo uses a different default. Like repository, a workspace-level value is only honored in trusted workspaces. |
aiSetupSync.targetFolders |
(see above) |
Files and folders to sync from the repo root. Each entry can be toggled on or off — set to false to disable a default without removing it. Add entries for any tool that reads config from your project. |
aiSetupSync.pathMappings |
{} |
Rename paths as files sync from the repo to your project. "Claude": ".claude" rewrites Claude/instructions/style.md → .claude/instructions/style.md. Use "/" to map a subfolder to your project root: "projectA": "/" syncs projectA/.github/ as .github/. See Path mappings and multi-project repos for how overlaps are resolved. |
aiSetupSync.postSyncCommand |
(empty) |
Shell command to run after a sync changes files — e.g. generate configs from synced templates. Runs only in trusted workspaces. See Post-sync command. |
Multi-root workspaces — every folder syncs, each with its own conflict tracking and its own
.git/info/exclude, and a failure in one folder doesn't stop the others. repository, branch,
targetFolders, and pathMappings apply to the whole window, so every folder syncs from the same
repository — you can't point one folder at a different repo. postSyncCommand is the exception:
set it per folder, and each command runs in the folder it's configured for.
Path mappings and multi-project repos
Path mappings rewrite a repo path to a different local path as files sync. Reach for them when your
repo's layout doesn't match what your tools expect at the project root — for example, when setup
files live under per-project or per-platform subfolders, or under names like Claude/ instead of
.claude/.
Which pattern do you want?
Map a whole subfolder to the workspace root
Set the mapping value to "/" to strip a subfolder prefix and sync everything inside it straight to
your project root. This is the simplest setup when one repo subfolder holds a project's whole AI setup:
Example repo layout:
your-setup-repo/
├── .github/ # shared across all projects
└── projectA/
├── .github/ # projectA-specific agents and instructions
├── .claude/
└── .cursor/
Config:
"aiSetupSync.pathMappings": {
"projectA": "/"
}
Every file under projectA/ syncs to the workspace root with its prefix stripped:
| Repo path |
Local path |
projectA/.github/agents/coding.md |
.github/agents/coding.md |
projectA/.claude/commands/foo.md |
.claude/commands/foo.md |
projectA/.cursor/rules/style.mdc |
.cursor/rules/style.mdc |
Merging root files with the subfolder
If both the root .github/ and projectA/.github/ exist in the repo, files from both land in your
local .github/. Differently named files simply merge together. If the same file exists in both, the
mapped subfolder wins — projectA/.github/agents/coding.md overrides the root
.github/agents/coding.md.
To sync only specific root folders alongside the subfolder — for example .github from the root but
nothing else — disable the defaults you don't need:
"aiSetupSync.targetFolders": {
".claude": false,
".cursor": false,
".agents": false
},
"aiSetupSync.pathMappings": {
"projectA": "/"
}
Map individual subpaths
For finer control — or when different projects share the same repo and each needs only its own
folder — map specific subpaths instead of the whole project folder:
Example repo layout:
your-setup-repo/
├── PlatformA/
│ ├── .claude/
│ ├── CLAUDE.md
│ └── .github/
└── PlatformB/
├── .claude/
├── CLAUDE.md
└── .github/
Fetching .claude and CLAUDE.md from PlatformA:
"aiSetupSync.pathMappings": {
"PlatformA/.claude": ".claude",
"PlatformA/CLAUDE.md": "CLAUDE.md"
}
PlatformA/.claude/ and everything inside → .claude/ locally
PlatformA/CLAUDE.md → CLAUDE.md locally
PlatformA/.github/, PlatformB/, and everything else → ignored (no mapping defined)
If your repo also has shared files at the root (e.g. a common .claude/ alongside the
per-platform folders), they'll be synced too because targetFolders includes .claude by default.
To prevent that, disable the root-level entries:
"aiSetupSync.targetFolders": {
".claude": false,
"CLAUDE.md": false
},
"aiSetupSync.pathMappings": {
"PlatformA/.claude": ".claude",
"PlatformA/CLAUDE.md": "CLAUDE.md"
}
To switch platforms, update the mapping keys (e.g. replace PlatformA with PlatformB). Everything
else stays the same.
How overlaps are resolved
When more than one rule could apply to the same file, the outcome is always predictable:
A mapping and a target folder point at the same file → the mapping wins. (Example: a root
.github/agents/coding.md from a target folder and a projectA/.github/agents/coding.md mapped to
.github/ — the mapped one is kept.)
Two mapping keys match the same file → the more specific key wins (the one that matches more of
the path). This lets a nested key override a broader one:
"aiSetupSync.pathMappings": {
"projectA": "/",
"projectA/.github": "archive/.github"
}
Here projectA/.github/agents/coding.md follows the more specific projectA/.github rule and syncs
to archive/.github/agents/coding.md, while everything else under projectA/ falls back to the
broader "/" rule and syncs to your project root.
In every case each repo file syncs to exactly one local path — overlapping rules never produce
duplicate copies.
Post-sync command
When synced files need a build step — rendering a template, injecting secrets, merging a fragment —
aiSetupSync.postSyncCommand runs a shell command after a sync changes files:
"aiSetupSync.postSyncCommand": "npm run generate"
- Runs once the whole sync finishes, only in trusted workspaces — a cloned repo can't run code just because you opened it.
- Asks before running a changed command — if it differs from the one you last approved (say a
git pull swapped it), you're shown the command in a dismissible notification and it runs only when you click Run. An unchanged command runs without prompting.
- Skips no-op syncs, has a 2-minute timeout, and logs its output to the AI Setup Sync channel.
- You get a brief notification when it finishes, or an error toast (Show Log / Open Settings) if it fails — the sync itself still succeeds either way. A failure also shows a status-bar warning that stays until the command succeeds; run Sync Now to retry it.
- Run it on demand — Run Post Sync Command (status-bar menu or Command Palette) runs it without waiting for a sync.
- Runs in your platform's shell —
cmd.exe on Windows, sh on macOS/Linux — so prefer cross-platform commands like npm run generate over shell-specific syntax.
Leave it empty to disable. Two things to keep in mind:
- Don't write into synced paths — the next sync would treat those files as locally edited.
- Its output goes to the log, exactly like a terminal — so keep secrets in files (
op inject, sops, envsubst), not echoed to stdout.
Conflict handling
On each sync the extension compares file content against what it last wrote:
Unmodified → updated silently.
Deleted locally → re-added automatically.
Edited locally → you're prompted to choose:
| Choice |
Effect |
| Overwrite all |
Replace with the repo version. (Shown when multiple files conflict; a single file goes straight to the per-file dialog.) |
| Keep mine |
Leave your edits; won't re-prompt as long as your local version and the upstream file both stay unchanged. |
| Review each |
Decide file by file — each dialog has a Show diff button to compare local vs. repository. |
| Escape / close |
Re-prompts on the next sync. |
Files removed from the repo or excluded by a settings change (e.g. you toggled a folder
off in targetFolders, changed a pathMappings key, or changed its destination path) are deleted
from your project on the next sync. Unmodified files are removed silently; locally-edited files
prompt you before deletion (Escape re-prompts next sync). Directories that become empty after
deletions are removed automatically.
Status bar
Look for AI Setup Sync in the status bar (bottom-right of the VS Code window). It shows sync
state at a glance; click it to open the action menu (Sync Now, Show Log, Open Settings, Remove
Synced Files, Set GitHub Token). Sync Now is the first item, so a click + Enter syncs immediately.
| Indicator |
Meaning |
✓ AI Setup Sync |
Up to date — last sync completed successfully. |
⟳ AI Setup Sync |
Sync in progress. |
⚠ AI Setup Sync |
Sync failed — hover to see the error, click for the action menu. |
⚙ AI Setup Sync |
No repository configured — click for the action menu. |
When a sync downloads files, a progress notification with a bar and a live "Syncing X of Y
files" count appears — only while files are actually being transferred, so routine no-op syncs
stay silent.
Commands
Every action is available from the status-bar action menu and from the command palette
(Ctrl+Shift+P / Cmd+Shift+P) under the AI Setup Sync category.
| Action |
Description |
| Sync Now |
Sync immediately. |
| Run Post Sync Command |
Run the configured post-sync command without waiting for a sync. The status-bar menu lists it only when one is configured. |
| Show Log |
Open the AI Setup Sync output channel. |
| Open Settings |
Open the extension's settings. |
| Remove Synced Files |
Delete synced files from the project (local edits are preserved). |
| Set GitHub Token |
Securely store a GitHub PAT in the OS keychain — needed for private, SAML SSO, and Enterprise Server repos. See Setting up your repository for token requirements. Submit empty to clear. |
Activity is logged to the AI Setup Sync output channel (Output panel → dropdown, or Show
Log from the menu).
How files stay out of git
Synced files are automatically added to .git/info/exclude (per-clone, never committed) so they
don't show up as pending changes. Only the exact synced files are excluded — anything you create
yourself in the same folders (e.g. a project-specific skill) stays visible to git and committable
normally.
If you edit a synced file locally, the extension detects the change on save and removes it from
the exclude list immediately — the file surfaces in Source Control and git status without any
manual step. The next time you sync, you'll be prompted to keep your edits or take the repo
version; taking the repo version puts the file back into the exclude list, while keeping your
edits leaves it visible so the drift stays inspectable.
Parallel agent sessions (worktrees)
Claude Code and OpenAI Codex can run tasks in isolated copies of your repo called
git worktrees — for example, fixing a bug in one terminal
while building a feature in another. Each worktree is a fresh checkout, so synced files wouldn't
normally be there.
AI Setup Sync handles this automatically by maintaining a .worktreeinclude file at your workspace
root. Both tools read it when creating a worktree and copy any matching gitignored files across, so
your AI configs are present in every session without any extra steps.
The patterns mirror your sync configuration:
- Folder targets (e.g.
.claude, .github) copy the whole folder — including files added to
the repo after the last sync.
- File targets (e.g.
CLAUDE.md, AGENTS.md) copy the exact file.
- Path mappings use the local destination, file or folder (e.g.
"Claude": ".claude" copies
the whole .claude/ folder; "src/config.json": ".cursor/config.json" copies just that file).
.worktreeinclude itself is excluded from git tracking so it never appears as an untracked file.
Removing synced files
Run Remove Synced Files before uninstalling for an immediate cleanup — it confirms first, so
it can't fire by accident. The extension also runs a cleanup hook on uninstall, but that fires only
after a full VS Code restart.
Only files whose content matches what the extension last wrote are removed — files you edited
locally are kept so no work is lost. If any files are kept, a warning toast appears with a
Show Log button that lists them in the AI Setup Sync output channel.
Cleanup also strips the managed block from .git/info/exclude and removes .worktreeinclude, so
once nothing is synced no trace of the extension is left in your repository.
FAQ
When does it sync?
Automatically: when you open a project, when you return focus to the VS Code window (at most once
every 10 minutes, so alt-tabbing doesn't re-sync), and shortly after you change a relevant setting
or set a GitHub token. Sync Now — from the status-bar action menu or the command palette —
syncs on demand and ignores the throttle. There's no schedule to configure; it just stays current
at the moments you're working.
Does it ever modify files I created myself?
No. The extension only touches files it synced from the repo. Anything else in your project is left
untouched and stays visible to git.
Is syncing two-way?
No — it's one-way, repo → projects. Local edits aren't pushed back; instead they're detected and you
choose whether to keep them or take the repo version.
Why does it need a classic token and not a fine-grained one?
Fine-grained personal access tokens don't support the repo scope this extension relies on. Use a
classic token with the repo scope.
Where is my token stored?
In the OS keychain via VS Code's SecretStorage — never in settings, files, or the repo.
Can I sync from a private, SSO-protected, or GitHub Enterprise Server repo?
Yes to all three — each needs a GitHub token; see
Setting up your repository. For Enterprise Server, set
aiSetupSync.repository to the full server URL (e.g. https://github.company.com/your-org/your-repo).
Will it work across a whole team?
That's the point. Everyone installs the extension and points at the same repo; merge a change and it
reaches every project on the next sync.
Support
Bug reports, questions, and feature requests go to
GitHub Issues. Include your extension and VS
Code versions plus the relevant output from the AI Setup Sync channel (Output panel →
dropdown) — it logs every decision the sync made, and it never logs your token.
License
MIT