Skip to content

Bruce v0.15.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 08:57
· 252 commits to main since this release

Bruce 0.15.0 发布说明

新功能 (Added)

  • 双端仪表盘物理卷轴抽屉展开动效 (C137):

    • macOS 端:以菜单栏图标为顶边固定锚点,自顶向下展开至目标高度(240ms cubic-bezier(0.16, 1.0, 0.3, 1.0) 阻尼曲线),内容采用低优先级垂直约束避免挤压形变,逆向回卷(140ms easeIn)后隐藏并归还焦点;支持 Reduce Motion 降级与连击打断保护;
    • Windows 端:通过 CSS clip-path 与硬件加速 transform 实现任务栏托盘侧物理卷轴展开(260ms)与逆向回卷收拢(140ms),并在 transitionend 后触发后端隐藏。
  • 全局界面动效总开关 (C145):

    • 单一裁决源:新增 MotionPreference(跟随系统 / 始终播放 / 始终关闭,默认跟随系统),解析规则唯一:suppressed = (never) ‖ (system ∧ 系统减弱动态效果);macOS 收在 OnboardingCoordinator.motionSuppressed,Windows 收在 app.js 的 motionSuppressed();
    • macOS 全覆盖:SwiftUI 的 \.accessibilityReduceMotion 为只读环境值无法覆盖,故自建可写环境键 \.motionSuppressed,在仪表盘面板与设置窗口两个宿主根注入,统一受控 19 处 withAnimation、5 处 .animation()、菜单栏刷新指示环与卷轴开合过渡;系统设置在运行中变更经 accessibilityDisplayOptionsDidChangeNotification 即时重算;
    • Windows 全覆盖:AppSettings.motionPreference 驱动 <html data-motion>,CSS 以 html[data-motion="off"] 全量闸门替换原 prefers-reduced-motion 媒体查询与 JS 判据的双重裁决,系统设置在运行中变更经 matchMedia change 事件重算;
    • 卷轴缓动曲线修正:展开曲线由 cubic-bezier(0.16, 1.0, 0.3, 1.0)(前 45ms 即走完 74.5% 行程,视觉等同瞬移)改为 cubic-bezier(0.22, 0.61, 0.36, 1),起始不透明度改为 0。
  • 订阅多账号自定义名称 (T18):

    • 默认名:新建账号统一使用「<Provider> · 账号 N」,N 为该 Provider 内最小未占用序号;Codex 优先用邮箱前缀。新名称不再写入 API Key 前 8 位,消除 Key 前缀泄漏与不可读哈希;存量账号不自动改名;
    • 重命名:macOS 三处账号列表(API/Kimi/DeepSeek/火山/智谱/StepFun/Jev/Cline 配置对话框、通用订阅外壳、Codex 账号区)与 Windows 账号行均提供入口,只编辑标签,Provider 前缀、accountID、凭据与 collector service ID 不变;空输入恢复默认名,同 Provider 重名就地拒绝;
    • 保存安全:重复粘贴同一凭证或令牌轮换不覆盖自定义名;StepFun 换站点时保留标签、仅重建站点前缀;站点判定改为名称开头的精确前缀,自定义标签里的「国际」不再误判站点。

修复 (Fixed)

  • 面板滚动/回弹后内容高度与窗口高度失步 (C147):
    • 高度单一真源:控制器记录 lastContentSize / pendingContentSize,过渡中或隐藏时上报的尺寸不再丢弃,动画结束与面板重新可见时补应用一次;打开面板优先用最近上报值而非 fittingSize;
    • 顶边锚定与屏幕夹取:窗口 frame 统一经 DashboardPanelSizingPolicy,顶部不高于 visibleFrame.maxY − 8、底部不低于 minY + 8,内容超高时压缩高度;
    • 宿主视图锚定:hostingController.view 改为显式 required 高度约束,并在每次窗口尺寸落定后 realignContentToTop,内容只向下溢出被视口裁切,不再整体平移;
    • 测量稳定:卡片栈高度上限由计算属性改为视图缓存值,在出现、面板重新可见与屏幕参数变更时刷新,滚动/开合期间不再随键盘窗口抖动。
  • 凭据存储「配置」不再是死按钮 (C156):
    • 该按钮自 C001 起只调用 configureKeychainAccess()(写配置、无界面),已配置用户点下去界面毫无变化,被判定为「点了没用」;
    • 现改为打开「凭据存储」面板:显示当前状态(已配置 / 未配置 / 访问被阻断)、存储位置与 0600 权限说明,点「重新配置」才执行写入;首次未配置的自动引导复用同一面板的解释文案。
  • Windows 启动或看板显示失败时用户拿不到任何线索 (C150):
    • 不再静默退出:初始化失败原以 expect 直接结束进程,发布版又关闭控制台,用户只看到程序一闪而过。现改为按固定阶段码弹出原生提示(TAURI_INIT_FAILED / DASHBOARD_WINDOW_MISSING / DASHBOARD_SHOW_FAILED),不依赖 WebView 是否创建成功;
    • 看板显示失败不再被丢弃:show 返回错误此前被忽略,现在分类为可见故障;焦点获取在窗口已显示后仍保持非致命,不把 Windows 前台激活策略的限制误报为启动失败;
    • 诊断内容收敛:提示只由阶段码生成,不包含原始异常文本、完整路径、账号或凭证;一次性闸门保证失败不会反复弹窗或递归报错。
  • Windows 本地打包失败仍可能复制旧产物并报告成功 (C151):
    • 退出码逐条检查:cargo install / cargo tauri build / cargo build 失败即停止,不再继续走到复制与 SHA256 步骤;
    • 产物按下标而非时间挑选:原先按目录内最新 LastWriteTime 取安装包,增量构建复用未改写文件时会选错版本甚至拾取上一轮残留;现按 tauri.conf.json 的 productName / version 与目标架构精确匹配文件名,缺失即非零退出;
    • 目标与目录显式化:构建目标取自 CARGO_BUILD_TARGET 或 rustc -vV 的 host 并显式传参,中间产物默认收拢到 local/build-win/cargo-target,越出 local/ 的 CARGO_TARGET_DIR 直接拒绝;
    • 签名残留拦截:--no-sign 构建遇到 local/dist 中同名旧签名时先失败,避免把旧签名与新安装包混搭;
    • 回归固化:新增 scripts/tests/test-build-win-app.ps1 故障注入行为测试并接入 CI verify-windows。
  • Windows 启动后没有可见入口、重复启动只多一个静默进程 (C149):
    • 启动即呈现面板:三个窗口此前全部 visible: false 且启动不显示任何窗口,用户双击快捷方式后只能自己去找托盘图标(Win11 新装应用的图标默认收进溢出区,而默认热键为空)。现 setup 末尾经统一入口呈现看板,双击启动即视为一次显式唤出;
    • 单实例:接入 tauri-plugin-single-instance(首个注册),第二次启动唤出既有面板后退出,不再起第二个无声无窗口的进程;
    • 统一唤出入口:托盘左键/托盘菜单/热键/预览卡展开/启动呈现/第二次启动统一走 reveal_dashboard(先 record_shown 再 show),修正预览卡展开漏记显式唤出、导致不参与 180ms 瞬态失焦保护的不一致;
    • 悬停预览卡事件授权:preview 窗口此前不在任何 capability 内,event.listen 被静默拒绝,420px 预览卡收不到 dashboard-updated。新增最小权限的 preview-panel capability,并在 check-win-frontend.mjs 增加「订阅事件的窗口必须有 listen 授权」的结构断言(缺授权即 CI 红灯);
    • 结构门禁修复:check-win-frontend.mjs 的提前退出位于 T11 结构断言之前,那些 FAIL 只打印不影响退出码,现把退出判定移到全部断言之后。
  • macOS 仪表盘展开/收起与 Tab 切换的弹簧抖动 (C148):
    • 面板高度单一动画源:内容高度变化统一折算成一次 0.30s easeInOut 窗口高度动画,同拍多条上报先经 30ms 合并成一个目标(此前每条上报各起一条 0.20s 窗口动画,反复重新起步读作弹簧回弹);宿主视图改为四边贴合窗口、根视图去掉 fixedSize,视口弹性伸缩,底栏随窗口下边缘同步移动,消除「底栏先跳到位、窗口边缘追赶」的错位与底部空壳帧;
    • 交换态显式高度:卡片正文、多账号段与 Tab 单卡改为 ZStack + 实测自然高度 + 显式 frame 插值(新增 DashboardSwapHeight 裁决),Tab 切换去掉 spring(damping 0.82) 过冲曲线,高度不再先冲高再缩回;屏高上限收敛到 DashboardPanelSizingPolicy 夹取,删除视图内的 maxStackHeight 缓存;
    • 标题行折叠交接:拖拽手柄常驻、占位宽度随折叠态插值(展开 0 宽),收起摘要与「最后更新 / LIVE」改为接力淡入(退场 0.07s、入场延迟 0.06s),消除标题横向跳动与文字压在量条上的叠影。
  • macOS 构建源码告警清零 (C140):
    • 跨模块主题类型导入:ProviderBrandBadge 显式 import BruceOnboardingCore,不再依赖 BruceAppCore 的传递可见性引用 ResolvedTheme,消除 Swift 6 implementation-only 可见性告警;
    • WebKit Cookie 清理时序:StepFunWebLoginView 清空登录缓存改用 await cookieStore.deleteCookie(_:),全部 Cookie 删除完成后再重载页面,消除 async 替代告警并修正清理与重载的并发竞态。
  • 构建源码告警清零(第二批)(C143 / C144):
    • 滚动条压制观察隔离 (C143):KVO 与通知回调改经 nonisolated 入口建立主线程语义(主线程 MainActor.assumeIsolated 同步压制,异线程交主队列),deinit 直接释放 KVO 观察与通知 token,不再调用 MainActor 隔离方法;
    • 设置下拉与测试卫生 (C144):ProviderPopUpPicker.Coordinator 标注 @MainActor,与 SwiftUI 协调器契约一致;NativeLifecycleHarness 的取消退出用例补断言「存在运行任务时先安排宽限期回调」,消除死变量。

调整与优化 (Changed)

  • 技术债批次收口 (C130–C136):
    • TD-003/006 总账校准 (C130):Windows Provider 清单与四处巨型文件切分均已由既有实现落地,从远期债务池移除;
    • TD-008/010 边界定稿 (C131):旧格式凭据迁移只在 macOS 侧发生(Windows 无历史格式);collector-credential 只读探测函数定位为测试/兼容面,并写入设计 02;
    • TD-012 滚动条压制事件化 (C132):面板滚动条压制由 0.3s Timer 轮询改为 KVO + 系统通知事件驱动,隐藏/离窗即解除观察;
    • TD-009 菜单栏额度门禁 (C133):菜单栏「最低/平均剩余额度」与仪表盘共用验证门禁,未验证 Provider 不再影响菜单栏;
    • TD-004 缓存原语收敛 (C134):JSONL / SQLite 缓存与 Codex 头尾指纹统一到 collector-local::cache_util,原子写盘补 sync_all;
    • TD-011 Windows 设置前端拆分 (C135):settings.js 由 3,258 行拆分为共享状态 + 订阅 / 工作台 / 计费 / 维护分节脚本 + 56 行壳层,脚本按 settings.html 固定顺序加载;
    • TD-005 重试契约通用化 (C138):codexQuotaRetryOnly 改为通用 quotaRetryOnly,额度计划一律经 build_account_plan,删除 codex 专属编排入口,并补非 codex provider 的重试回归;
    • TD-002 峰谷/分档计价 (C139):TokenBucket 增加计价类别份额,DeepSeek V4 Pro 峰值 00:30–16:30 UTC 按 $1.32/$3.96、Qwen3.7 Plus 单请求 >256K 按 $1.20/$4.80 计费;SQLite/JSONL 缓存保留份额并升聚合版本。
  • 设置页去除冗余说明文字 (C146):
    • 开关状态字移除:macOS 通用页「锁屏暂停订阅刷新」「系统通知」与 Windows 维护页「系统通知」不再在开关旁渲染「已开启 / 已关闭」,开关开合位置即唯一状态表达(改写 C112 §5 的居左状态字契约);
    • 软件更新卡去噪:「自动检查更新」行去掉状态字;「当前版本」行去掉「正式版 · 从 GitHub Releases 检查 (...)」频道小字(dev 构建的降级小字同步移除),只保留等宽版本值;UpdateCopy / update-presentation.js 与共享 fixture tests/fixtures/update-copy-parity/cases.json 同步删键。
  • 设置窗口侧栏改按窗口宽度锁定比例 (C152):
    • 比例锁定:侧栏由固定 216pt 改为窗口内容宽度的 17.6%(1000pt 窗口下 176pt、右侧面板 823pt),窗口缩放时左右比例保持不变,160pt 为长标签可读性下限;macOS 统一由 BruceAppCore.SettingsWindowMetrics 计算,Windows .sidenav 以同比例 CSS 表达;
    • 默认尺寸:设置窗口内容区默认 1040×680 → 1000×680(mac setContentSize 与 Windows tauri.conf.json 同步),最小 980×620 不变,仍可自由缩放——锁定的是比例而非长宽;
    • 回归护栏:新增 SettingsWindowMetricsHarness(默认尺寸 / 多宽度比例恒定 / 比旧值收窄 / 单调增长 / 非法输入兜底),Windows frontend.test.mjs 增补侧栏比例与窗口可缩放断言。
  • 设置通用页配置项按功能分组重排 (C153):
    • macOS 行序:配色模式 → 界面风格 →(模糊风格)→ 界面动效 → 仪表盘卡片布局 → 刷新间隔 → 锁屏暂停订阅刷新 → 系统通知 → 凭据存储 → 外部 CLI 来源,外观类(含动效)聚在前,再看板呈现、刷新行为,最后通知与凭据安全;
    • Windows 同构:界面风格 → 界面动效 → 看板布局 → 刷新间隔 → 系统通知,与 mac 去掉平台独占行后的相对顺序一致;
    • 回归护栏:frontend.test.mjs 新增通用页行序源码断言,并把「设置保存串行化」用例从分段控件下标定位改为按 setting-interval id 定位,避免行序变动造成误报。
  • 凭据存储行去掉重复状态表达 (C154):
    • 已配置态不再渲染绿色「已配置」文字,只保留主按钮;按钮文案由「重新配置 / 配置 / 修复」统一为「配置」,三态共用同一处置入口;
    • 「未配置」「访问被阻断」两条需要用户处置的警示仍保留(warn 黄字,紧邻按钮)。
  • 设置窗口行内按钮统一颜色与尺寸 (C155):
    • 凭据存储行的「配置」由主按钮改回中性次按钮,与订阅额度行的同名「配置」一致;主按钮只保留给区块级主动作(「添加…」「确认授权」)与对话框确认,危险操作仍用 danger;
    • FluentButtonStyle 为非 link 角色加 64pt 最小宽度并居中,短标签按钮(配置 / 管理 / 预览 / 导出 / 录制 / 清除)等宽,行尾控件成列对齐。