Configuration
ai-rules-sync.json serves two different roles depending on where it is placed:
| Location | Path | Role | Key Fields |
|---|---|---|---|
| Rules Repository (provider) | ./ai-rules-sync.json (repo root) | Defines how rules are organized in the repo | version, sourceDir, rootPath |
| Project (consumer) | ./ai-rules-sync.json (project root) | Records which rules to sync from which repos | version, tool.subtype entries |
Additional config files:
| File | Path | Purpose |
|---|---|---|
ai-rules-sync.local.json | Project root | Private rules (not committed, auto-added to .gitignore) |
user.json | ~/.config/ai-rules-sync/user.json | User-level config (applies to all projects) |
TIP
Most users never edit these files directly — the CLI (ais add, ais rm, etc.) manages them. Edit manually only for advanced cases: aliases, custom targetDir, or custom sourceDir in rules repos.
Schema Version
All config files include a version field for forward compatibility:
{
"version": 1
}AIS automatically migrates legacy configs (without version) on read.
Rules Repository Config (Provider)
Placed in the rules repository root. Tells AIS where to find rules within this repo.
When to customize: Only needed when your rules are not in the default locations (e.g., .cursor/rules, .claude/skills). Run ais init to create a repo with default structure — no custom config required.
Basic Structure
{
"version": 1,
"rootPath": "src",
"sourceDir": {
"<tool>": {
"<subtype>": "<path>"
}
}
}Fields
| Field | Type | Description |
|---|---|---|
version | number | Config schema version (currently 1) |
rootPath | string? | Optional path prefix applied to all source directories |
sourceDir | object | Maps tool → subtype → source path |
Example
{
"version": 1,
"rootPath": "src",
"sourceDir": {
"cursor": {
"rules": ".cursor/rules",
"commands": ".cursor/commands",
"skills": ".cursor/skills",
"agents": ".cursor/agents"
},
"copilot": {
"instructions": ".github/instructions"
},
"claude": {
"skills": ".claude/skills",
"rules": ".claude/rules",
"md": ".claude"
}
}
}With rootPath: "src", the actual path for Cursor rules resolves to src/.cursor/rules.
Wildcard (*) Fallback
Use * as a tool key to define shared config that applies to all tools when tool-specific config is missing. Useful for subtypes like skills that are identical across Cursor, Copilot, Claude, etc.
{
"version": 1,
"rootPath": "src",
"sourceDir": {
"*": {
"skills": "common/skills"
},
"cursor": {
"rules": ".cursor/rules"
}
}
}cursor.skills,copilot.skills,claude.skills, etc. all resolve tocommon/skillswhen not explicitly defined- Tool-specific config (e.g.
cursor.rules) takes precedence over*
Source Path Modes
Source paths can be a simple string or an object with a mode discriminant for advanced mapping:
Simple String
"rules": ".cursor/rules"File Mode
Map a specific source file to a different target filename:
"claude": {
"md": {
"mode": "file",
"dir": "common",
"sourceFile": "AGENTS.md",
"targetFile": "CLAUDE.md"
}
}This maps common/AGENTS.md in the repo → CLAUDE.md in the project.
Directory Mode
Map a source directory to a different target directory name:
"cursor": {
"rules": {
"mode": "directory",
"dir": "common",
"sourceDir": "shared-rules",
"targetName": "cursor-rules"
}
}This maps common/shared-rules/ in the repo → .cursor/rules/cursor-rules/ in the project.
Project Config (Consumer)
Placed in the project root. Records dependencies on rules from remote repositories.
Basic Structure
{
"version": 1,
"<tool>": {
"<subtype>": {
"<entry-name>": "<repo-url>" | { "url": "...", ... }
}
}
}Wildcard (*) Fallback
Use * as a tool key to define shared dependencies that apply to all tools when tool-specific config is missing:
{
"version": 1,
"*": {
"skills": {
"shared-skill": "https://example.com/skills.git"
}
},
"cursor": {
"rules": {
"my-rule": "https://example.com/rules.git"
}
}
}cursor skills,copilot skills, etc. all seeshared-skillwhen their ownskillssection is empty- Tool-specific entries take precedence; add/remove uses the adapter's config path, with fallback to
*for remove
Example
{
"version": 1,
"cursor": {
"rules": {
"react": "https://github.com/user/repo.git",
"react-v2": {
"url": "https://github.com/user/another-repo.git",
"rule": "react"
}
},
"commands": { "deploy-docs": "https://github.com/user/repo.git" },
"skills": { "code-review": "https://github.com/user/repo.git" },
"agents": { "code-analyzer": "https://github.com/user/repo.git" }
},
"claude": {
"rules": { "general": "https://github.com/user/repo.git" },
"skills": { "code-review": "https://github.com/user/repo.git" },
"agents": { "debugger": "https://github.com/user/repo.git" },
"md": { "CLAUDE": "https://github.com/user/repo.git" }
},
"agentsMd": {
"file": { "AGENTS": "https://github.com/user/repo.git" }
}
}All tools (copilot, trae, opencode, codex, gemini, warp, windsurf, cline) follow the same tool → subtype → entries structure.
Entry Formats
| Format | When to use | Example |
|---|---|---|
| String | Same name in project and repo | "react": "https://github.com/user/repo.git" |
Object with rule | Different local name (alias) | "react-v2": { "url": "...", "rule": "react" } |
Object with targetDir | Custom symlink location | "docs-rule": { "url": "...", "targetDir": "docs/ai/rules" } |
Simple string — just the repo URL
"react": "https://github.com/user/repo.git"Object with alias — different name in project vs repo
"react-v2": {
"url": "https://github.com/user/repo.git",
"rule": "react"
}react-v2 is the local name; react is the name in the rules repo.
Object with custom target directory
"docs-rule": {
"url": "https://github.com/user/repo.git",
"targetDir": "docs/ai/rules"
}Override where the symlink is placed in the project.
Local/Private Rules
Use ai-rules-sync.local.json for rules you don't want to commit:
ais cursor add company-secrets --local- Same structure as
ai-rules-sync.json - Automatically added to
.gitignore - Merges with main config (local takes precedence on conflict)
User-Level Config (user.json)
Global rules applied to all projects. Stored at
~/.config/ai-rules-sync/user.json.
Same tool → subtype → entries structure:
{
"version": 1,
"claude": {
"md": { "CLAUDE": "https://github.com/me/my-rules.git" }
},
"gemini": {
"md": { "GEMINI": "https://github.com/me/my-rules.git" }
}
}Manage the user config path:
ais config user show
ais config user set ~/dotfiles/ai-rules-sync/user.json
ais config user resetConfig Priority
When multiple configs exist, they merge with this priority (highest first):
ai-rules-sync.local.json— private, per-projectai-rules-sync.json— shared, per-projectuser.json— global, per-user