fix(cli-auth): 保活刷新不再误报「认证脱节」,孤儿 Token 可自愈 - #124
Merged
Merged
Conversation
`schemars 0.8`(tauri-build / tauri-plugin 的传递依赖,且开启了 `preserve_order`)
按 `IndexMap<K, V>` 两参数形式引用 `indexmap 1.x`,而 `indexmap 1.9.3` 的默认哈希参数
`S` 只在 `has_std` 下存在。该 cfg 由 crate 内 build.rs 里的 `autocfg` 探测 sysroot 得出,
在新版 Rust(本机 1.98.1 实测)上该探测会失败,于是编译报:
E0107: struct takes 3 generic arguments but 2 were supplied
这里把 `indexmap` patch 到 `vendor-patched/indexmap`:其 build.rs 无条件声明 `has_std`,
从根上消除 E0107。只改 build script 的探测逻辑,不触碰任何库代码——该 crate 的 `src/`
只用到 `has_std` 这一个自定义 cfg(已核对),因此不改变任何运行时行为。
纯构建层兼容修复,与业务逻辑无关。若你的工具链较老(autocfg 探测正常),
可整段回退本提交并删除 `vendor-patched/`。
Windows 上 CodeBuddy CLI 认证横幅有两个独立成因: 1. 误报:保活刷新先改写账号库里的 token、再同步回 settings.json。 这个中间态被原判定当成「认证脱节」,于是每次启动都可能弹一次。 现按账号库 mtime 划出 30 秒宽限窗口,窗口内报 syncInProgress (「正在同步,无需操作」),窗口外才报 syncPending(真脱节)。 2. 不可自愈:settings 里的 token 若匹配不上账号库中任何账号(孤儿值, 多因历史刷新未同步成功),原判断 `!previous_matches && !already_synced` 会永远 return Ok(false),状态卡死只能手动点按钮。 现增加孤儿例外:孤儿值允许被活跃账号的最新 token 覆盖; 若命中的是其它账号(用户手动切换)仍不覆盖。 配套:刷新前后与切换账号/接入 helper 后广播 codebuddy-cli-updated, 前端监听该事件并加 30 秒兜底轮询,横幅不再滞留。 测试隔离:新增 e2e 用 WB_SWITCH_HOME 把家目录沙箱化(新增 config::HOME_ENV_VAR 覆盖钩子),并在沙箱期间清除 CODEBUDDY_AUTH_TOKEN / CODEBUDDY_INTERNET_ENVIRONMENT,使用例在 CodeBuddy CLI 自身进程里也能跑绿; 整个测试文件加 `#![cfg(windows)]`,避免非 Windows 下 `clippy --all-targets -D warnings` 因未使用导入 / 死代码失败。 验证:wb-switch-core 700 单测 + 5 个新增 e2e 全通过;反向验证(移除孤儿例外) 确认 e2e 中 orphaned_settings_token_is_healed_by_sync 会精确失败于 Ok(false)。
…ted_cfgs
CI 的 lint job 跑 `cargo clippy -p wb-switch-core -p wb-switch-server -p wb-switch-rust
--all-targets --no-deps -- -D warnings`,会把 vendor-patched/indexmap 里
`#[cfg(has_std)]` 触发的 rustc `unexpected_cfgs` 告警直接判成错误,
`indexmap` 编译失败(13 errors),PR 的 lint job 因此红。
根因:autocfg 的自由函数 `emit()` 不会自动调用 `emit_possibility()`
(其文档明确写了这点),所以 `has_std` 这个 cfg 名从未被声明。
补一行 `autocfg::emit_possibility("has_std")` 即可。
本地验证:同一条 CI 命令下 has_std 相关输出从 13 条降为 0;
fmt / core 700+5 单测 / server 9 单测 均通过。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
Windows 上 CodeBuddy CLI 认证横幅有两个独立成因,之前都表现为「认证脱节」告警,且无法自愈。
1. 误报
保活刷新先批量改写账号库(
~/.wb-switch/accounts.json)里的access_token,再异步同步回~/.codebuddy/settings.json。这个中间态被原判定当成「认证脱节」,于是每次启动都可能弹一次横幅。2. 不可自愈
settings.json里的 token 若匹配不上账号库中任何账号(孤儿值,多因历史某次刷新未同步成功),原判断!previous_matches && !already_synced会永远return Ok(false)——状态卡死,只能靠用户手动点「更新 CLI 认证」,点了也未必收敛。改动
核心(
crates/wb-switch-core/src/modules/codebuddy_cli.rs)syncInProgress(正在同步,无需操作),窗口外才报syncPending(真脱节)。判定抽成纯函数classify_sync_state,边界(尤其窗口临界点)可被单测固定。settings的 token 匹配不上任何账号时,允许被活跃账号的最新 token 覆盖;若命中的是其它账号(用户手动切换),仍不覆盖,保留原保护。前端
codebuddy-cli-updated;AccountsPage监听该事件并加 30 秒兜底轮询,横幅不再滞留。syncInProgress期间只给状态说明、不显示按钮,避免用户在刷新未完成时重复触发写入。测试
crates/wb-switch-core/tests/cli_auth_sync_e2e.rs(5 个用例):误报、真脱节、一致、孤儿自愈、不得覆盖其它账号。config::HOME_ENV_VAR(WB_SWITCH_HOME)覆盖钩子,把家目录沙箱化,测试全程不触碰真实账号与 CLI 配置;沙箱期间清除CODEBUDDY_AUTH_TOKEN/CODEBUDDY_INTERNET_ENVIRONMENT,因此在 CodeBuddy CLI 自身进程里跑也是绿的,不会出现「测的是当前 shell 而不是被测逻辑」的假红。#![cfg(windows)]:被测分支本就是 Windows 专属,避免非 Windows 下clippy --all-targets -- -D warnings因未使用导入 / 死代码失败。验证
cargo test -p wb-switch-corecargo test -p wb-switch-servercargo fmt --check -p wb-switch-core -p wb-switch-server -p wb-switch-rustcargo clippy --all-targets --no-deps -- -D warningsnpm run build(tsc + vite)反向验证:临时移除孤儿例外后,
orphaned_settings_token_is_healed_by_sync精确失败于Ok(false)(期望Ok(true)),确认测试确实咬住了原 bug,而不是恒真。附带的构建层提交(与业务无关)
本 PR 另含一个独立提交
e629264:schemars 0.8(tauri-build / tauri-plugin 的传递依赖,且开启preserve_order)按IndexMap<K, V>两参数形式引用indexmap 1.x,而indexmap 1.9.3的默认哈希参数S只在has_std下存在;该 cfg 由 crate 内 build.rs 的autocfg探测 sysroot 得出,在新版 Rust(本机 1.98.1 实测)上该探测失败,导致E0107: struct takes 3 generic arguments but 2 were supplied。现 patch 到vendor-patched/indexmap:其 build.rs 无条件声明has_std,只改 build script 探测逻辑、不触碰任何库代码(已核对:该 crate 的src/只用到has_std这一个自定义 cfg)。如不需要,可单独回退该提交并删除vendor-patched/。已知的既有问题(非本 PR 引入)
src-tauri/src/tray.rs:1031在 Windows 上跑cargo clippy -p wb-switch-rust --all-targets会报E0425: cannot find function taskbar_uses_light_theme(#[cfg(windows)]的测试函数缺use)。该文件最后改动在77d3a39(v0.1.50);CI 的 clippy 跑在 macOS,该分支被 cfg 掉,所以 CI 不报。vscode_cn_inject.rs、codebuddy_cli.rs:378报needless_return等,均为既有 Windows-only 代码。