Metadata-Version: 2.4
Name: asura-sync
Version: 0.1.2
Summary: Cross-platform CLI to sync scattered local dev configs & secrets to a private Git repo, with qoder<->codex AI config translation.
Author-email: 你的姓名 <your@email.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/你的用户名/config-sync
Project-URL: Repository, https://github.com/你的用户名/config-sync
Project-URL: Issues, https://github.com/你的用户名/config-sync/issues
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: PyYAML>=6.0
Requires-Dist: tomli>=2.0; python_version < "3.11"
Requires-Dist: tomli-w>=1.0

# asura-sync

Cross-platform CLI to sync scattered local dev configs & secrets to a private Git repo, with qoder↔codex AI config translation.

跨平台配置与密钥同步工具——将散落在本机各处的 SSH 密钥、AI skill/MCP、Docker、npm、gitconfig 等用户级配置统一同步到私有 Git 仓库，支持 **三方对账**（本地/仓库/基线）和 **AI 配置平级翻译**（qoder↔codex）。

## Features

- **6 个同步模块**：SSH、Docker、npm/yarn、gitconfig、AI skills、AI MCP
- **三方对账引擎**：引入"上次同步基线"作为第三参照点，内容 sha256 比较，绝不依赖 mtime
- **AI 配置翻译**：canonical 中立格式为仓库唯一权威源，qoder/codex 平级双向翻译，确定性规则 + 四道工程兜底
- **增量同步**：仅处理有变化的项，支持 `--dry-run` 预览
- **冲突安全**：冲突项自动备份 + 上报，支持 `--prefer local|cloud` 决策
- **SSH 权限保持**：私钥回写本机后自动恢复 600 权限（Windows 跳过）
- **Docker 凭据剔除**：`--exclude-secrets` 选项可剔除 config.json 的 auths 字段

## Installation

```bash
pip install config-sync
```

Or install from source:

```bash
git clone <this-repo>
cd config-sync
pip install -e .
```

## Quick Start

### 1. Initialize

```bash
config-sync init --repo git@github.com:your/config-sync-repo.git
```

### 2. Push local configs to repo

```bash
config-sync push                        # push all modules
config-sync push --only ssh,skills      # push specific modules
config-sync push --only skills --dry-run  # preview only
```

### 3. Pull configs from repo

```bash
config-sync pull                        # pull all modules
config-sync pull --only ssh             # pull SSH only
```

### 4. Two-way sync (default)

```bash
config-sync sync                        # auto-detect push/pull per item
config-sync sync --prefer local         # resolve conflicts in favor of local
config-sync sync --prefer cloud         # resolve conflicts in favor of cloud
```

### 5. Check status

```bash
config-sync status                      # show reconciliation results
config-sync status --only ssh,skills    # filter by module
```

## CLI Reference

| Command | Description |
|---------|-------------|
| `init --repo <url>` | Initialize local working copy (clone or init + remote) |
| `sync` | Two-way sync with three-way reconciliation |
| `push` | One-way: local → repo → git push |
| `pull` | One-way: git pull → repo → local |
| `status` | Show per-item reconciliation status |

### Common Options

| Option | Description |
|--------|-------------|
| `--only <modules>` | Comma-separated module list: `ssh,docker,npm,git,skills,mcp` |
| `--dry-run` | Preview actions without executing |
| `-v, --verbose` | Verbose output |
| `--prefer local\|cloud` | Conflict resolution direction (sync/push only) |
| `--exclude-secrets` | Strip Docker `auths` and similar credentials (push only) |
| `--from <tool>` | Specify authoritative AI tool when collecting (`qoder` or `codex`) |

## Modules

| Module | Source | Repo Path | Notes |
|--------|--------|-----------|-------|
| `ssh` | `~/.ssh/` | `ssh/` | Keys, config, known_hosts; chmod 600 on private keys |
| `docker` | `~/.docker/` | `docker/` | daemon.json + config.json; `--exclude-secrets` strips auths |
| `npm` | `~/.npmrc` etc. | `npm/` | .npmrc / .yarnrc / .yarnrc.yml |
| `git` | `~/.gitconfig` | `gitconfig/` | Global git config + ignore file |
| `skills` | `~/.qoder/skills/` etc. | `ai/skills/` | SKILL.md standard, fan-out to all detected tools |
| `mcp` | Tool MCP files | `ai/mcp/` | Canonical JSON, translated to codex TOML / qoder JSON |

## Three-Way Reconciliation

Problem: configs are scattered across `~/.ssh`, `~/.qoder/skills`, `~/.codex`, etc. Git can't see these external source files, so git version alone can't tell which side is newer.

Solution: Introduce a **sync baseline (base)** as the third reference point. Compare three content hashes per item:

| Condition | Decision |
|-----------|----------|
| local==base && repo==base | No change → skip |
| local!=base && repo==base | Local only → push |
| local==base && repo!=base | Cloud only → pull |
| Both changed, local==repo | Converged → update base |
| Both changed, local!=repo | **Conflict** → backup + report |

Never relies on mtime — always uses content sha256 as the authority.

## AI Config Translation

- **Canonical as authority**: Git repo stores one neutral canonical format; qoder and codex are equal peers
- **Skills**: Same SKILL.md standard, fan-out by copying to each tool's skills root directory
- **MCP**: Canonical `servers.json` → codex TOML `[mcp_servers.*]` / qoder JSON `mcpServers`
- **Four safeguards**: unknown field passthrough, round-trip idempotency check, versioned field map, graceful degradation

## Architecture

```
config-sync/
├── pyproject.toml
├── config_sync/
│   ├── cli.py              # argparse subcommands
│   ├── syncer.py           # Three-way reconciliation engine
│   ├── manifest.py         # Module registry
│   ├── state.py            # Sync baseline (sha256 per item)
│   ├── gitrepo.py          # Git subprocess wrapper
│   ├── logger.py           # Console + file logging
│   ├── toolpaths.py        # TOOL_TARGETS path table
│   ├── modules/
│   │   ├── base.py         # SyncModule + FileSyncModule
│   │   ├── ssh.py          # SSH module
│   │   ├── docker.py       # Docker module
│   │   ├── npm.py          # npm/yarn module
│   │   ├── gitcfg.py       # gitconfig module
│   │   └── ai.py           # AiSkillsModule + AiMcpModule
│   └── adapters/
│       ├── canonical.py    # Neutral canonical format
│       ├── collectors.py   # Tool → canonical
│       ├── translators.py  # Canonical → tool format
│       └── _toml.py        # TOML read/write compat
└── tests/
    └── test_core.py        # 22 unit tests
```

## Development

```bash
# Install in dev mode
pip install -e ".[dev]"

# Run tests
python -m pytest
```

## Requirements

- Python 3.9+
- Git installed and available in PATH
- Dependencies: PyYAML, tomli (Python < 3.11), tomli-w

## License

MIT
