Skip to content

NeoHsu/agent-switch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Agent Switch

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.

Quickstart

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 migrate

Use init only for a new canonical-first repository that has no native agent files to import yet:

ags init
ags setup
ags sync --export-only

Check for drift in CI without writing files:

ags sync --check --export-only

Switch 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 --prune
ags sync --tool codex

Commands

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

See 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
--debug

Supported tools in v1:

claude, codex, copilot, opencode, pi, antigravity

Default integrations by tool:

Tool Native paths managed by default Canonical source Integration mode
Claude .claude/agents, .claude/commands, .claude/rules, .claude/skills, CLAUDE.md, .mcp.json .agents/agents, .agents/commands, .agents/rules, .agents/skills, AGENTS.md, .agents/mcp.json symlink/copy; no generated adapter
Codex .codex/agents/*.toml, .codex/config.toml .agents/agents/*.md, .agents/mcp.json generated TOML agents; MCP marker-block merge
Copilot .github/agents/*.agent.md, .github/prompts/*.prompt.md, .github/instructions/**/*.instructions.md, .copilot/mcp-config.json .agents/agents, .agents/commands, .agents/rules, .agents/mcp.json generated Markdown; MCP config conversion
OpenCode .opencode/commands, .opencode/agents/*.md, opencode.json .agents/commands, .agents/agents, .agents/mcp.json commands symlink/copy; generated agents; MCP merge
Pi .claude/skills, .pi/mcp.json .agents/skills, .agents/mcp.json Claude-compatible skills and MCP symlink/copy
Antigravity .agent/rules, .agent/workflows, .agent/skills .agents/rules, .agents/commands, .agents/skills symlink/copy; no generated adapter

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.

Project Config

Agent Switch v1 reads .agent-switch.yaml by default. It does not read scripts/mappings.yaml.

version: 1
agents_dir: .agents
manifest: .agents/.sync-manifest.json

Default 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

symlinks:
  .claude/skills: .agents/skills
  .claude/agents: .agents/agents
  .claude/commands: .agents/commands
  .claude/rules: .agents/rules
  .opencode/commands: .agents/commands
  .agent/rules: .agents/rules
  .agent/workflows: .agents/commands
  .agent/skills: .agents/skills
  .mcp.json: .agents/mcp.json
  .pi/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
  copilot-mcp-config:
    to: .copilot/mcp-config.json
    format: copilot

Run 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. Copilot generated files default to tracked because GitHub-hosted Copilot reads .github/agents, .github/prompts, and .github/instructions from the repository.

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;
  • generate output directories must be unique;
  • use either tool or tools on a mapping, not both;
  • tools lists 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 .copilot/mcp-config.json). Pruning is conservative: unmanaged real files, modified generated outputs, and directories with user content are skipped and reported instead of deleted.

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.

Cross-Platform Behavior

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.

Migrating Native Tool Files

Import native files into .agents/:

ags --tool claude,copilot migrate
ags doctor
ags sync --export-only

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.

Migration From Repo-Local Scripts

  1. Add .agent-switch.yaml to the repo.
  2. Keep canonical files under .agents/.
  3. Run ags sync --check in CI to detect drift.
  4. Replace repo-local wrapper scripts with:
ags setup
ags sync

The Rust CLI v1 migrates native tool files, but it does not parse arbitrary repo-local wrapper scripts.

Build

The workspace declares a minimum supported Rust version (MSRV) of Rust 1.85.

cargo build --release -p agent-switch-cli

The release binary is:

target/release/ags

Install the release binary somewhere on your PATH, for example:

cargo build --release -p agent-switch-cli
install -m 0755 target/release/ags ~/.local/bin/ags

Release builds in CI use explicit target triples for Linux, macOS, and Windows so archive names match the binaries they contain.

Exit Codes

Code Meaning
0 command succeeded
1 drift detected in --check mode
2 invalid config or command input
3 I/O or unexpected runtime error
4 unsupported config version or platform behavior

Sync Event Filtering and JSON Output

ags sync --event-filter lets you keep only selected events in text or JSON output.

ags sync --json --event-filter imported,generated
ags sync --check --json --event-filter drift,synced_no_changes

When --json is used, events are emitted in a deterministic order and payload fields are fixed for scripts and CI machines.

Test

cargo test

CI runs cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings, an MSRV cargo check --workspace --all-targets, cargo audit, and cargo test --workspace on Linux, macOS, and Windows. Tag pushes matching v* build release archives for Linux, macOS, and Windows.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages