diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ae6c2bf..900f267 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -47,3 +47,10 @@ jobs:
- uses: actions/checkout@v7
- name: Reject common credential and private-path shapes
run: python3 scripts/privacy_scan.py
+
+ installer:
+ runs-on: macos-14
+ steps:
+ - uses: actions/checkout@v7
+ - run: zsh -n scripts/install.sh
+ - run: test -x scripts/install.sh
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7d2e447..f6d42de 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -13,6 +13,7 @@ PYTHONPATH=src python -m unittest discover -s tests
PYTHONPATH=src python -m unittest discover -s tests/integration
swift build --package-path macos-app/AgentSwitch
python3 scripts/privacy_scan.py
+zsh -n scripts/install.sh
```
## Required boundaries
diff --git a/README.md b/README.md
index 8fa4974..b8a3335 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,7 @@
+
+ English · 简体中文
+
+
# Agent Switch
**Define each MCP once. Store each credential once. Project both into every supported local AI agent.**
@@ -14,9 +18,10 @@ Agent Switch replaces those copies with one local registry, one private
credential store, and deterministic per-agent projections.
> [!IMPORTANT]
-> Agent Switch is **alpha software**. Today it is installed from source and the
-> macOS app is built locally; there is no signed, notarized public app, PyPI
-> package, or Homebrew formula yet. See the [roadmap](docs/roadmap.md).
+> Agent Switch is **alpha software**. The current installer builds from source
+> and requires Xcode. The intended public distribution is a Developer ID-signed,
+> notarized GitHub Release installed through Homebrew Cask. That release channel
+> is not available yet, so this README does not advertise a fake `brew` command.
## Quick start
@@ -26,74 +31,62 @@ credential store, and deterministic per-agent projections.
- Git
- Python 3.11 or newer
- [`pipx`](https://pipx.pypa.io/)
-- Full Xcode with `xcodebuild` for the native app
+- Full Xcode with `xcodebuild`
-### Install with your coding agent
+Install missing command-line prerequisites with:
-This is the recommended alpha installation path. Paste the prompt below into
-Codex, Claude Code, or another local coding agent:
+```bash
+brew install python pipx
+```
-```text
-Install and verify Agent Switch on this Mac instead of only explaining the steps.
-
-Repository: https://github.com/JNHFlow21/agent-switch
-Checkout: ~/Agent-Workspace/agent-switch
-
-1. Read the repository README and install script first. Verify macOS 14+, Git,
- Python 3.11+, pipx, and full Xcode. Install only missing prerequisites.
-2. Clone the repository at the checkout path, or update it with `git pull
- --ff-only` only when the existing worktree is clean. Never overwrite local work.
-3. Install the CLI from the checkout with pipx. Run both Python test suites,
- then run `macos-app/AgentSwitch/install.sh`.
-4. Initialize the config and run `agent-switch mcp import --dry-run --json`.
- Show me the detected MCP IDs, target apps, and required secret NAMES before
- adopting or writing native agent configs.
-5. Run Doctor before Reconcile. Apply changes only when no target is blocked,
- then verify `agent-switch doctor --strict`, `agent-switch agents`,
- `agent-switch mcp list`, and `agent-switch secret list`.
-6. Never request, print, log, or pass a secret as a command argument. Never put
- one in a project .env file. If a value is required, let me enter it in the
- app or pipe it locally to `agent-switch secret set --stdin NAME`.
-
-Report what was installed, which agents were enrolled, missing secret NAMES
-only, and any remaining action. Confirm that ~/Applications/Agent Switch.app opens.
+### Install
+
+Run one verified source-install command:
+
+```bash
+git clone https://github.com/JNHFlow21/agent-switch.git && cd agent-switch && ./scripts/install.sh
```
-Your first successful setup should produce all three results:
+The installer:
+
+1. verifies macOS, Python, pipx, and Xcode;
+2. installs the Python CLI in an isolated pipx environment;
+3. builds and installs the native app at `~/Applications/Agent Switch.app`;
+4. creates a neutral, empty Agent Switch config if none exists;
+5. opens the app without adopting MCPs or rewriting native agent configs.
+
+Expected first result:
```text
-agent-switch --version -> agent-switch 0.2.0
-agent-switch doctor --strict -> exits successfully with no managed drift
-Native app -> opens from ~/Applications/Agent Switch.app
+agent-switch --version -> agent-switch 0.2.0
+Native app -> opens from ~/Applications/Agent Switch.app
```
-
-Install manually from source
+Then preview your existing user-level command/stdio MCPs:
```bash
-brew install python pipx
-pipx ensurepath
-export PATH="$HOME/.local/bin:$PATH"
+agent-switch mcp import --dry-run --json
+agent-switch doctor
+```
-mkdir -p "$HOME/Agent-Workspace"
-git clone https://github.com/JNHFlow21/agent-switch.git \
- "$HOME/Agent-Workspace/agent-switch"
-cd "$HOME/Agent-Workspace/agent-switch"
+Review the detected MCP IDs, target apps, and required secret **names** before
+running `agent-switch mcp import --adopt` or `agent-switch reconcile`.
-pipx install .
-PYTHONPATH=src python3 -m unittest discover -s tests
-PYTHONPATH=src python3 -m unittest discover -s tests/integration
-macos-app/AgentSwitch/install.sh
+
+Why not npm, NPX, or a public Homebrew command?
-agent-switch write-default-config
-agent-switch mcp import --dry-run --json
-agent-switch doctor
-agent-switch reconcile
-agent-switch doctor --strict
+Agent Switch is a native macOS application with a Python CLI; Node.js is not
+part of its runtime. npm/NPX would add an unrelated dependency and still need
+to build or download the macOS app.
+
+The correct end-user channel is:
+
+```text
+signed + notarized release artifact -> GitHub Releases -> Homebrew Cask
```
-Review the import preview before using `agent-switch mcp import --adopt` on
-existing agent configurations.
+Until that artifact exists, the source installer above is the shortest honest
+path. See the [roadmap](docs/roadmap.md).
@@ -218,7 +211,7 @@ It does **not** yet provide:
- project-scoped MCP discovery;
- automatic support for unknown agents;
- a signed and notarized downloadable app;
-- published PyPI or Homebrew distribution;
+- a published Homebrew Cask or Python package;
- a password-manager or hardware-backed credential vault.
These are limitations, not hidden features. Planned work lives in the
@@ -252,17 +245,12 @@ agent-switch reconcile
See [Unified MCP Registry](docs/mcp-registry.md) for lifecycle commands and
safe import behavior.
-## Update from source
+## Update
+
+From the cloned repository:
```bash
-cd "$HOME/Agent-Workspace/agent-switch"
-git pull --ff-only
-pipx uninstall agent-switch
-pipx install .
-PYTHONPATH=src python3 -m unittest discover -s tests
-PYTHONPATH=src python3 -m unittest discover -s tests/integration
-macos-app/AgentSwitch/install.sh
-agent-switch doctor
+git pull --ff-only && ./scripts/install.sh
```
Agent Switch does not silently update itself, third-party CLIs, or Skill
diff --git a/README.zh-CN.md b/README.zh-CN.md
new file mode 100644
index 0000000..f622f51
--- /dev/null
+++ b/README.zh-CN.md
@@ -0,0 +1,273 @@
+
+ English · 简体中文
+
+
+# Agent Switch
+
+**每个 MCP 只定义一次,每个密钥只保存一次,再安全同步到所有支持的本地 AI Agent。**
+
+[](https://github.com/JNHFlow21/agent-switch/actions/workflows/ci.yml)
+[](https://www.apple.com/macos/)
+[](LICENSE)
+
+Codex、Claude Code、Claude Desktop 和 Hermes 都维护着各自的 MCP
+配置。把相同的服务器与密钥复制到每个客户端,不仅容易产生配置漂移,也会让密钥散落在多个文件中。
+
+Agent Switch 用一个本地 MCP 注册表、一个私密凭据存储和可重复生成的 Agent
+配置替代这些副本。
+
+> [!IMPORTANT]
+> Agent Switch 目前仍是 **Alpha 软件**。当前安装器会在本机从源码构建,因此需要
+> Xcode。正式面向用户的发行方式应当是经过 Developer ID 签名和 Apple 公证的
+> GitHub Release,并通过 Homebrew Cask 安装。这个发行通道尚未完成,所以这里不会
+> 放一个实际上不能使用的 `brew` 命令。
+
+## 快速开始
+
+### 前置条件
+
+- macOS 14 或更高版本
+- Git
+- Python 3.11 或更高版本
+- [`pipx`](https://pipx.pypa.io/)
+- 包含 `xcodebuild` 的完整 Xcode
+
+缺少命令行依赖时,可以运行:
+
+```bash
+brew install python pipx
+```
+
+### 安装
+
+运行下面这一条经过验证的源码安装命令:
+
+```bash
+git clone https://github.com/JNHFlow21/agent-switch.git && cd agent-switch && ./scripts/install.sh
+```
+
+安装器会:
+
+1. 检查 macOS、Python、pipx 和 Xcode;
+2. 在独立的 pipx 环境中安装 Python CLI;
+3. 构建原生应用并安装到 `~/Applications/Agent Switch.app`;
+4. 仅在配置不存在时创建一个中立、空白的 Agent Switch 配置;
+5. 打开应用,但不会自动接管 MCP,也不会改写原生 Agent 配置。
+
+首次安装成功后应当看到:
+
+```text
+agent-switch --version -> agent-switch 0.2.0
+原生应用 -> 从 ~/Applications/Agent Switch.app 打开
+```
+
+然后先预览已有的用户级 command/stdio MCP:
+
+```bash
+agent-switch mcp import --dry-run --json
+agent-switch doctor
+```
+
+在执行 `agent-switch mcp import --adopt` 或 `agent-switch reconcile`
+之前,请先检查检测到的 MCP ID、目标应用和所需密钥的**名称**。
+
+
+为什么不使用 npm、NPX 或直接写一个 Homebrew 命令?
+
+Agent Switch 是原生 macOS 应用加 Python CLI,Node.js 并不是它的运行时。
+npm/NPX 只会引入无关依赖,最终仍然需要构建或下载 macOS 应用。
+
+正确的用户发行链路应当是:
+
+```text
+签名并公证的发行产物 -> GitHub Releases -> Homebrew Cask
+```
+
+在这个产物真正存在之前,上面的源码安装器是最短且诚实的路径。详情见
+[路线图](docs/roadmap.md)。
+
+
+
+## 使用前后有什么变化
+
+| 使用 Agent Switch 之前 | 使用 Agent Switch 之后 |
+| --- | --- |
+| 同一个 MCP 要分别配置到每个 Agent | 注册一次,再选择需要同步到哪些 Agent |
+| API Key 被复制到多个原生客户端配置中 | 密钥值只保存在一个私密本地存储中 |
+| MCP 修改后,不同客户端会悄悄产生漂移 | `doctor` 发现漂移,`reconcile` 修复漂移 |
+| 每个 MCP 都可能继承完整的 Shell 环境 | 每个 Wrapper 只注入明确授权的密钥名称 |
+| 迁移现有配置像一次不可控的大改动 | 先预览,再明确确认接管,并自动备份 |
+
+新安装默认使用空注册表。Agent Switch 不会预装维护者喜欢的 MCP,也不会索取无关密钥。
+
+## 核心工作流
+
+```bash
+# 1. 只预览支持的用户级 stdio MCP,不修改文件
+agent-switch mcp import --dry-run --json
+
+# 2. 备份原生配置,并明确接管预览过的 MCP
+agent-switch mcp import --adopt
+
+# 3. 通过本地管道写入密钥,不把值放进参数或聊天记录
+secret-producing-command | agent-switch secret set --stdin SEARCH_API_KEY
+
+# 4. 先检查健康状态与漂移,再应用中央配置
+agent-switch doctor
+agent-switch reconcile
+
+# 5. 要求所有受管状态完全一致
+agent-switch doctor --strict
+```
+
+不要在被记录的命令中用真实密钥替换 `secret-producing-command`。
+macOS 应用是交互式录入密钥最简单的方式。
+
+## Agent Switch 管理什么
+
+| 领域 | 当前能力 |
+| --- | --- |
+| **MCP 服务** | 导入、新增、编辑、选择目标、启用、停用、删除并同步用户级 command/stdio MCP |
+| **凭据** | 每个值只保存一次,每个 MCP 只能获得明确声明的密钥名称 |
+| **Agent 策略** | 为 Codex、Claude Code 和 Hermes 同步有边界的指令块 |
+| **健康检查** | 检测无效配置、缺失密钥名称、未固定版本的 `npx` 包、受阻目标和配置漂移 |
+| **恢复** | 原子写入,并在迁移或替换原生文件前创建备份 |
+| **CLI 清单** | 显示本机 AI 工具、版本、包管理器和可执行文件路径 |
+| **Skills** | 读取可选的 Skill Hub 清单,但不会把“已下载”当成“已激活” |
+| **CC Switch** | 保留 Provider 切换,只镜像 Agent Switch 自己拥有的 MCP 行 |
+
+## 工作原理
+
+```mermaid
+flowchart LR
+ UI["macOS 应用或 CLI"] --> C["中央配置"]
+ C --> D["Doctor"]
+ D --> R["Reconcile"]
+ S["私密密钥存储"] --> W["每个 MCP 独立 Wrapper"]
+ R --> X["不含密钥的 Agent 配置"]
+ W --> M["MCP 进程"]
+ X --> A["Codex"]
+ X --> B["Claude Code / Desktop"]
+ X --> H["Hermes"]
+```
+
+| 本地事实来源 | 默认路径 |
+| --- | --- |
+| MCP 定义与授权 | `~/.config/agent-switch/config.json` |
+| 凭据值 | `~/.config/agent-switch/secrets.env` |
+| 生成的 MCP Wrapper | `~/.config/agent-switch/mcp/bin/` |
+| 原生配置备份 | `~/.config/agent-switch/backups/` |
+
+Agent Switch 只管理 `agent-*` MCP 条目和带标记的指令块。其他 Provider 与 MCP
+设置会被保留。
+
+## 支持的集成
+
+| 集成 | MCP 同步 | 共享策略 | 状态清单 |
+| --- | :---: | :---: | :---: |
+| Codex | ✓ | ✓ | ✓ |
+| Claude Code | ✓ | ✓ | ✓ |
+| Claude Desktop | ✓ | — | — |
+| Hermes | ✓ | ✓ | ✓ |
+| CC Switch | 仅镜像自己拥有的行 | 保留 Provider 设置 | Schema 检查 |
+| Skill Hub | Skill 清单/更新 | 显式项目或全局 Profile | ✓ |
+
+新增 Agent 必须先实现并测试专用适配器。Agent Switch 不会猜测未知配置格式。
+
+## 凭据与隐私边界
+
+Agent Switch 是本地优先工具,但它**不是密码保险库**。
+
+- 凭据值保存在本地 mode-`0600` 文件中,不进入 Git、应用偏好、生成的
+ Agent 配置或 Wrapper 源码。
+- 写入密钥使用 stdin 或继承的文件描述符,不使用位置参数。
+- 读取密钥时拒绝 stdout、stderr、终端和别名描述符。
+- Wrapper 把密钥文件当数据解析,移除继承的敏感变量,只注入当前 MCP
+ 获得授权的名称。
+- 诊断、导入预览和审计只报告密钥**名称**,不报告值。
+- 缺少必需密钥名称时,Wrapper 会关闭失败。
+- 产品没有上传服务或云账户;但 Agent 调用某个 MCP 时,该 MCP 仍可能访问自己的服务商。
+
+使用敏感凭据前,请阅读[密钥与 Wrapper](docs/secrets-and-wrappers.md)和
+[安全策略](SECURITY.md)。安全问题应按照 `SECURITY.md` 的私密渠道报告,不要创建公开 Issue。
+
+## 当前 Alpha 范围
+
+0.2 版本管理 macOS 上用户级 command/stdio MCP 定义和静态凭据值。
+
+目前尚未提供:
+
+- 原生 HTTP/SSE Transport 或 OAuth Session 迁移;
+- 项目级 MCP 发现;
+- 对未知 Agent 的自动支持;
+- 已签名并公证的可下载应用;
+- 已发布的 Homebrew Cask 或 Python 包;
+- 密码管理器或硬件保护的凭据保险库。
+
+这些是明确限制,不是隐藏功能。计划中的工作记录在[路线图](docs/roadmap.md)中。
+
+## 常用命令
+
+```bash
+agent-switch agents # 检测到的 Agent 与策略接入状态
+agent-switch clis # 已安装的 AI CLI 清单
+agent-switch mcp list # 中央 MCP 注册表
+agent-switch secret list # 只显示凭据名称
+agent-switch skills # 可选的 Skill Hub 清单
+agent-switch doctor --json # 机器可读的健康报告
+agent-switch reconcile --dry-run # 计划执行的受管变更
+```
+
+新增一个中央管理的 MCP:
+
+```bash
+agent-switch mcp add filesystem \
+ --command npx \
+ --arg=-y \
+ --arg=@modelcontextprotocol/server-filesystem@1.0.0 \
+ --app codex \
+ --app claude
+
+agent-switch reconcile
+```
+
+完整生命周期命令和安全导入行为见[统一 MCP 注册表](docs/mcp-registry.md)。
+
+## 更新
+
+在已经克隆的仓库中运行:
+
+```bash
+git pull --ff-only && ./scripts/install.sh
+```
+
+Agent Switch 不会静默更新自己、第三方 CLI 或 Skill 源。
+
+## 文档
+
+- [统一 MCP 注册表](docs/mcp-registry.md)
+- [密钥与 Wrapper](docs/secrets-and-wrappers.md)
+- [CC Switch 兼容性](docs/ccswitch-compat.md)
+- [恢复与回滚](docs/recovery.md)
+- [路线图](docs/roadmap.md)
+- [参与贡献](CONTRIBUTING.md)
+- [安全策略](SECURITY.md)
+
+## 开发
+
+```bash
+git clone https://github.com/JNHFlow21/agent-switch.git
+cd agent-switch
+python3 -m venv .venv
+. .venv/bin/activate
+python -m pip install -e .
+python -m unittest discover -s tests
+python -m unittest discover -s tests/integration
+```
+
+原生应用位于 [`macos-app/AgentSwitch`](macos-app/AgentSwitch),最低支持
+macOS 14。完整测试和隐私门禁见 [CONTRIBUTING.md](CONTRIBUTING.md)。
+
+## 许可证
+
+[MIT](LICENSE) © 2026 JNHFlow21
diff --git a/docs/roadmap.md b/docs/roadmap.md
index 47e221d..f583829 100644
--- a/docs/roadmap.md
+++ b/docs/roadmap.md
@@ -23,8 +23,9 @@ distribution.
explicit ownership choice before adoption.
3. Add adapters through a documented contract and fixture suite rather than
guessing unknown agent configuration formats.
-4. Ship a signed and notarized macOS release, a verified installer, published
- Python packages, and a Homebrew path.
+4. Ship a Developer ID-signed and notarized macOS release that packages the app
+ and CLI together, publish it through GitHub Releases, and make Homebrew Cask
+ the one-line end-user install path.
5. Add complete English and Chinese localization plus a first-run wizard that
previews targets, MCP IDs, and secret names before any write.
6. Add a first-class backup browser and guided restore flow.
diff --git a/scripts/install.sh b/scripts/install.sh
new file mode 100755
index 0000000..6ede6e0
--- /dev/null
+++ b/scripts/install.sh
@@ -0,0 +1,53 @@
+#!/bin/zsh
+set -euo pipefail
+
+ROOT="${0:A:h:h}"
+
+fail() {
+ print -u2 "Agent Switch install failed: $*"
+ exit 1
+}
+
+[[ "$(uname -s)" == "Darwin" ]] || fail "macOS is required."
+command -v python3 >/dev/null 2>&1 || fail "Python 3.11 or newer is required."
+command -v pipx >/dev/null 2>&1 || fail "pipx is required. Install it with: brew install pipx"
+command -v xcodebuild >/dev/null 2>&1 || fail "Full Xcode with xcodebuild is required."
+
+python3 - <<'PY' || fail "Python 3.11 or newer is required."
+import sys
+
+raise SystemExit(sys.version_info < (3, 11))
+PY
+
+xcodebuild -version >/dev/null 2>&1 || fail "Select a full Xcode installation with xcode-select."
+
+print "Installing Agent Switch CLI..."
+if ! pipx install --force "$ROOT"; then
+ print "The existing pipx environment could not be refreshed; recreating it..."
+ pipx uninstall agent-switch >/dev/null 2>&1 || true
+ pipx install "$ROOT"
+fi
+
+PIPX_BIN_DIR="$(pipx environment --value PIPX_BIN_DIR)"
+CLI="$PIPX_BIN_DIR/agent-switch"
+[[ -x "$CLI" ]] || fail "pipx installed the package but the agent-switch executable was not found."
+"$CLI" --version
+
+print "Building and installing the native macOS app..."
+"$ROOT/macos-app/AgentSwitch/install.sh"
+
+"$CLI" write-default-config
+
+cat < None:
readme = (ROOT / "README.md").read_text()
+ readme_zh = (ROOT / "README.zh-CN.md").read_text()
compat = (ROOT / "docs" / "ccswitch-compat.md").read_text()
recovery = (ROOT / "docs" / "recovery.md").read_text()
secrets = (ROOT / "docs" / "secrets-and-wrappers.md").read_text()
@@ -17,6 +18,14 @@ def test_docs_reference_current_commands_and_boundaries(self) -> None:
roadmap = (ROOT / "docs" / "roadmap.md").read_text()
instructions = (ROOT / "src" / "agent_switch" / "instructions.py").read_text()
self.assertIn("agent-switch doctor", readme)
+ self.assertIn("README.zh-CN.md", "\n".join(readme.splitlines()[:12]))
+ self.assertIn("README.md", "\n".join(readme_zh.splitlines()[:12]))
+ install_command = (
+ "git clone https://github.com/JNHFlow21/agent-switch.git && "
+ "cd agent-switch && ./scripts/install.sh"
+ )
+ self.assertIn(install_command, readme)
+ self.assertIn(install_command, readme_zh)
self.assertIn("agent-*", compat)
self.assertIn("CC Switch", compat)
self.assertIn("agent-switch reconcile", recovery)