diff --git a/README.md b/README.md
index 2f5ae88..9fd404f 100644
--- a/README.md
+++ b/README.md
@@ -1,143 +1,221 @@
# Codex 账号切换工具
-Codex 账号切换工具是一个本地桌面应用,用来在同一台机器上管理多个 Codex 账号。它通过本地账号备份目录保存不同账号状态,支持切换当前账号、查看账号状态和额度信息,并提供 macOS 与 Windows 原生 Tauri 桌面界面。
+
+ 简体中文 |
+ 中文(备份) |
+ Changelog |
+ Releases
+
-`macOS-backup/` 里的 shell 脚本仍然保留,作为兼容旧流程的入口;当前主要方向是原生桌面端。
+
+
+
+
+
+
+
-## 当前功能
+**Codex 账号切换工具**(Codex Switch)是一个面向 **OpenAI Codex CLI** 的本地桌面账号管理器。它把多份 `~/.codex/{auth.json,config.toml,sessions/...}` 状态各自打包到独立账号备份目录,一键切换"当前 Codex 账号",并把每个账号的 plan / 5 小时额度 / 周额度直接渲染在桌面端。
-- 仪表盘:显示当前账号、账号总数、可用账号和待登录账号数量。
-- 账号页:每页 8 个账号条目(横向单行布局:账号名 + 套餐 / 5 小时与周额度 / 操作按钮),支持切换、登录刷新、重命名、删除或清空、打开账号目录、编辑 Base URL。登录中点击同一按钮可取消(向 codex login 发送 SIGTERM / taskkill),适用于 OAuth 浏览器关闭后应用卡在等待回调的场景。
-- 设置页:包含语言、主题、更新地址、版本、许可证、检查更新、GitHub 入口,以及 **Codex CLI 路径**(显示当前路径与来源标签,自动定位失败或路径错误时随时手动指定,写入 `install_state.json` 的 `user_codex_path` 优先级最高)。
-- 引导页:展示添加账号、登录、切换账号的基础流程。
-- 支持多套浅色和深色主题、中英文界面,以及没有 Tauri API 时的本地预览数据。
+跟纯账号切换脚本不同,本项目内置 **plan / quota 直读**:登录后通过 ChatGPT OAuth 的 `id_token` + ChatGPT Web API `account/rateLimits` / Codex app-server JSON-RPC fallback 拉取真实计划等级和 rate-limit 窗口剩余比例,不需要本地解析 Codex sessions/jsonl 日志即可看到每个账号"还能用多久"。
-## 平台支持
+当前版本 **v1.5.10**(详见 [CHANGELOG](CHANGELOG.md) 与 [Releases](https://github.com/Cmochance/Codex_Account_Switch/releases))。
-- macOS:原生 Tauri 桌面端,同时保留 `macOS-backup/` 下的兼容脚本。
-- Windows:原生 Tauri 桌面端,通过 Release 中的 `.exe` 分发。
+## 能做什么
-平台专属逻辑优先放在 `src-tauri/mac/**` 或 `src-tauri/win/**` 下。`src-tauri/shared/**` 只放共享前端模块、命令契约、运行时模型和中立的跨平台逻辑。
+- 同一台机器多账号管理:每个账号一个备份目录(含独立的 `auth.json` / `config.toml` / `sessions/`),切换时把目标账号 swap 进 `~/.codex/`,旧账号自动归档到备份目录。
+- **账号页**:每页 8 个账号条目,横向单行布局展示「账号名 + 套餐」「5 小时额度 + 刷新时间」「周额度 + 刷新时间」「删除 / 重命名 / 刷新 / 登录 / Base / 切换」按钮。
+- **登录可取消**:进行中的 `codex login` OAuth 流程支持点击同一按钮取消(向子进程 SIGTERM / taskkill),解决浏览器关闭后应用卡在等待回调的场景。
+- **plan / quota 智能缓存**:bulk plan refresh 在 6 小时窗口内跳过已确认账号,per-card 刷新按钮也共享同一缓存;切换 / 登录 / 刷新后直接复用 backend 写回的 snapshot,不重复发 IPC。
+- **Custom Base URL**:每个账号可独立配置 `OPENAI_BASE_URL`;配置后按钮变红警示(自定义 Base 与 ChatGPT OAuth 账号互斥)。
+- **Codex CLI 路径自检**:自动定位 `codex` 可执行(PATH / `~/.codex/bin` / Homebrew / nvm),找不到或路径错误时设置页可手动指定,结果写入 `install_state.json` 优先生效。
+- **跨平台原生 Tauri**:macOS arm64 与 Windows x64 提供原生窗口、原生标题栏 / 关闭按钮,配套 5 套浅色 / 深色主题与中英文界面。
+- **本地预览模式**:没有 Tauri 运行时(直接 `vite` 跑前端)时自动使用 mock snapshot,方便单纯调样式。
-## 仓库结构
+## 下载
-- `src-tauri/`:Rust 与 Tauri 应用根目录。
-- `src-tauri/mac/front/`:macOS HTML 壳、样式和窗口控制。
-- `src-tauri/win/front/`:Windows HTML 壳、样式和窗口控制。
-- `src-tauri/shared/front/`:共享前端状态、渲染、动作、主题、国际化和 Tauri 桥接。
-- `src-tauri/mac/runtime/`:macOS 运行时集成。
-- `src-tauri/win/runtime/`:Windows 运行时集成。
-- `src-tauri/shared/runtime/`:共享模型、账号数据处理、更新检查、路径、元数据和切换核心逻辑。
-- `src-tauri/shared/commands/`:暴露给前端的 Tauri 命令处理层。
-- `macOS-backup/`:旧 shell 流程和桌面桥接的兼容安装、卸载脚本。
-- `examples/account_backup/demo/`:示例 `auth.json` 模板。
-- `scripts/`:版本同步、macOS 产物布局和 macOS `.pkg` 生成脚本。
+最新版:
-生成文件不进仓库。前端网页构建输出放在 `dist/web/`,macOS 桌面端打包产物直接落到 `dist/` 根目录。
+资产命名:
-## 开发
+```text
+codex_switch_<版本>_aarch64.dmg macOS Apple Silicon DMG(拖拽到 Applications)
+codex_switch_<版本>_aarch64.pkg macOS Apple Silicon PKG 安装包
+codex_switch_<版本>_x64-setup.exe Windows x64 NSIS 安装包
+```
-安装依赖:
+> macOS / Windows 都暂未做代码签名,首次启动可能提示「未知开发者 / 未知发布者」;macOS 可在「系统设置 → 隐私与安全」放行,Windows 可在 SmartScreen 弹窗点「更多信息 → 仍要运行」。
-```bash
-npm install
-```
+## 快速开始
-启动前端和 Tauri 开发应用:
+1. 从 Releases 下载并安装 Codex Switch,启动桌面窗口。
+2. 进入「设置」页,确认 **Codex CLI 路径** 已自动填好(默认探测 PATH / `~/.codex/bin`);缺失时手动指定,状态变绿即可。
+3. 进入「账号」页,点「添加账号」→ 输入账号别名(落地为 `~/.codex/account_backup/<别名>/`)。
+4. 在新账号条目点「登录」→ 浏览器完成 ChatGPT OAuth → 回到应用,套餐 + 额度自动加载。
+5. 多账号场景:在目标条目点「切换」即可一键替换当前 `~/.codex/`,原账号自动归档。
+6. 需要清空 quota cache 或重新拉计划时,点对应账号的「刷新」(≥ 6h 走完整 OAuth rotation,< 6h 复用缓存)。
-```bash
-npm run tauri:dev
-```
+## 仓库结构
-只构建前端:
+- `src-tauri/`:Rust + Tauri 应用根目录。
+- `src-tauri/mac/front/`:macOS HTML 壳、样式、原生窗口控制。
+- `src-tauri/win/front/`:Windows HTML 壳、样式、自绘标题栏与窗口按钮。
+- `src-tauri/shared/front/`:跨平台前端 — state / render / actions / theme / i18n / Tauri bridge / mock preview。
+- `src-tauri/mac/runtime/` / `src-tauri/win/runtime/`:各自平台的 runtime adapter(profile_actions / switch / login spawn)。
+- `src-tauri/shared/runtime/`:共享 runtime — `chatgpt_api`、`models`、`switch_core`、`profiles_index`、`paths`、`metadata`、`process_lock`、`fs_ops`。
+- `src-tauri/shared/commands/`:前端可见的 Tauri command 层(dashboard / switch / profile lifecycle)。
+- `macOS-backup/`:兼容老的 shell 流程(`install.sh` / `uninstall.sh` / `codex-switch.sh`),用于 desktop 不可用的回退场景。
+- `scripts/`:version-sync、macOS 产物布局、`.pkg` 生成、CHANGELOG 校验。
+- `examples/account_backup/demo/`:`auth.json` / `profile.json` 占位模板,演示账号备份目录结构。
+- `docs/`:发布、实现笔记、安全说明、上游协议参考。
-```bash
-npm run build
-```
+构建输出(`dist/`、`src-tauri/target/`、`node_modules/`、`.app` / `.dmg` / `.pkg` / `.exe`)全部 .gitignore,不入仓。
-运行 Rust 测试:
+## 本地开发
```bash
-npm run test:rust
+npm install
+npm run tauri:dev # 起 Tauri 桌面 dev 窗口 + Vite HMR
+npm run build # 仅前端 production build(vite + tsc)
+npm run test # cargo test --manifest-path src-tauri/Cargo.toml
+npm run check:rust:windows # cross check Windows target(macOS 本地交叉验证)
+npm run test:rust:windows # 在 Windows runner 上跑(CI 主用)
```
## 桌面端打包
-Tauri 2 没有提供 bundle 输出目录配置。macOS 打包脚本会在运行 Tauri 前,把 `src-tauri/target/release/bundle/macos` 和 `src-tauri/target/release/bundle/dmg` 准备成指向 `dist/` 的链接。Tauri 仍然写入它自己的固定 bundle 路径,但实际 `.app` 和 `.dmg` 会直接落到 `dist/`;`.pkg` 生成脚本也直接写入 `dist/`。
+Tauri 2 没暴露 bundle 输出目录配置,macOS 打包脚本在 `tauri build` 前把 `src-tauri/target/release/bundle/macos` 与 `bundle/dmg` symlink 到 `dist/`,把最终 `.app` / `.dmg` / `.pkg` 直接落到仓库根目录的 `dist/`。
-本地测试阶段只打包 `.app`:
+本地仅打包 `.app`(用于手测,不签名):
```bash
npm run tauri:build:macos-app
```
-`.app` 写入 `dist/` 后,会删除构建过程中生成的裸 macOS 可执行中间产物。
-
-最终发布阶段打包 `.dmg` 和 `.pkg`:
+发布构建(`.dmg` + `.pkg`):
```bash
npm run tauri:build:macos-release
```
-最终发布流程会把 `.app` 作为打包输入,随后从 `dist/` 中移除 `.app`,只把发布用安装包保留在 `dist/` 根目录。`dist/` 根目录里的旧版本 `.dmg` 和 `.pkg` 会移动到 `dist/history/` 下对应的版本命名文件夹中;重复构建当前版本时会替换当前根目录安装包,不再额外备份。
+发布构建的 `.app` 会作为打包输入参与签名 / notarization 链路(CI 跑),随后从 `dist/` 移除,只保留 `.dmg` / `.pkg`。旧版本产物会移动到 `dist/history/v<旧版本>/` 下归档;重复构建当前版本只替换根目录的当前文件,不会再额外备份。
-预期本地产物结构:
+期望产物结构:
```text
dist/
- codex_switch__.dmg
- codex_switch__.pkg
+ codex_switch_<版本>_aarch64.dmg
+ codex_switch_<版本>_aarch64.pkg
+ codex_switch_<版本>_x64-setup.exe (Windows runner)
history/
- v/
+ v<旧版本>/
...
web/
...
```
+Windows 构建走 CI 的 `tauri build --target x86_64-pc-windows-msvc`;本地 macOS 上一般只跑 `check:rust:windows` 做类型检查。
+
## 版本与发布
-- 项目版本保存在 `package.json`,并同步到 Tauri 和 Cargo 元数据。
-- GitHub Release 标签使用完整语义版本号,例如 `1.5.3`。
-- 每个补丁版本单独创建一个 Release 标签。
-- 不要把补丁版本产物上传到旧的两段式标签下,例如不要继续把 `1.5.x` 上传到 `1.5`。
-- macOS 安装包作为 Release 资产发布,不提交到 Git。
+- 版本号源头是 `package.json`,`npm run version:sync` / `npm run version:set -- ` 把同一版本写到 `package-lock.json`、`src-tauri/Cargo.toml`、`src-tauri/Cargo.lock`,并在 `src-tauri/mac/front/index.html` / `win/front/index.html` 通过 Vite-injected `__CODEX_APP_VERSION__` 渲染到设置页。
+- GitHub Release tag 用完整 semver(如 `v1.5.10`)。push tag → `.github/workflows/build.yml` 自动跑 macOS arm64 + Windows x64 构建并把产物上传到一个 **draft release**,不会自动转 Latest。
+- 不要把补丁版本的 asset 上传到旧的两段式 tag(如 `1.5`)。
+- macOS 安装包仅作 Release asset 发布,不提交到 Git。
常用命令:
```bash
-npm run version:sync
-npm run version:set -- 1.5.4
+npm run version:sync # 把 package.json 当前 version 同步到 Cargo / lock
+npm run version:set -- 1.5.11 # 一次性 bump 到指定版本
+npm run version:check # CI 用:拒绝把 semver 字面量写回 *.html
```
+## 常见问题
+
+### 没有 Codex CLI 怎么办
+
+应用启动后会探测 `codex` 路径;探测失败时设置页会标红「Codex CLI 路径未找到」,可手动指定(写入 `install_state.json` 的 `user_codex_path` 优先级最高)。未装 Codex CLI 也能用 plan / quota 查看(走 ChatGPT OAuth token 直接拉 rate-limits),但「登录」按钮和切换后启动 Codex 等动作需要 CLI 存在。
+
+### 切换账号会丢失原账号的 sessions / 历史吗
+
+不会。切换时整个 `~/.codex/` 子集(`auth.json` / `config.toml` / `sessions/`)被原子归档到原账号的备份目录,目标账号的同名内容覆盖回 `~/.codex/`。再切回来时全部恢复。
+
+### 「刷新」按钮和「切换」之后会不会消耗 quota
+
+不会真发 ChatGPT 对话请求。Plan 数据来自 `id_token` claims;quota 走 ChatGPT Web API `account/rateLimits/read`(HTTP GET),或 Codex 0.130+ 的 `app-server` JSON-RPC fallback。没有 LLM 调用,不消耗用户额度。
+
+### per-card「登录」按钮为什么有时变成「取消」
+
+当 codex 进程已经起来并打开了浏览器,但 OAuth 回调没回来(用户关浏览器 / 网络异常),点同一按钮会向 codex login 子进程发 SIGTERM / taskkill 中止它,释放 `.switch.lock` 全局锁。
+
+### Custom Base URL 配置后能继续用 ChatGPT OAuth 吗
+
+不能。Custom Base URL(指向第三方 OpenAI 兼容反代)和 ChatGPT 官方 OAuth 是互斥的 — OAuth `id_token` 校验只对官方 endpoint 生效。配置 Base 之后该卡片的「Base」按钮会变红警示。
+
+### macOS 提示「无法打开,因为无法验证开发者」
+
+App 暂未做 Apple Developer 代码签名 / notarization。第一次启动按住 Control 点应用图标 → 选「打开」一次即可放行;后续直接双击就行。或在「系统设置 → 隐私与安全」放行。
+
+### Windows SmartScreen 提示「Windows 已保护你的电脑」
+
+同上,未做 Authenticode 签名。SmartScreen 弹窗点「更多信息 → 仍要运行」即可。
+
+### 日志和账号数据存在哪里
+
+- 账号备份:`~/.codex/account_backup/<别名>/`(macOS / Linux)/ `%USERPROFILE%\.codex\account_backup\<别名>\`(Windows)
+- 应用运行时 cache:`~/.codex-switch/`(plan / quota 缓存、`install_state.json`、`switch.lock`)
+- Codex 当前账号状态:`~/.codex/auth.json` + `~/.codex/config.toml`
+
+## 技术栈
+
+- **后端 / runtime**:Rust 1.80+ · Tauri 2.x · tokio + reqwest(rustls-tls)· chrono · serde
+- **协议适配**:`shared/runtime/chatgpt_api.rs`(ChatGPT Web API `account/{read,rateLimits/read}`)+ Codex app-server JSON-RPC fallback(`codex` ≥ 0.130 时 OAuth refresh 失败兜底)
+- **前端**:HTML + CSS + 原生 TypeScript(`shared/front/{render,state,actions,theme,i18n,tauri}.ts`),无前端框架;Vite 7 打包
+- **跨平台 runtime**:mac / win runtime 各自实现 spawn / process control / OS-native title bar;shared runtime 处理协议、profile lifecycle、JSON-RPC、缓存、文件锁
+- **构建 / 发布**:`tauri build` 单命令出 dmg / pkg / exe;`.github/workflows/build.yml` 出 draft release,全部 asset 由 GitHub Actions 上传
+
+## 平台支持
+
+- **macOS**:原生 Tauri 桌面端(Apple Silicon),同时保留 `macOS-backup/` 下的 legacy shell 流程兼容。
+- **Windows**:原生 Tauri 桌面端(x64),通过 Release 中的 `.exe` 分发。
+- **Linux**:暂未做正式发布;前端代码跨平台,理论可自行 `cargo tauri build` 出 AppImage / deb,但 macOS-backup 与 Codex CLI 路径探测未覆盖 Linux 路径约定。
+
+平台专属逻辑放在 `src-tauri/mac/**` 或 `src-tauri/win/**`,跨平台逻辑都在 `src-tauri/shared/**`。
+
## macOS 兼容脚本
-通过兼容入口安装:
+老的 shell 流程仍然保留,作为桌面 GUI 不可用 / SSH 终端场景的兜底:
```bash
bash macOS-backup/install.sh
source ~/.zshrc
```
-支持三种模式:
+三种模式:
-- `auto`:优先尝试原生桌面运行时,找不到时回退到 legacy shell 流程。
-- `desktop`:强制使用原生桌面运行时。
-- `legacy`:强制使用原来的 shell 版 `codex-switch.sh` 流程。
+- `auto`:优先尝试原生桌面 runtime,找不到回退到 legacy shell。
+- `desktop`:强制走原生桌面。
+- `legacy`:强制走 `codex-switch.sh`。
卸载:
```bash
-bash macOS-backup/uninstall.sh
-bash macOS-backup/uninstall.sh --remove-script
+bash macOS-backup/uninstall.sh # 只移除命令接入层
+bash macOS-backup/uninstall.sh --remove-script # 连脚本一起删
source ~/.zshrc
```
-卸载脚本只移除受管理的命令接入层,不会删除账号备份目录;账号目录需要时手动清理。
+卸载脚本不会删 `~/.codex/account_backup/`,账号目录需要时手动清理。
+
+## 免责声明
+
+本项目专注 **OpenAI Codex CLI 多账号管理**,**不是** OpenAI 官方项目,也不复用其商标 / Logo / 发布身份。
-## Windows 安装
+所有账号凭据 / OAuth token 仅保存在本机 `~/.codex/account_backup/`(Unix 0600 + atomic write);plan / quota 通过 HTTPS 直连 `chatgpt.com` / `api.openai.com`,不经任何第三方中转。
-在仓库 Releases 页面下载最新 Windows `.exe`。
+ChatGPT OAuth `id_token` / `access_token` 仅用于读取计划与 rate-limit 元数据,不会向模型发起任何对话请求,因此不会消耗用户额度。
-## 账号数据
+## 许可证
-账号数据只保存在本机。导出的配置或账号备份可能包含 API Key 或认证数据,只应保存在可信设备上。
+MIT License。完整文本见 [LICENSE](LICENSE).
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 2f5ae88..9fd404f 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1,143 +1,221 @@
# Codex 账号切换工具
-Codex 账号切换工具是一个本地桌面应用,用来在同一台机器上管理多个 Codex 账号。它通过本地账号备份目录保存不同账号状态,支持切换当前账号、查看账号状态和额度信息,并提供 macOS 与 Windows 原生 Tauri 桌面界面。
+
+ 简体中文 |
+ 中文(备份) |
+ Changelog |
+ Releases
+
-`macOS-backup/` 里的 shell 脚本仍然保留,作为兼容旧流程的入口;当前主要方向是原生桌面端。
+
+
+
+
+
+
+
-## 当前功能
+**Codex 账号切换工具**(Codex Switch)是一个面向 **OpenAI Codex CLI** 的本地桌面账号管理器。它把多份 `~/.codex/{auth.json,config.toml,sessions/...}` 状态各自打包到独立账号备份目录,一键切换"当前 Codex 账号",并把每个账号的 plan / 5 小时额度 / 周额度直接渲染在桌面端。
-- 仪表盘:显示当前账号、账号总数、可用账号和待登录账号数量。
-- 账号页:每页 8 个账号条目(横向单行布局:账号名 + 套餐 / 5 小时与周额度 / 操作按钮),支持切换、登录刷新、重命名、删除或清空、打开账号目录、编辑 Base URL。登录中点击同一按钮可取消(向 codex login 发送 SIGTERM / taskkill),适用于 OAuth 浏览器关闭后应用卡在等待回调的场景。
-- 设置页:包含语言、主题、更新地址、版本、许可证、检查更新、GitHub 入口,以及 **Codex CLI 路径**(显示当前路径与来源标签,自动定位失败或路径错误时随时手动指定,写入 `install_state.json` 的 `user_codex_path` 优先级最高)。
-- 引导页:展示添加账号、登录、切换账号的基础流程。
-- 支持多套浅色和深色主题、中英文界面,以及没有 Tauri API 时的本地预览数据。
+跟纯账号切换脚本不同,本项目内置 **plan / quota 直读**:登录后通过 ChatGPT OAuth 的 `id_token` + ChatGPT Web API `account/rateLimits` / Codex app-server JSON-RPC fallback 拉取真实计划等级和 rate-limit 窗口剩余比例,不需要本地解析 Codex sessions/jsonl 日志即可看到每个账号"还能用多久"。
-## 平台支持
+当前版本 **v1.5.10**(详见 [CHANGELOG](CHANGELOG.md) 与 [Releases](https://github.com/Cmochance/Codex_Account_Switch/releases))。
-- macOS:原生 Tauri 桌面端,同时保留 `macOS-backup/` 下的兼容脚本。
-- Windows:原生 Tauri 桌面端,通过 Release 中的 `.exe` 分发。
+## 能做什么
-平台专属逻辑优先放在 `src-tauri/mac/**` 或 `src-tauri/win/**` 下。`src-tauri/shared/**` 只放共享前端模块、命令契约、运行时模型和中立的跨平台逻辑。
+- 同一台机器多账号管理:每个账号一个备份目录(含独立的 `auth.json` / `config.toml` / `sessions/`),切换时把目标账号 swap 进 `~/.codex/`,旧账号自动归档到备份目录。
+- **账号页**:每页 8 个账号条目,横向单行布局展示「账号名 + 套餐」「5 小时额度 + 刷新时间」「周额度 + 刷新时间」「删除 / 重命名 / 刷新 / 登录 / Base / 切换」按钮。
+- **登录可取消**:进行中的 `codex login` OAuth 流程支持点击同一按钮取消(向子进程 SIGTERM / taskkill),解决浏览器关闭后应用卡在等待回调的场景。
+- **plan / quota 智能缓存**:bulk plan refresh 在 6 小时窗口内跳过已确认账号,per-card 刷新按钮也共享同一缓存;切换 / 登录 / 刷新后直接复用 backend 写回的 snapshot,不重复发 IPC。
+- **Custom Base URL**:每个账号可独立配置 `OPENAI_BASE_URL`;配置后按钮变红警示(自定义 Base 与 ChatGPT OAuth 账号互斥)。
+- **Codex CLI 路径自检**:自动定位 `codex` 可执行(PATH / `~/.codex/bin` / Homebrew / nvm),找不到或路径错误时设置页可手动指定,结果写入 `install_state.json` 优先生效。
+- **跨平台原生 Tauri**:macOS arm64 与 Windows x64 提供原生窗口、原生标题栏 / 关闭按钮,配套 5 套浅色 / 深色主题与中英文界面。
+- **本地预览模式**:没有 Tauri 运行时(直接 `vite` 跑前端)时自动使用 mock snapshot,方便单纯调样式。
-## 仓库结构
+## 下载
-- `src-tauri/`:Rust 与 Tauri 应用根目录。
-- `src-tauri/mac/front/`:macOS HTML 壳、样式和窗口控制。
-- `src-tauri/win/front/`:Windows HTML 壳、样式和窗口控制。
-- `src-tauri/shared/front/`:共享前端状态、渲染、动作、主题、国际化和 Tauri 桥接。
-- `src-tauri/mac/runtime/`:macOS 运行时集成。
-- `src-tauri/win/runtime/`:Windows 运行时集成。
-- `src-tauri/shared/runtime/`:共享模型、账号数据处理、更新检查、路径、元数据和切换核心逻辑。
-- `src-tauri/shared/commands/`:暴露给前端的 Tauri 命令处理层。
-- `macOS-backup/`:旧 shell 流程和桌面桥接的兼容安装、卸载脚本。
-- `examples/account_backup/demo/`:示例 `auth.json` 模板。
-- `scripts/`:版本同步、macOS 产物布局和 macOS `.pkg` 生成脚本。
+最新版:
-生成文件不进仓库。前端网页构建输出放在 `dist/web/`,macOS 桌面端打包产物直接落到 `dist/` 根目录。
+资产命名:
-## 开发
+```text
+codex_switch_<版本>_aarch64.dmg macOS Apple Silicon DMG(拖拽到 Applications)
+codex_switch_<版本>_aarch64.pkg macOS Apple Silicon PKG 安装包
+codex_switch_<版本>_x64-setup.exe Windows x64 NSIS 安装包
+```
-安装依赖:
+> macOS / Windows 都暂未做代码签名,首次启动可能提示「未知开发者 / 未知发布者」;macOS 可在「系统设置 → 隐私与安全」放行,Windows 可在 SmartScreen 弹窗点「更多信息 → 仍要运行」。
-```bash
-npm install
-```
+## 快速开始
-启动前端和 Tauri 开发应用:
+1. 从 Releases 下载并安装 Codex Switch,启动桌面窗口。
+2. 进入「设置」页,确认 **Codex CLI 路径** 已自动填好(默认探测 PATH / `~/.codex/bin`);缺失时手动指定,状态变绿即可。
+3. 进入「账号」页,点「添加账号」→ 输入账号别名(落地为 `~/.codex/account_backup/<别名>/`)。
+4. 在新账号条目点「登录」→ 浏览器完成 ChatGPT OAuth → 回到应用,套餐 + 额度自动加载。
+5. 多账号场景:在目标条目点「切换」即可一键替换当前 `~/.codex/`,原账号自动归档。
+6. 需要清空 quota cache 或重新拉计划时,点对应账号的「刷新」(≥ 6h 走完整 OAuth rotation,< 6h 复用缓存)。
-```bash
-npm run tauri:dev
-```
+## 仓库结构
-只构建前端:
+- `src-tauri/`:Rust + Tauri 应用根目录。
+- `src-tauri/mac/front/`:macOS HTML 壳、样式、原生窗口控制。
+- `src-tauri/win/front/`:Windows HTML 壳、样式、自绘标题栏与窗口按钮。
+- `src-tauri/shared/front/`:跨平台前端 — state / render / actions / theme / i18n / Tauri bridge / mock preview。
+- `src-tauri/mac/runtime/` / `src-tauri/win/runtime/`:各自平台的 runtime adapter(profile_actions / switch / login spawn)。
+- `src-tauri/shared/runtime/`:共享 runtime — `chatgpt_api`、`models`、`switch_core`、`profiles_index`、`paths`、`metadata`、`process_lock`、`fs_ops`。
+- `src-tauri/shared/commands/`:前端可见的 Tauri command 层(dashboard / switch / profile lifecycle)。
+- `macOS-backup/`:兼容老的 shell 流程(`install.sh` / `uninstall.sh` / `codex-switch.sh`),用于 desktop 不可用的回退场景。
+- `scripts/`:version-sync、macOS 产物布局、`.pkg` 生成、CHANGELOG 校验。
+- `examples/account_backup/demo/`:`auth.json` / `profile.json` 占位模板,演示账号备份目录结构。
+- `docs/`:发布、实现笔记、安全说明、上游协议参考。
-```bash
-npm run build
-```
+构建输出(`dist/`、`src-tauri/target/`、`node_modules/`、`.app` / `.dmg` / `.pkg` / `.exe`)全部 .gitignore,不入仓。
-运行 Rust 测试:
+## 本地开发
```bash
-npm run test:rust
+npm install
+npm run tauri:dev # 起 Tauri 桌面 dev 窗口 + Vite HMR
+npm run build # 仅前端 production build(vite + tsc)
+npm run test # cargo test --manifest-path src-tauri/Cargo.toml
+npm run check:rust:windows # cross check Windows target(macOS 本地交叉验证)
+npm run test:rust:windows # 在 Windows runner 上跑(CI 主用)
```
## 桌面端打包
-Tauri 2 没有提供 bundle 输出目录配置。macOS 打包脚本会在运行 Tauri 前,把 `src-tauri/target/release/bundle/macos` 和 `src-tauri/target/release/bundle/dmg` 准备成指向 `dist/` 的链接。Tauri 仍然写入它自己的固定 bundle 路径,但实际 `.app` 和 `.dmg` 会直接落到 `dist/`;`.pkg` 生成脚本也直接写入 `dist/`。
+Tauri 2 没暴露 bundle 输出目录配置,macOS 打包脚本在 `tauri build` 前把 `src-tauri/target/release/bundle/macos` 与 `bundle/dmg` symlink 到 `dist/`,把最终 `.app` / `.dmg` / `.pkg` 直接落到仓库根目录的 `dist/`。
-本地测试阶段只打包 `.app`:
+本地仅打包 `.app`(用于手测,不签名):
```bash
npm run tauri:build:macos-app
```
-`.app` 写入 `dist/` 后,会删除构建过程中生成的裸 macOS 可执行中间产物。
-
-最终发布阶段打包 `.dmg` 和 `.pkg`:
+发布构建(`.dmg` + `.pkg`):
```bash
npm run tauri:build:macos-release
```
-最终发布流程会把 `.app` 作为打包输入,随后从 `dist/` 中移除 `.app`,只把发布用安装包保留在 `dist/` 根目录。`dist/` 根目录里的旧版本 `.dmg` 和 `.pkg` 会移动到 `dist/history/` 下对应的版本命名文件夹中;重复构建当前版本时会替换当前根目录安装包,不再额外备份。
+发布构建的 `.app` 会作为打包输入参与签名 / notarization 链路(CI 跑),随后从 `dist/` 移除,只保留 `.dmg` / `.pkg`。旧版本产物会移动到 `dist/history/v<旧版本>/` 下归档;重复构建当前版本只替换根目录的当前文件,不会再额外备份。
-预期本地产物结构:
+期望产物结构:
```text
dist/
- codex_switch__.dmg
- codex_switch__.pkg
+ codex_switch_<版本>_aarch64.dmg
+ codex_switch_<版本>_aarch64.pkg
+ codex_switch_<版本>_x64-setup.exe (Windows runner)
history/
- v/
+ v<旧版本>/
...
web/
...
```
+Windows 构建走 CI 的 `tauri build --target x86_64-pc-windows-msvc`;本地 macOS 上一般只跑 `check:rust:windows` 做类型检查。
+
## 版本与发布
-- 项目版本保存在 `package.json`,并同步到 Tauri 和 Cargo 元数据。
-- GitHub Release 标签使用完整语义版本号,例如 `1.5.3`。
-- 每个补丁版本单独创建一个 Release 标签。
-- 不要把补丁版本产物上传到旧的两段式标签下,例如不要继续把 `1.5.x` 上传到 `1.5`。
-- macOS 安装包作为 Release 资产发布,不提交到 Git。
+- 版本号源头是 `package.json`,`npm run version:sync` / `npm run version:set -- ` 把同一版本写到 `package-lock.json`、`src-tauri/Cargo.toml`、`src-tauri/Cargo.lock`,并在 `src-tauri/mac/front/index.html` / `win/front/index.html` 通过 Vite-injected `__CODEX_APP_VERSION__` 渲染到设置页。
+- GitHub Release tag 用完整 semver(如 `v1.5.10`)。push tag → `.github/workflows/build.yml` 自动跑 macOS arm64 + Windows x64 构建并把产物上传到一个 **draft release**,不会自动转 Latest。
+- 不要把补丁版本的 asset 上传到旧的两段式 tag(如 `1.5`)。
+- macOS 安装包仅作 Release asset 发布,不提交到 Git。
常用命令:
```bash
-npm run version:sync
-npm run version:set -- 1.5.4
+npm run version:sync # 把 package.json 当前 version 同步到 Cargo / lock
+npm run version:set -- 1.5.11 # 一次性 bump 到指定版本
+npm run version:check # CI 用:拒绝把 semver 字面量写回 *.html
```
+## 常见问题
+
+### 没有 Codex CLI 怎么办
+
+应用启动后会探测 `codex` 路径;探测失败时设置页会标红「Codex CLI 路径未找到」,可手动指定(写入 `install_state.json` 的 `user_codex_path` 优先级最高)。未装 Codex CLI 也能用 plan / quota 查看(走 ChatGPT OAuth token 直接拉 rate-limits),但「登录」按钮和切换后启动 Codex 等动作需要 CLI 存在。
+
+### 切换账号会丢失原账号的 sessions / 历史吗
+
+不会。切换时整个 `~/.codex/` 子集(`auth.json` / `config.toml` / `sessions/`)被原子归档到原账号的备份目录,目标账号的同名内容覆盖回 `~/.codex/`。再切回来时全部恢复。
+
+### 「刷新」按钮和「切换」之后会不会消耗 quota
+
+不会真发 ChatGPT 对话请求。Plan 数据来自 `id_token` claims;quota 走 ChatGPT Web API `account/rateLimits/read`(HTTP GET),或 Codex 0.130+ 的 `app-server` JSON-RPC fallback。没有 LLM 调用,不消耗用户额度。
+
+### per-card「登录」按钮为什么有时变成「取消」
+
+当 codex 进程已经起来并打开了浏览器,但 OAuth 回调没回来(用户关浏览器 / 网络异常),点同一按钮会向 codex login 子进程发 SIGTERM / taskkill 中止它,释放 `.switch.lock` 全局锁。
+
+### Custom Base URL 配置后能继续用 ChatGPT OAuth 吗
+
+不能。Custom Base URL(指向第三方 OpenAI 兼容反代)和 ChatGPT 官方 OAuth 是互斥的 — OAuth `id_token` 校验只对官方 endpoint 生效。配置 Base 之后该卡片的「Base」按钮会变红警示。
+
+### macOS 提示「无法打开,因为无法验证开发者」
+
+App 暂未做 Apple Developer 代码签名 / notarization。第一次启动按住 Control 点应用图标 → 选「打开」一次即可放行;后续直接双击就行。或在「系统设置 → 隐私与安全」放行。
+
+### Windows SmartScreen 提示「Windows 已保护你的电脑」
+
+同上,未做 Authenticode 签名。SmartScreen 弹窗点「更多信息 → 仍要运行」即可。
+
+### 日志和账号数据存在哪里
+
+- 账号备份:`~/.codex/account_backup/<别名>/`(macOS / Linux)/ `%USERPROFILE%\.codex\account_backup\<别名>\`(Windows)
+- 应用运行时 cache:`~/.codex-switch/`(plan / quota 缓存、`install_state.json`、`switch.lock`)
+- Codex 当前账号状态:`~/.codex/auth.json` + `~/.codex/config.toml`
+
+## 技术栈
+
+- **后端 / runtime**:Rust 1.80+ · Tauri 2.x · tokio + reqwest(rustls-tls)· chrono · serde
+- **协议适配**:`shared/runtime/chatgpt_api.rs`(ChatGPT Web API `account/{read,rateLimits/read}`)+ Codex app-server JSON-RPC fallback(`codex` ≥ 0.130 时 OAuth refresh 失败兜底)
+- **前端**:HTML + CSS + 原生 TypeScript(`shared/front/{render,state,actions,theme,i18n,tauri}.ts`),无前端框架;Vite 7 打包
+- **跨平台 runtime**:mac / win runtime 各自实现 spawn / process control / OS-native title bar;shared runtime 处理协议、profile lifecycle、JSON-RPC、缓存、文件锁
+- **构建 / 发布**:`tauri build` 单命令出 dmg / pkg / exe;`.github/workflows/build.yml` 出 draft release,全部 asset 由 GitHub Actions 上传
+
+## 平台支持
+
+- **macOS**:原生 Tauri 桌面端(Apple Silicon),同时保留 `macOS-backup/` 下的 legacy shell 流程兼容。
+- **Windows**:原生 Tauri 桌面端(x64),通过 Release 中的 `.exe` 分发。
+- **Linux**:暂未做正式发布;前端代码跨平台,理论可自行 `cargo tauri build` 出 AppImage / deb,但 macOS-backup 与 Codex CLI 路径探测未覆盖 Linux 路径约定。
+
+平台专属逻辑放在 `src-tauri/mac/**` 或 `src-tauri/win/**`,跨平台逻辑都在 `src-tauri/shared/**`。
+
## macOS 兼容脚本
-通过兼容入口安装:
+老的 shell 流程仍然保留,作为桌面 GUI 不可用 / SSH 终端场景的兜底:
```bash
bash macOS-backup/install.sh
source ~/.zshrc
```
-支持三种模式:
+三种模式:
-- `auto`:优先尝试原生桌面运行时,找不到时回退到 legacy shell 流程。
-- `desktop`:强制使用原生桌面运行时。
-- `legacy`:强制使用原来的 shell 版 `codex-switch.sh` 流程。
+- `auto`:优先尝试原生桌面 runtime,找不到回退到 legacy shell。
+- `desktop`:强制走原生桌面。
+- `legacy`:强制走 `codex-switch.sh`。
卸载:
```bash
-bash macOS-backup/uninstall.sh
-bash macOS-backup/uninstall.sh --remove-script
+bash macOS-backup/uninstall.sh # 只移除命令接入层
+bash macOS-backup/uninstall.sh --remove-script # 连脚本一起删
source ~/.zshrc
```
-卸载脚本只移除受管理的命令接入层,不会删除账号备份目录;账号目录需要时手动清理。
+卸载脚本不会删 `~/.codex/account_backup/`,账号目录需要时手动清理。
+
+## 免责声明
+
+本项目专注 **OpenAI Codex CLI 多账号管理**,**不是** OpenAI 官方项目,也不复用其商标 / Logo / 发布身份。
-## Windows 安装
+所有账号凭据 / OAuth token 仅保存在本机 `~/.codex/account_backup/`(Unix 0600 + atomic write);plan / quota 通过 HTTPS 直连 `chatgpt.com` / `api.openai.com`,不经任何第三方中转。
-在仓库 Releases 页面下载最新 Windows `.exe`。
+ChatGPT OAuth `id_token` / `access_token` 仅用于读取计划与 rate-limit 元数据,不会向模型发起任何对话请求,因此不会消耗用户额度。
-## 账号数据
+## 许可证
-账号数据只保存在本机。导出的配置或账号备份可能包含 API Key 或认证数据,只应保存在可信设备上。
+MIT License。完整文本见 [LICENSE](LICENSE).