Skip to main content

Bidirectional synchronization tool for custom agents and settings between Claude Code and GitHub Copilot.

Project description

Agent Sync Tool

Bidirectional synchronization tool for custom agents and settings between Claude Code and GitHub Copilot.

Features

  • Bidirectional sync - Sync in both directions automatically
  • Permission sync - Sync permission configurations (Claude settings.json ↔ Copilot .perm.json)
  • Smart conflict resolution - Handles conflicts with user prompts or auto-resolution
  • Deletion tracking - Removes agents deleted from source
  • Modification tracking - Only syncs changed files using state tracking
  • Format conversion - Automatic conversion between .md and .agent.md formats
  • Field mapping - Intelligent mapping of format-specific fields
  • Dry-run mode - Preview changes before applying

Building Standalone Executable

You can package the application as a standalone executable (no Python installation required) for Linux or Windows.

Using GitHub Actions (Recommended)

This repository includes a GitHub Action to automatically build both Linux and Windows binaries.

Automated Releases: Simply push a tag starting with v (e.g., v1.0.0) to the repository. The workflow will automatically:

  1. Build the binaries for Linux and Windows.
  2. Create a new GitHub Release.
  3. Upload the binaries as assets.
  4. Generate release notes from the commit history.

Manual Trigger:

  1. Go to the "Actions" tab in the repository.
  2. Select "Build and Release".
  3. Click "Run workflow".
  4. Download the artifacts from the completed run.

Building Manually

Linux: Run the provided build script:

./scripts/build_executable.sh

The executable will be located at dist/agent-sync.

Windows: Run the following command in a terminal (PowerShell or Command Prompt) with Python installed:

pip install -r requirements.txt
pip install pyinstaller
pyinstaller --clean agent-sync.spec

The executable will be located at dist/agent-sync.exe.

Requirements

pip install -r requirements.txt

Usage

The tool is run via the cli.main module.

GUI Mode

Launch the graphical user interface by running the tool without arguments or with the --gui flag:

# Launch GUI (default if no args)
python -m cli.main

# Or explicitly
python -m cli.main --gui

Basic Bidirectional Agent Sync

python -m cli.main \
  --source-dir ~/.claude/agents \
  --target-dir .github/agents \
  --source-format claude \
  --target-format copilot \
  --config-type agent

Permission Sync

Sync permission configurations between VS Code (Copilot) and Claude Code formats:

VS Code (Copilot) → Claude:

python -m cli.main \
  --source-dir ~/.vscode \
  --target-dir ~/.claude \
  --source-format copilot \
  --target-format claude \
  --config-type permission

Claude → VS Code (Copilot):

python -m cli.main \
  --source-dir ~/.claude \
  --target-dir .github \
  --source-format claude \
  --target-format copilot \
  --config-type permission

Bidirectional sync:

python -m cli.main \
  --source-dir ~/.claude \
  --target-dir ~/.vscode \
  --source-format claude \
  --target-format copilot \
  --config-type permission

See Permission Conversion Details below for more information.

One-Time Migration

Claude → Copilot:

python -m cli.main \
  --source-dir ~/.claude/agents \
  --target-dir .github/agents \
  --source-format claude \
  --target-format copilot \
  --config-type agent \
  --direction source-to-target

Copilot → Claude:

python -m cli.main \
  --source-dir .github/agents \
  --target-dir ~/.claude/agents \
  --source-format copilot \
  --target-format claude \
  --config-type agent \
  --direction source-to-target

Preview Changes (Dry Run)

python -m cli.main \
  --source-dir ~/.claude/agents \
  --target-dir .github/agents \
  --source-format claude \
  --target-format copilot \
  --config-type agent \
  --dry-run

With Enhanced Copilot Features

python -m cli.main \
  --source-dir ~/.claude/agents \
  --target-dir .github/agents \
  --source-format claude \
  --target-format copilot \
  --config-type agent \
  --direction source-to-target \
  --add-argument-hint \
  --add-handoffs

