diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57340b5..f6d2375 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,10 +8,13 @@ on: jobs: test: - runs-on: windows-latest + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: + os: + - windows-latest + - ubuntu-latest node-version: - "16" - "24" @@ -33,3 +36,13 @@ jobs: dotnet-version: "10.0.x" - run: dotnet test desktop/CodexProviderSync.Core.Tests/CodexProviderSync.Core.Tests.csproj - run: dotnet test desktop/CodexProviderSync.App.Tests/CodexProviderSync.App.Tests.csproj + + desktop-macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: "10.0.x" + - run: dotnet test desktop/CodexProviderSync.Core.Tests/CodexProviderSync.Core.Tests.csproj + - run: dotnet build desktop/CodexProviderSync.Mac/CodexProviderSync.Mac.csproj --configuration Release diff --git a/AGENTS.md b/AGENTS.md index 19ef19d..566263f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,9 +15,11 @@ For normal Windows users, prefer the GUI app when it is available. Use the CLI w The tool works by updating both: - rollout metadata under `~/.codex/sessions` and `~/.codex/archived_sessions` -- SQLite thread metadata in the detected Codex state database, normally - `~/.codex/sqlite/state_5.sqlite` with legacy fallback to - `~/.codex/state_5.sqlite` +- SQLite thread metadata in the resolved Codex state database + +Resolve SQLite Home in this order: explicit CLI/GUI override, root `sqlite_home` in `config.toml`, `CODEX_SQLITE_HOME`, then `/sqlite`. Only the default layout may fall back to `/state_5.sqlite`. Never fall back when an explicit/config/environment SQLite Home is missing. + +On Windows, `\\wsl.localhost\...` and `\\wsl$\...` SQLite Homes are diagnostic-only. SQLite operations for these paths run inside WSL and use the corresponding Linux path. Do not solve this by manually editing rollout files only unless the user explicitly asks for manual intervention. @@ -87,6 +89,9 @@ GUI mapping: - `Execute` with config checkbox = switch-like behavior - `Restore Backup` = restore a previous backup - backup retention defaults to 5 and can be customized in the GUI +- SQLite Home overrides are stored per Codex Home in app settings and are passed to refresh, sync, switch, and restore +- Windows GUI refresh reports WSL UNC SQLite Homes as diagnostic-only paths; Execute and Restore are disabled for that layout +- restoring a metadata v2 backup to a different SQLite Home requires a second confirmation showing source and target - `Clean Old Backups` = prune managed backups down to the selected retention count ## Important Behavior @@ -107,6 +112,12 @@ If the output says `state_5.sqlite is currently in use`: - tell the user to close Codex, Codex App, and app-server - then rerun the same command +If the output says Windows cannot safely access SQLite through a WSL UNC path: + +- identify the message as a WSL UNC path safety diagnostic +- open the corresponding WSL distribution +- run the CLI there with the Windows Codex Home mounted under `/mnt//...` and SQLite Home expressed as a Linux `/home/...` path + If sync reports `Skipped locked rollout files`: - treat the sync as mostly successful @@ -128,6 +139,9 @@ If `switch ` fails because the provider is missing: - by default the tool keeps the most recent 5 managed backups - use GUI retention settings or CLI `--keep ` when the user wants a different retention count - do not edit `state_5.sqlite` or rollout files manually if the tool can do it +- classify WSL UNC messages as path safety diagnostics and route SQLite operations through WSL with Linux paths +- metadata v2 backups record `sqliteHome` and `sqliteDbFiles`; a missing default-layout database may be rebuilt from a valid backup, but a missing explicit/config/environment database remains an error +- CLI restore to a different SQLite Home requires `--sqlite-home`, `--allow-sqlite-home-relocation`, and `--no-config`; desktop apps must reject relocation while config restore is selected - GUI settings live in `%AppData%\codex-provider-sync\settings.json` ## Recommended Commands @@ -152,6 +166,13 @@ codex-provider sync --codex-home C:\Users\you\.codex codex-provider switch openai --codex-home C:\Users\you\.codex ``` +From WSL when Codex Home is on Windows and SQLite Home is in WSL: + +```bash +codex-provider status --codex-home /mnt/c/Users/you/.codex --sqlite-home /home/you/.codex/sqlite +codex-provider sync --codex-home /mnt/c/Users/you/.codex --sqlite-home /home/you/.codex/sqlite +``` + ## One-Shot Prompt Template Use this prompt in another AI tool if the user wants one-step handling: diff --git a/README.md b/README.md index 381f95a..c0377ad 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Codex 切换 `model_provider` 后,旧会话可能从 Desktop 或 `/resume` 中 ## 它会处理什么 - 同步 `~/.codex/sessions` 和 `~/.codex/archived_sessions` 中的 rollout metadata。 -- 同步 Codex SQLite 线程记录;优先检测 `~/.codex/sqlite/state_5.sqlite`,并兼容旧路径 `~/.codex/state_5.sqlite`。 +- 同步 Codex SQLite 线程记录,并支持 SQLite 与 `Codex Home` 分开存放。 - 修复项目可见性相关路径信息,并在需要时同步相关 model metadata。 - 每次同步前自动备份,支持恢复和清理旧备份。 - 大型 rollout 文件在满足条件时原地更新,否则自动使用完整安全重写。 @@ -49,6 +49,8 @@ Codex 切换 `model_provider` 后,旧会话可能从 Desktop 或 `/resume` 中 GUI 会保留备份并显示同步结果。每天首次启动会在后台检查一次稳定版更新,网络查询最多等待 10 秒;也可以随时手动检查。执行日志保存在 `%AppData%\codex-provider-sync\logs`。 +Windows GUI 支持为每个 Codex Home 单独指定 Windows 文件系统中的 SQLite Home。`\\wsl.localhost\...` 和 `\\wsl$\...` 一类 WSL UNC 路径仅用于安全诊断;GUI 会显示诊断信息并禁用同步和恢复。Windows Codex Home + WSL SQLite Home 场景应在 WSL 内运行 CLI。 + 项目目前未做 Windows 代码签名,从浏览器下载后可能出现 SmartScreen 提示。请从本项目 Release 下载,并按需核对同版本 SHA-256。 Windows 完整说明见 [README_GUI_ZH.md](docs/README_GUI_ZH.md)。macOS 用户可自行构建 Avalonia 桌面版,参见 [README_MAC_GUI_ZH.md](docs/README_MAC_GUI_ZH.md)。 @@ -75,7 +77,18 @@ codex-provider sync | `codex-provider watch` | 监听配置、SQLite 和 WAL 变化并自动同步 | | `codex-provider watch --once` | 第一次变化并成功同步后退出 | -`switch` 支持 `--model ` 显式设置根级 model,或使用 `--keep-root-model` 只切换 Provider。所有主要命令都支持 `--codex-home `。 +`switch` 支持 `--model ` 显式设置根级 model,或使用 `--keep-root-model` 只切换 Provider。所有主要命令都支持 `--codex-home ` 和 `--sqlite-home `。 + +SQLite Home 按以下顺序解析:命令行 override → `config.toml` 根级 `sqlite_home` → `CODEX_SQLITE_HOME` → `/sqlite`。只有最后一种默认布局会继续检查旧路径 `/state_5.sqlite`;一旦显式指定 SQLite Home,就不会回退到 Codex Home 中的旧数据库。 + +例如 Codex App 使用 Windows 配置、app-server 与 SQLite 位于 WSL 时,可在 WSL CLI 中直接传入: + +```bash +codex-provider status --codex-home /mnt/c/Users/you/.codex --sqlite-home /home/you/.codex/sqlite +codex-provider sync --codex-home /mnt/c/Users/you/.codex --sqlite-home /home/you/.codex/sqlite +``` + +`status` 会显示 effective SQLite Home 和来源。显式路径缺少 `state_5.sqlite` 时,状态查询只报告诊断,`sync`、`switch` 和数据库恢复不会偷偷回退到其它位置。默认布局中的数据库被删除时,`restore` 可以根据备份 metadata 在原默认位置重建数据库。 ## 安全与限制 @@ -88,6 +101,8 @@ codex-provider sync - 不修改消息历史、会话标题、认证信息、`auth.json` 或 `updated_at`。 - 不在多台设备之间复制配置或会话文件;它只修复当前 Codex Home 的 metadata。 - SQLite 被占用时,需要先关闭 Codex、Codex App 和 app-server 后重试。 +- Windows 进程检测到 WSL UNC SQLite Home 时会立即显示专用安全诊断并停止操作。后续操作应进入对应 WSL 发行版,并使用 `/home/...` 形式的 Linux 路径运行 CLI。 +- 新备份使用 metadata v2 记录独立 SQLite Home;恢复到其它 SQLite Home 默认拒绝。CLI 需要同时传入 `--sqlite-home`、`--allow-sqlite-home-relocation` 和 `--no-config`,避免恢复后的 `config.toml` 重新指向原 SQLite Home。 - 活跃会话锁住 rollout 文件时,工具会跳过该文件并继续处理其它会话;结束活跃会话后可再次同步。 - 含 `encrypted_content` 的会话跨 Provider/account 后,可能只能恢复列表可见性,继续对话或 compact 仍可能报 `invalid_encrypted_content`。 - Codex Desktop 首屏目前只显示最近 50 条会话。若 `/resume` 可见但项目侧仍不显示,请查看状态中的 `first page` / `ranks` 诊断;本工具不会修改时间戳来绕过此限制。 @@ -106,10 +121,13 @@ git clone https://github.com/Dailin521/codex-provider-sync.git cd codex-provider-sync npm test dotnet test desktop/CodexProviderSync.Core.Tests/CodexProviderSync.Core.Tests.csproj +./scripts/test-wsl-unc-safety.sh pwsh ./scripts/publish-gui.ps1 ./scripts/publish-gui-macos.sh ``` +`test-wsl-unc-safety.sh` 需要从 WSL 运行,并调用 Windows `dotnet.exe` 验证真实 WSL ext4 SQLite 的安全阻断。 + ## License MIT diff --git a/desktop/CodexProviderSync.App.Tests/MainFormPresentationTests.cs b/desktop/CodexProviderSync.App.Tests/MainFormPresentationTests.cs index 9027d58..f83e39f 100644 --- a/desktop/CodexProviderSync.App.Tests/MainFormPresentationTests.cs +++ b/desktop/CodexProviderSync.App.Tests/MainFormPresentationTests.cs @@ -1,6 +1,7 @@ using System.Drawing; using System.Reflection; using System.Windows.Forms; +using CodexProviderSync.Core; namespace CodexProviderSync.App.Tests; @@ -25,6 +26,8 @@ public void MainForm_UsesChineseChromeAndGreenPrimaryAction() Assert.Equal(FlatStyle.Flat, execute.FlatStyle); Assert.Equal("浏览...", Field