_______ ___ ___ __ ____ / __/ _ | / _ \/ _ \/ / / __/ _\ \/ __ |/ // / // / /__/ _/ /___/_/ |_/____/____/____/___/
One repo. One source of truth. Sync your AI tool configs everywhere.
Keep your agents, skills, commands, and configurations in sync across
Claude Code, Codex, Copilot, Cursor, Gemini, and OpenCode — on every machine.
# Clone and set up
git clone https://github.com/ndizazzo/saddle.git ~/dev/ai
cd ~/dev/ai && pnpm install
# Launch the interactive installer
npx saddle
# Or run non-interactively
npx saddle --yes --all # apply everything
npx saddle --dry-run --all # preview first
npx saddle --check # verify sync
npx saddle --uninstall # clean removalThe interactive TUI detects which AI tools are installed and walks you through linking skills, agents, commands, and config files for each.
| Tool | Home | Skills | Agents | Commands | Root File | Config Files |
|---|---|---|---|---|---|---|
| Claude Code | ~/.claude |
✓ | ✓ | ✓ | — | — |
| Codex | ~/.codex |
✓ | ✓ | ✓ | AGENTS.md |
— |
| Copilot | ~/.copilot |
✓ | ✓ | ✓ | — | — |
| Cursor | ~/.cursor |
✓ | ✓ | ✓ | — | — |
| Gemini | ~/.gemini |
✓ | ✓ | ✓ | GEMINI.md |
configurations/gemini/ → ~/.gemini/ |
| OpenCode | ~/.config/opencode |
✓ | ✓ | ✓ | AGENTS.md |
opencode/ → ~/.config/opencode/ |
Interactive TUI — A beautiful terminal interface built with Ink. Browse tools, preview diffs, toggle individual actions — all from your terminal.
Headless-ready — Full non-interactive mode for CI/CD. --dry-run, --yes, --all, --check — automate everything.
Smart Symlinks — Creates relative symlinks, detects existing content, shows diffs before replacing, and backs up what was there.
Lockfile Tracking — Know exactly what Saddle installed. Verify sync status with --check. Safely uninstall with --uninstall.
YAML Rules — Declarative per-tool rules define what gets linked where. Add new tools by writing a single YAML file.
Zero Config — Detects installed tools automatically. Grays out what's missing. Just run saddle and go.
1. Define — Keep agents, skills, commands, and configs in one canonical repo.
2. Detect — Saddle finds which AI tools are installed on your machine.
3. Link — Symlinks wire each tool to your canonical definitions. Done.
saddle/
├── agents/ # Per-tool instruction files and shared agent definitions
│ ├── codex/AGENTS.md
│ ├── gemini/GEMINI.md
│ └── opencode/AGENTS.md
├── commands/ # Slash command files → each tool's commands/
├── skills/ # Skill subdirectories → each tool's skills/
├── configurations/
│ └── gemini/ # Gemini-specific config → ~/.gemini/
├── opencode/ # OpenCode-specific config → ~/.config/opencode/
├── rules/ # Per-tool installer rules (YAML)
│ ├── claude.yaml
│ ├── codex.yaml
│ ├── copilot.yaml
│ ├── cursor.yaml
│ ├── gemini.yaml
│ └── opencode.yaml
└── scripts/ # Repo maintenance helpers
Keep the real files in this repo and rebuild tool-specific links on each machine. Do not sync ~/.claude, ~/.codex, ~/.cursor, ~/.gemini, ~/.copilot, or ~/.config/opencode symlinks directly between machines.
saddle [options]
| Flag | Description |
|---|---|
--dry-run |
Preview changes without writing to disk |
--yes |
Auto-confirm replacements without prompting |
--all |
Select every available profile |
--profile id1,id2 |
Apply specific profile IDs by name |
--list |
Print available profiles and exit |
--check |
Verify installed symlinks are in sync (exit 0 clean, 1 drift) |
--uninstall |
Remove symlinks recorded in lockfile |
--verbose |
Show extra detail (source paths, resolved targets) |
--quiet |
Suppress ok/link/skip/mkdir output; errors and summary only |
The TUI is built with Ink and @inkjs/ui. It presents selectable profiles grouped by tool, with per-action toggling and diff previews.
Profiles for tools not detected on the system are shown grayed out with a "NOT INSTALLED" badge and cannot be selected.
When piped or used with --yes, Saddle falls back to a plain-text installer. Ideal for CI/CD pipelines and headless environments.
# Preview all changes
npx saddle --dry-run --all
# Apply everything, no prompts
npx saddle --yes --all
# Apply specific profiles
npx saddle --profile claude-skills-skills,cursor-directory-agents --yes| Variable | Default | Description |
|---|---|---|
SADDLE_DIR |
~/.config/saddle |
Base config directory |
SADDLE_CONFIG |
~/.config/saddle/config.yaml |
Path to config file |
SADDLE_RULES_DIR |
~/.config/saddle/rules |
Path to rules directory |
Rules are YAML files that define how to sync a tool's configurations. Each rule describes what to link and where. Place custom rules in ~/.config/saddle/rules/ (or set SADDLE_RULES_DIR to override).
tool: claude # Unique identifier for this tool
label: Claude Code # Display name in the TUI
binary: # How to detect if tool is installed (optional)
which: claude # Try `which claude` to detect
# OR
paths: # Or check these paths on specific platforms
darwin: /Applications/Claude.app
linux: /usr/bin/claude
home: ~/.claude # Tool's config directory (supports ~)
enabled: true # Include in sync (default: true)
mode: multi-select # Selection mode: multi-select (default) or single-select
mappings: # List of what to link
- type: skills # Type: skills | file | directory
source: skills # Path relative to repo root
target: skills # Path relative to home (or . for home itself)
itemType: skill # Optional: type hint for skills mapping
- type: file # Link a single file
source: agents/claude/AGENTS.md
target: AGENTS.md # File name in home
- type: directory # Link files from a directory
source: configs/claude
target: . # Flatten files directly into home| Field | Required | Type | Notes |
|---|---|---|---|
tool |
✓ | string | Machine-readable identifier (lowercase, no spaces) |
label |
✗ | string | Display name; defaults to capitalized tool |
binary |
✗ | object | Detection method; omit to never detect |
home |
✓ | string | Tool's config directory; supports ~ |
enabled |
✗ | boolean | Default: true. Set false to skip syncing |
mode |
✗ | string | Selection mode (see below) |
mappings |
✓ | array | List of symlink definitions |
Control how users can select items from this rule:
-
multi-select(default) — User can select any combination of profiles. UI shows checkboxes[x]/[ ]. Useful for skills, agents, commands where you might want multiple at once. -
single-select— User can select only one profile from this rule at a time. UI shows radio buttons(•)/( ). Useful when alternatives are mutually exclusive (e.g., multiple config files targeting the same destination).
Example: oh-my-openagent.yaml has 3 file mappings all targeting oh-my-openagent.json. Setting mode: single-select ensures only one alternative config gets installed:
tool: oh-my-openagent
label: OpenCode Config
home: ~/.config/opencode
enabled: true
mode: single-select # Only allow ONE of the three files
mappings:
- type: file
source: oh-my-openagent/config.openai.json
target: oh-my-openagent.json
- type: file
source: oh-my-openagent/config.claude.json
target: oh-my-openagent.json
- type: file
source: oh-my-openagent/config.copilot.json
target: oh-my-openagent.jsonskills — Discovers subdirectories in source and creates one action per skill.
- type: skills
source: skills
target: skills
itemType: skill # optional type hintfile — Links a single file. Source file must exist.
- type: file
source: agents/claude/AGENTS.md
target: AGENTS.mddirectory — Discovers files in source directory (non-recursive) and creates one action per file.
- type: directory
source: configs/claude
target: . # Flatten into home
# OR
target: config/ # Put into subdirectoryDetect if a tool is installed:
# Method 1: `which` command (cross-platform)
binary:
which: claude
# Method 2: Platform-specific paths
binary:
paths:
darwin: /Applications/Claude.app
linux: /usr/bin/claude
win32: C:\Program Files\Claude\claude.exe
# Method 3: Both (tries `which` first, falls back to paths)
binary:
which: cursor
paths:
darwin: /Applications/Cursor.appLinks to official documentation for each supported AI coding tool.
Claude Code
- CLI Reference — commands and flags
- Interactive Mode — slash commands and shortcuts
- Skills — custom slash commands via SKILL.md
- Subagents — agent delegation
- Agent Teams — multi-agent collaboration
- Settings — settings.json reference
- Memory / CLAUDE.md — project instructions
- Hooks — lifecycle event hooks
- MCP — MCP server integration
- Plugins — plugin system
Cursor
- CLI Overview — getting started with the CLI
- Using Agent in CLI — interactive agent usage
- Parameters Reference — all CLI flags
- Slash Commands — in-session commands
- Agent Modes — plan, ask, and agent modes
- Rules — .cursor/rules/ configuration
- Skills — multi-step workflow files
- MCP in CLI — MCP server management
- Headless / CI — non-interactive scripting
Codex (OpenAI)
- CLI Reference — all subcommands and flags
- CLI Features — feature overview
- Slash Commands — in-session TUI commands
- Config Basics — config.toml setup
- Config Reference — all config keys
- AGENTS.md Guide — agent instruction files
- Rules — rule system
- Skills — skill system
- MCP Integration — MCP server setup
- Non-interactive Mode — codex exec for CI/CD
Gemini
- CLI Cheatsheet — launch flags and model flags
- Interactive Commands — slash, at, and shell commands
- Configuration Reference — settings.json schema
- GEMINI.md Context Files — agent memory and instructions
- Custom Commands — .toml custom slash commands
- Skills — agent skills system
- MCP Server Integration — MCP setup
- Plan Mode — read-only planning
- Headless / Non-interactive — CI/automation usage
OpenCode
- CLI Reference — all commands and flags
- Config Reference — opencode.json setup
- Agents — agent definitions and built-in agents
- Skills — SKILL.md skill system
- Custom Commands — slash command files
- Rules / AGENTS.md — project instruction files
- MCP Servers — MCP integration
- Providers — model provider configuration
- Plugins — plugin system
- TUI Usage — terminal UI reference
pnpm install
pnpm run lint:agentsThe same validator runs from the Husky pre-commit hook.
- Ink — React for CLIs
- @inkjs/ui — Terminal UI components
- React — Component framework
- yaml — YAML parser
MIT License · Made by ndizazzo