Arguments

Argument Required Default Description
--source-dir Yes - Path to source directory containing configuration files
--target-dir Yes - Path to target directory
--source-format Yes - Source format name (claude or copilot)
--target-format Yes - Target format name (claude or copilot)
--config-type No agent Type of configuration to sync: agent or permission
--direction No both Sync direction: source-to-target, target-to-source, or both
--dry-run No false Show changes without applying them
--force No false Auto-resolve conflicts using newest file
--verbose, -v No false Detailed logging output
--state-file No ~/.agent_sync_state.json Custom path for state file
--add-argument-hint No false Add argument-hint field (Claude→Copilot only)
--add-handoffs No false Add handoffs placeholder (Claude→Copilot only)
--gui No false Launch the graphical user interface

How It Works

File Matching

Files are matched by base name:

  • Agents: planner.md (Claude) ↔ planner.agent.md (Copilot)
  • Permissions: settings.json (Claude) ↔ settings.perm.json (Copilot)

Sync Logic

  1. First Sync: Uses the newest file based on modification time
  2. Subsequent Syncs: Only syncs files modified since last sync
  3. Conflicts: When both files are modified:
    • Without --force: Prompts user to choose
    • With --force: Uses newest file automatically
  4. Deletions: Removes target file when source is deleted

Field Conversions

Claude → Copilot

Claude Field Copilot Field Conversion
name name Direct
description description Direct
description argument-hint Optional (with --add-argument-hint)
tools tools String → Array ("tool1, tool2"['tool1', 'tool2'])
model model Mapped (sonnetClaude Sonnet 4)
- target Added (vscode)
- handoffs Optional placeholder (with --add-handoffs)
permissionMode - Dropped (See Permission Sync)
skills - Dropped

Copilot → Claude

Copilot Field Claude Field Conversion
name name Direct
description description Direct
tools tools Array → String (['tool1', 'tool2']"tool1, tool2")
model model Mapped (Claude Sonnet 4sonnet)
argument-hint - Dropped
handoffs - Dropped
target - Dropped
mcp-servers - Dropped

Permission Conversion

The tool supports bidirectional conversion of permission configurations between VS Code (Copilot) and Claude Code formats.

Permission Format Overview

VS Code (Copilot) Format:

{
  "chat.tools.terminal.autoApprove": {
    "mkdir": true,
    "/^git status$/": true,
    "rm": false,
    "/dangerous/": false
  },
  "chat.tools.urls.autoApprove": {
    "https://*.github.com/*": true,
    "https://untrusted.com": false
  }
}

Claude Code Format:

{
  "permissions": {
    "allow": [
      "Bash(mkdir:*)",
      "Bash(/^git status$/)",
      "WebFetch(domain:*.github.com)"
    ],
    "ask": [
      "Bash(rm:*)",
      "Bash(/dangerous/)",
      "WebFetch(domain:untrusted.com)"
    ],
    "deny": []
  }
}

Conversion Rules

VS Code → Claude

VS Code Setting Claude Category Description
"command": true allow Auto-approve (no prompt)
"command": false ask Require approval before execution
/regex/: true allow Regex patterns preserved
/regex/: false ask Regex patterns preserved
Terminal commands Bash() permissions Simple strings become Bash(cmd:*), regex stays as-is
URL patterns WebFetch(domain:...) Domain extracted from URL

Claude → VS Code

Claude Category VS Code Setting Notes
allow true Auto-approve
ask false Require approval
deny false (with warning) Lossy conversion - VS Code doesn't support blocking entirely
Bash() rules Terminal commands Pattern extracted from Bash(pattern)
WebFetch() rules URL patterns Domain becomes https://domain/*

Important Notes

1. Lossy Conversions

When converting Claude deny rules to VS Code format, they become false (require approval) instead of blocking entirely. This is because VS Code doesn't have a true "deny" concept.

