Skip to content

ndizazzo/saddle

Repository files navigation

   _______   ___  ___  __   ____ 
  / __/ _ | / _ \/ _ \/ /  / __/
 _\ \/ __ |/ // / // / /__/ _/  
/___/_/ |_/____/____/____/___/  

One repo. One source of truth. Sync your AI tool configs everywhere.

CI License: MIT Node.js >=18 npm

Keep your agents, skills, commands, and configurations in sync across
Claude Code, Codex, Copilot, Cursor, Gemini, and OpenCode — on every machine.

GitHub · npm · Changelog


Quick Start

# 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 removal

The interactive TUI detects which AI tools are installed and walks you through linking skills, agents, commands, and config files for each.


What Gets Synced

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/

Features

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.


How It Works

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.


Canonical Layout

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.


CLI Reference

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

Interactive Mode

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.

Non-Interactive Mode

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

Configuration

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

Writing Rules

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).

Rule Schema

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

Key Fields

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

Selection Mode

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.json

Mapping Types

skills — Discovers subdirectories in source and creates one action per skill.

- type: skills
  source: skills
  target: skills
  itemType: skill # optional type hint

file — Links a single file. Source file must exist.

- type: file
  source: agents/claude/AGENTS.md
  target: AGENTS.md

directory — 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 subdirectory

Binary Detection

Detect 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.app

CLI Documentation Reference

Links to official documentation for each supported AI coding tool.

Claude Code
Cursor
Codex (OpenAI)
Gemini
OpenCode

Validation

pnpm install
pnpm run lint:agents

The same validator runs from the Husky pre-commit hook.


Built With

Tech stack

  • Ink — React for CLIs
  • @inkjs/ui — Terminal UI components
  • React — Component framework
  • yaml — YAML parser

MIT License · Made by ndizazzo

About

Keep your agents, skills, commands, and configurations in sync across Claude Code, Codex, Copilot, Cursor, Gemini, and OpenCode on every machine.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors