Agent Switch is a zero-runtime-dependency Rust CLI for synchronizing a canonical .agents/
directory with native coding-agent formats.
The binary name is ags.
For maintainers, see docs/architecture.md for the
workspace layout, sync pipeline, manifest semantics, and extension points.
For CLI workflows and option semantics, see docs/cli-usage.md.
For canonical .agents/ file conventions and frontmatter examples, see
docs/canonical-files.md.
Download a prebuilt archive for Linux, macOS, or Windows from the latest GitHub release, or build from source with Rust 1.85 or newer:
cargo build --release -p agent-switch-cliOn Unix-like systems, install the binary somewhere on PATH:
mkdir -p ~/.local/bin
install -m 0755 target/release/ags ~/.local/bin/agsOn Windows, copy target\release\ags.exe to a directory on PATH.
For most existing repositories, let coding-agent tools create their native files
first, then consolidate those files into the canonical .agents/ layout:
ags migrate --check
ags migrate
# or only selected source tools
ags --tool claude,copilot migrateUse init only for a new canonical-first repository that has no native agent
files to import yet:
ags init
ags setupThe generated config uses canonical-only mode, and setup runs the initial
export-side sync automatically.
Check for drift in CI without writing files:
ags sync --check --export-onlySwitch to a selected tool set and remove old managed links, file-copy fallbacks, generated outputs, and managed MCP merge content for tools that are no longer selected:
ags setup --tool codex --prunesetup syncs the selected tool set automatically unless --no-sync is used.
# native-first onboarding
ags migrate
ags migrate --check
# canonical-first bootstrap for repos with no native files yet
ags init
ags setup
ags setup --tool codex --prune
ags setup --check
ags sync
ags sync --check
# import-only / export-only are mutually exclusive
ags sync --tool codex,copilot
ags sync --check --import-only
ags sync --check --export-only
ags sync --json
ags sync --json --event-filter generated,merged
ags doctor
ags mappings validate
ags versionSee docs/cli-usage.md for the full scenario guide,
including bootstrap, tool switching, drift checks, JSON output, and CI usage.
Global options:
--root <path>
--config <path>
--tool <list>
--quiet
--verbose
--debugSupported tools:
claude, codex, copilot, opencode, pi, antigravity
Default integrations prefer each tool's native discovery paths, use managed links or copies for shared files, generate adapters when formats differ, and merge canonical MCP settings into native configs when required.
Pi reads root/ancestor AGENTS.md and .agents/skills directly. Agent Switch
only exposes shared commands at Pi's native .pi/prompts path. Official Pi
does not ship built-in subagents, a path-scoped rules directory, or
MCP, so those are not fabricated by the default integration. Pi-only resources
such as extensions, themes, project settings, SYSTEM.md, and
APPEND_SYSTEM.md remain project-owned and trackable under .pi/.
Existing .agent-switch.yaml files are never silently rewritten on upgrade. To
adopt these Pi defaults, keep/add .pi/prompts, remove .pi/skills and the
legacy .pi/mcp.json mapping, then run ags --tool pi migrate; Pi discovers
canonical skills directly. For current Antigravity, remove .agent/rules and
.agent/skills before ags --tool antigravity migrate; .agents/rules and
.agents/skills are now its preferred paths, and MCP is rendered to
.agents/mcp_config.json. Use ags init --force --tools antigravity (or another
explicit tool list) only when replacing the entire existing config is
intentional. Existing Copilot configs should likewise add
.mcp.json: .agents/mcp.json and remove the legacy copilot-mcp-config merge
job; ags --tool copilot migrate imports and
backs up the obsolete .copilot/mcp-config.json, while Copilot discovers the
shared workspace file directly.
For a path-by-path canonical-to-native matrix, see
docs/canonical-files.md.
For symlink/copy entries, setup creates managed links; on Windows, directory
link failures can use junctions and file symlink failures can use managed
plain-file copies.
Agent Switch reads .agent-switch.yaml using config schema version 1 by
default. It does not read scripts/mappings.yaml.
version: 1
agents_dir: .agents
manifest: .agents/.sync-manifest.jsonDefault config generated by ags init or by ags migrate when no config exists
contains managed-link mappings, generation mappings, and MCP merge mappings
similar to:
version: 1
agents_dir: .agents
manifest: .agents/.sync-manifest.json
sync_mode: canonical-only
generated_tracking:
copilot-agents: tracked
copilot-prompts: tracked
copilot-instructions: tracked
claude: ignored
codex-agents: ignored
opencode-agents: ignored
antigravity-mcp-config: ignored
symlinks:
.claude/skills: .agents/skills
.claude/agents: .agents/agents
.claude/commands: .agents/commands
.claude/rules: .agents/rules
.opencode/commands: .agents/commands
.pi/prompts: .agents/commands
.agent/workflows: .agents/commands
.mcp.json: .agents/mcp.json
CLAUDE.md: AGENTS.md
generate:
copilot-agents:
from: .agents/agents
to: .github/agents
format: copilot-agent
suffix: .agent.md
copilot-prompts:
from: .agents/commands
to: .github/prompts
format: copilot-prompt
suffix: .prompt.md
copilot-instructions:
from: .agents/rules
to: .github/instructions
format: copilot-instructions
suffix: .instructions.md
recursive: true
opencode-agents:
from: .agents/agents
to: .opencode/agents
format: opencode-agent
suffix: .md
codex-agents:
from: .agents/agents
to: .codex/agents
format: codex-agent
suffix: .toml
merge:
opencode-config:
to: opencode.json
format: opencode
codex-config:
to: .codex/config.toml
format: codex
antigravity-mcp-config:
to: .agents/mcp_config.json
format: antigravityRun ags migrate when a repository already has native agent files, or when your
team prefers to use coding-agent tools first and consolidate them later. It
creates .agent-switch.yaml if needed, imports supported native layouts into
.agents/, backs up managed native paths as .bak, and then runs setup. Use
ags init only for a new canonical-first repository with no native files to
import; it creates the default config, canonical directories, sample files, and
recommended .gitignore entries. ags init --tools codex,copilot writes a
starter config filtered to only those tool mappings.
For Claude compatibility, ags setup also discovers nested repository
instructions named AGENTS.md and creates same-directory managed CLAUDE.md
links or copy fallbacks. For example, packages/api/AGENTS.md produces
packages/api/CLAUDE.md. Hidden tool output directories such as .agents/,
.claude/, .github/, and .git/ are skipped.
sync_mode: canonical-only makes plain ags sync export from .agents/ to
native adapters without importing native edits back into the canonical tree.
Use ags sync --import-only when you explicitly want to pull managed generated
edits back into canonical files.
generated_tracking controls .gitignore generation by mapping id. Ignore
rules are emitted for exact managed paths rather than whole tool directories,
so changing a mapping to tracked makes that output committable without also
unignoring unrelated adapters. Copilot generated files default to tracked
because GitHub-hosted Copilot reads .github/agents, .github/prompts, and
.github/instructions from the repository. Re-run ags init (without
--force) or ags migrate after editing tracking settings to refresh the
managed .gitignore block from the active config.
Config paths are validated before any setup or sync work runs:
- paths must be repository-relative;
- paths must use forward slashes for portability;
- absolute paths and
./..path components are rejected; generateoutput directories must be unique;- unknown or misspelled config fields are rejected;
- use either
toolortoolson a mapping, not both; toolslists must be non-empty and contain no duplicates.
Symlinks can be declared as a simple link: target mapping or as an object with
explicit tool ownership. Custom links without inferred or explicit ownership are
kept when --tool ... --prune is used.
symlinks:
CUSTOM.md:
to: .agents/custom.md
tools: [codex]Use ags setup --tool <tool> --prune when switching tools and you want
Agent Switch to remove everything it manages for tools that are no longer
selected: managed links, file-copy fallbacks, generated outputs (for example
.github/agents/*.agent.md), and managed MCP merge content (opencode.json's
mcp object, the .codex/config.toml marker block, and
.agents/mcp_config.json's mcpServers object). Prune also removes an obsolete
.copilot/mcp-config.json only when it exactly matches generated legacy output.
Pruning is conservative: unmanaged real files, modified managed-copy
fallbacks, modified generated outputs, and directories with user content are
skipped and reported instead of deleted. An unresolved setup or prune operation
exits with the drift code instead of reporting success.
During ags sync, managed file copies are only reconciled when they are
tracked in the sync manifest. A real file sitting at a managed link location
that Agent Switch never created is left untouched and reported as a warning;
it is never copied over the canonical source.
Agent Switch is designed to run on Linux, macOS, and Windows.
- Repository paths in output are normalized to forward slashes.
- Text files are read as UTF-8 and tolerate a leading UTF-8 BOM.
- Markdown frontmatter parsing tolerates CRLF line endings.
- Unix platforms create symlinks for managed links.
- Windows tries to create symlinks; directory links can fall back to junctions.
- If a Windows file symlink cannot be created, Agent Switch falls back to a managed plain-file copy so the tool remains usable without Developer Mode or administrator privileges.
- Generated files, manifests, and config writes use atomic replacement to reduce the chance of partially written files.
Import native files into .agents/:
ags --tool claude,copilot migrate
ags doctorUnless --keep-native or --no-setup is used, migrate finishes by running
setup and its automatic sync.
Migration preserves dotted Copilot filenames such as
speckit.git.commit.agent.md as .agents/agents/speckit.git.commit.md, infers
missing name fields from native filenames, strips native suffixes, and prefers
full Copilot instructions over same-named Claude pointer rules.
- Add
.agent-switch.yamlto the repo. - Keep canonical files under
.agents/. - Run
ags sync --checkin CI to detect drift. - Replace repo-local wrapper scripts with:
ags setupsetup performs sync by default. The Rust CLI migrates native tool files, but
it does not parse arbitrary repo-local wrapper scripts.
The workspace declares a minimum supported Rust version (MSRV) of Rust 1.85.
cargo build --release -p agent-switch-cliThe release binary is:
target/release/ags
See Install for platform-specific installation guidance.
Release builds in CI use explicit target triples for Linux, macOS, and Windows so archive names match the binaries they contain.
| Code | Meaning |
|---|---|
| 0 | command succeeded |
| 1 | drift detected by --check/doctor, or setup/prune could not complete |
| 2 | invalid config or command input |
| 3 | I/O or unexpected runtime error |
| 4 | unsupported config version or platform behavior |
ags sync --event-filter <events> keeps only selected events in text or JSON
output.
ags sync --json --event-filter imported,generated
ags sync --check --json --event-filter drift,synced_no_changesWhen --json is used, events are emitted in a deterministic order and payload
fields are fixed for scripts and CI machines.
cargo testCI runs cargo fmt --all --check, Clippy with warnings denied, an MSRV
cargo check --workspace --all-targets --locked, cargo audit --deny warnings,
and cargo test --workspace --locked on Linux, macOS, and Windows. Tag pushes
matching v* repeat format, lint, test, and audit verification before building
release archives for Linux, macOS, and Windows.
Agent Switch is available under the MIT License.