Example:

// Claude
{
  "permissions": {
    "deny": ["Bash(rm -rf:*)"]
  }
}

// Converts to VS Code as:
{
  "chat.tools.terminal.autoApprove": {
    "rm -rf": false  // Require approval, not blocked
  }
}

The tool generates warnings for these lossy conversions.

2. Regex Pattern Handling

Regex patterns are preserved as-is during conversion:

// VS Code
{
  "chat.tools.terminal.autoApprove": {
    "/^git (status|show\\b.*)$/": true
  }
}

// Converts to Claude as:
{
  "permissions": {
    "allow": ["Bash(/^git (status|show\\b.*)$/)"]
  }
}

3. URL Split Approval

VS Code supports separate approval for request vs response (approveRequest / approveResponse). Claude doesn't support this granularity, so split approvals map to ask (safer) with original details stored in metadata.

Example:

// VS Code
{
  "chat.tools.urls.autoApprove": {
    "https://api.example.com/*": {
      "approveRequest": true,
      "approveResponse": false
    }
  }
}

// Converts to Claude as:
{
  "permissions": {
    "ask": ["WebFetch(domain:api.example.com)"]
  }
  // Metadata stores original split approval details
}

4. Round-Trip Fidelity

For VS Code → Claude → VS Code conversions (without deny rules), perfect fidelity is maintained:

# Convert VS Code → Claude
python -m cli.main --convert-file vscode-settings.json --target-format claude

# Convert back Claude → VS Code
python -m cli.main --convert-file claude-settings.json --target-format copilot

# Result: Identical to original vscode-settings.json

Examples

See examples/permission_conversion_example.py for complete working examples of:

  • VS Code → Claude conversion
  • Claude → VS Code conversion
  • Lossy conversion tracking
  • Round-trip conversion
  • Complex URL permissions

Run the examples:

PYTHONPATH=/workspaces/coding-agent-settings-sync python examples/permission_conversion_example.py

Conversion Warnings

Note: Conversion warning display and --strict mode are planned for v2.0.0 (see issue #69).

Currently, lossy conversions happen silently:

  • Claude deny → VS Code false (require approval instead of blocking)
  • VS Code split URL approvals → Claude ask (stored in metadata)

Warnings are tracked in the canonical model metadata but not displayed during sync operations.

Troubleshooting

"No YAML frontmatter found"

Ensure your agent files have proper YAML frontmatter:

---
name: agent-name
description: Agent description
---

Body content here

Conflicts Keep Appearing

Use --force to automatically resolve conflicts, or manually review and edit the files to resolve differences.

State File Issues

If sync state gets corrupted, you can safely delete it (default: ~/.agent_sync_state.json). The next sync will treat all files as new.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agent_sync-1.0.1.tar.gz (132.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agent_sync-1.0.1-py3-none-any.whl (52.3 kB view details)

Uploaded Python 3

File details

Details for the file agent_sync-1.0.1.tar.gz.

File metadata

  • Download URL: agent_sync-1.0.1.tar.gz
  • Upload date:
  • Size: 132.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for agent_sync-1.0.1.tar.gz
Algorithm Hash digest
SHA256 cd778aa2fd0fc1e8667f14b7654a4f934225da0a92cbf1a2261cad427f741f06
MD5 dbc0bf921fb10a54f7e6f399ba5ea206
BLAKE2b-256 1752c660688fdb34d3c77384e7b63be47356183f84453214e234ef96cb57cad2

See more details on using hashes here.

File details

Details for the file agent_sync-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: agent_sync-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 52.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for agent_sync-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 477f25eaf315ca55121096ac5f0b3e3200ee588bc680361140ae39c3c5c897e0
MD5 2a812e5fb11fad70525c6bd876c2d78d
BLAKE2b-256 d1b58251d41d13bfd80a7d424149554335f2140ac395c899c2a243e0110a1754

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page