asura-sync
Cross-platform CLI to sync scattered local dev configs and portable local state to a private Git repo, with qoder↔codex AI config translation.
跨平台配置同步工具——将散落在本机各处的 SSH、Docker、npm、gitconfig、AI skill/MCP、Codex 本地状态等用户级配置统一同步到私有 Git 仓库,支持 三方对账(本地/仓库/基线)和 AI 配置平级翻译(qoder↔codex)。
Features
- 7 个同步模块:SSH、Docker、npm/yarn、gitconfig、AI skills、AI MCP、Codex 本地状态
- 三方对账引擎:引入"上次同步基线"作为第三参照点,内容 sha256 比较,绝不依赖 mtime
- AI 配置翻译:canonical 中立格式为仓库唯一权威源,qoder/codex 平级双向翻译,确定性规则 + 四道工程兜底
- 增量同步:仅处理有变化的项,支持
--dry-run预览 - 冲突安全:冲突项自动备份本地与仓库两份内容 + 上报,支持
--prefer local|cloud决策 - SSH 权限保持:私钥回写本机后自动恢复 600 权限(Windows 跳过)
- 安全默认值:默认剔除 Docker
auths、Codexauth.json等登录凭据,可显式--include-secrets - Codex 状态同步:同步 Codex 配置、规则、会话索引与 SQLite 主库快照,排除缓存、临时文件、生成图片、skills/MCP 重复源
Installation
pip install asura-sync
Or install from source:
git clone <this-repo>
cd asura-sync
pip install -e .
Quick Start
1. Initialize
asura-sync init --repo git@github.com:your/asura-sync-repo.git
2. Push local configs to repo
asura-sync push # push all modules
asura-sync push --only ssh,skills # push specific modules
asura-sync push --only skills --dry-run # preview only
3. Pull configs from repo
asura-sync pull # pull all modules
asura-sync pull --only ssh # pull SSH only
4. Two-way sync (default)
asura-sync sync # auto-detect push/pull per item
asura-sync sync --prefer local # resolve conflicts in favor of local
asura-sync sync --prefer cloud # resolve conflicts in favor of cloud
5. Check status
asura-sync status # show reconciliation results
asura-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 only) |
--exclude-secrets |
Strip Docker auths, Codex auth files, and similar credentials (default) |
--include-secrets |
Allow secret files/fields to be synced; use only with an encrypted private repo |
--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 |
codex |
~/.codex/ |
codex/ |
Portable Codex state; excludes auth, cache, temp, generated images, skills and MCP duplicate data |
Codex State Sync
The codex module syncs portable local Codex state under ~/.codex, including config fields outside [mcp_servers], rules, session indexes, shell snapshots and SQLite/database files. SQLite and .db files are copied through the SQLite backup API where possible, so a live local database can be snapshotted safely.
To avoid duplicating canonical modules or leaking volatile data, it skips skills/, [mcp_servers] inside config.toml, plugin caches, vendor imports, temp folders, generated images, WAL/SHM files, logs and auth files by default. The existing skills and mcp modules remain the authoritative sync path for Codex skills and MCP servers.
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 JSONmcpServers - Four safeguards: unknown field passthrough, round-trip idempotency check, versioned field map, graceful degradation
Architecture
asura-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
│ │ └── codex.py # Portable Codex local state module
│ └── 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 # Core unit tests
Development
# Install in dev mode
pip install -e ".[dev]"
# Run tests
python -m pytest
Requirements
- Python 3.9+
- Git installed and available in PATH
- Runtime dependencies: tomli (Python < 3.11), tomli-w
- Dev dependencies: pytest
License
MIT
Metadata
Release files for asura-sync 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| asura_sync-0.1.4.tar.gz | 29.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| asura_sync-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 63.2 kB
Release files / asura_sync-0.1.4.tar.gz
| Download URL | asura_sync-0.1.4.tar.gz |
|---|---|
| Size | 29.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
df4dc72e5de8340772d09fac95bf184ace9298a322bd62344713e2cdd7abe652
|
|
BLAKE2b-256 checksum How to use checksums |
c341160105b8518239e6ed360cde3cb651003b91c4f947dfebec0f9649244e00
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Release files / asura_sync-0.1.4-py3-none-any.whl
| Download URL | asura_sync-0.1.4-py3-none-any.whl |
|---|---|
| Size | 33.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4e92904a0c4640c681c7ce55e5f54ae7e8f5e40c802f1c7b30339ebfaf53874e
|
|
BLAKE2b-256 checksum How to use checksums |
b5980ddd9be70297ed5b98398443e614b4f419b6f6930f57808df193358422ec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.6
|
Security for asura-sync 0.1.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.