Skip to content

Conversation

@Rogers-F
Copy link
Contributor

新功能

  • Gemini CLI 代理支持 - 完整的 Gemini 代理托管功能
  • 应用自动更新 - 支持检测新版本并自动更新
  • 侧边栏导航 - 可收起侧边栏,新增 NEW 徽章
  • 新增功能页面:
    • 🚀 SpeedTest - API 端点延迟测试
    • 🔍 EnvCheck - 环境变量冲突检测
    • 📝 Prompts - 系统提示词管理(支持 Claude/Codex/Gemini)
  • DeepLink 支持 - 通过 URL scheme 导入配置
  • 黑名单功能 - Provider 黑名单管理与自动降级

修复

  • 修复按钮文字溢出/垂直排列问题(Tailwind CSS v4 兼容)
  • 修复页面切换状态丢失问题(keep-alive)
  • 修复开机自启动选项视觉闪烁
  • 修复 HTTP 状态码记录问题
  • 多处 UI/UX 改进

Wails CI 构建时会清除并重新生成绑定文件,自动生成的绑定
可能不直接导出 interface 类型。改为在组件内部定义类型。
使用 Wails 自动生成的类型定义,解决类型不兼容问题:
- 从 bindings/codeswitch/services/models 导入类型
- 更新函数签名适配 null | undefined 联合类型
- 移除首页工具栏的 MCP、Skill、日志按钮(侧边栏已有)
- 移除侧边栏 Gemini 入口(已集成到首页 Tab)
- 移除 Gemini 独立路由
- 从导航中移除 Gemini CLI 配置页面入口
- 从路由中移除 /gemini 路由
- 添加侧边栏收起/展开功能
  - 默认展开状态
  - 点击按钮可收起
  - 状态通过 localStorage 持久化
  - 收起时仅显示图标,hover 显示 tooltip
- 侧边栏收起时添加 align-items: center 使图标居中
- 按钮添加 flex-direction: row, white-space: nowrap, flex-wrap: nowrap 防止文字竖排
- 侧边栏NEW徽章在用户访问页面后自动隐藏(使用localStorage记录)
- 修复环境检测页重新检测按钮文字竖排
- 移除提示词和测速页按钮的justify-content:center避免文字溢出
- 添加全局 button { line-height: 1 } 修复 Tailwind Preflight 导致的按钮文字溢出
- 使用 keep-alive 保持路由组件状态,防止切换页面后本地转发开关状态丢失
- 侧边栏版本号从 v0.4.0 更新为 v1.1.11
- 设置页面版本号从 v1.0.0 更新为 v1.1.11
- 新增 claude-opus-4-5-20250929 模型定价
- Input: $5/M, Output: $25/M
- Cache 写入(5min): $6.25/M, Cache 写入(1hr): $10/M
- Cache 读取: $0.50/M
- 新增 claude-opus-4-5-20251101 定价
- 新增 claude-haiku-4-5-20251001 定价
- 添加多个模型别名以提高匹配率
- 版本号更新至 v1.1.12
- recordFailureFixedMode 函数添加 failureThreshold 参数
- 从配置中动态读取失败阈值而非硬编码为3
- 修复用户设置9次拉黑但实际3次就触发的bug
- 更新所有相关日志输出使用动态阈值
后端更改:
- 数据库添加 enable_blacklist 字段(默认 true)
- SettingsService 添加 IsBlacklistEnabled 和 UpdateBlacklistEnabled 方法
- RecordFailure 和 IsBlacklisted 开头检查总开关,关闭时跳过拉黑逻辑
- 修复固定拉黑模式优先使用数据库配置而非 JSON 默认值
- 修复 settingsservice.go 缺少 log import

前端更改:
- settings.ts 添加 getBlacklistEnabled 和 setBlacklistEnabled API
- General/Index.vue 添加拉黑功能总开关 UI(在等级拉黑开关上方)
- 添加 blacklistEnabled 状态和 toggleBlacklist 切换函数
- 添加中英文国际化文本(enableBlacklist 和 enableBlacklistHint)

修复问题:
- 固定拉黑模式使用硬编码 30 分钟而非用户设置的 5 分钟
- 缺少拉黑功能总开关导致无法完全禁用拉黑
问题根源:
1. xdb 连接池懒初始化:Inits() 只注册配置不建立连接
2. 首次 INSERT 时连接池未准备好导致写入失败
3. 缺少 busy_timeout 导致遇到锁立即失败
4. 未启用 WAL 模式,写操作阻塞整个数据库

解决方案:
1. DSN 添加 _busy_timeout=10000:遇到锁等待 10 秒而非立即失败
2. DSN 添加 _journal_mode=WAL:启用 Write-Ahead Logging,读写可并发
3. 初始化后执行预热查询:强制建立连接,模拟用户点击查询的效果
4. 添加详细的连接状态日志输出

影响文件:
- services/providerrelay.go:主服务数据库初始化
- requestlog_mock_test.go:测试文件保持配置一致性

修复效果:
- 解决首次启动写入失败需要手动点击查询才能恢复的问题
- 解决数据库锁导致 token 和计费统计丢失的问题
- 提升并发写入性能,避免多请求时互相阻塞
主要更新:
- 新增控制台日志查看器功能,支持实时查看后端日志
- 修复非流式请求返回状态码0时被错误判定为失败的问题
- 更新版本号至v1.1.13

详细变更:
1. 后端新增 ConsoleService 服务捕获 stdout/stderr
2. 前端新增控制台页面组件,支持实时日志刷新和自动滚动
3. 侧边栏添加控制台导航按钮
4. 修复 providerrelay.go 中状态码0的特殊处理逻辑
5. 添加中英文国际化支持

Co-Authored-By: Half open flowers <1816524875@qq.com>
问题:
- AutoRecoverExpired 定时器每分钟执行时,会遍历多个过期provider
- 同时正常API请求也会更新数据库,导致写锁冲突
- 出现大量 "database is locked (5) (SQLITE_BUSY)" 错误

解决方案:
1. 添加3次重试机制,间隔50ms/100ms/150ms
2. 仅针对SQLITE_BUSY错误重试,其他错误直接失败
3. 重试失败后只记录警告,不影响主流程(下次定时器会再试)

Co-Authored-By: Half open flowers <1816524875@qq.com>
问题1:SQLITE_BUSY根本原因
- 之前的重试方案只是"掩盖"问题,不是真正解决
- 定时器每次循环执行多个UPDATE,每次都单独获取写锁
- 与正常API请求的写操作产生锁竞争

解决方案(事务批量处理):
1. 收集所有需要恢复的provider到内存数组
2. 开启事务(db.Begin)
3. 在事务内批量执行所有UPDATE
4. 一次性提交事务(tx.Commit)
5. 从多次获取写锁优化为只获取一次,彻底避免并发冲突

问题2:控制台日志无限增长
- 日志只有数量限制(1000条),没有时间限制
- 长期运行会累积大量历史日志

解决方案:
1. 每次添加日志后自动清理3天前的旧日志
2. 使用时间窗口(72小时)而不仅仅是数量限制
3. 清理时输出日志记录清理数量

Co-Authored-By: Half open flowers <1816524875@qq.com>
Co-Authored-By: Half open flowers <1816524875@qq.com>
Co-Authored-By: Half open flowers <1816524875@qq.com>
问题:
- 即使provider返回状态码0或200,如果ToHttpResponseWriter复制响应时出错
  (如客户端断开连接),provider会被错误标记为失败并可能被拉黑

根本原因:
- 混淆了"provider响应成功"和"客户端接收成功"两个概念
- 复制失败是客户端问题(网络中断、超时等),不应归咎于provider

解决方案:
- 只要provider返回了响应(状态码0或2xx),就判定为成功
- 复制失败时记录警告日志,但不影响provider的成功判定
- 返回 (true, nil) 而不是 (copyErr == nil, copyErr)

影响:
- 避免正常工作的provider因客户端问题被错误拉黑
- 日志中会显示"复制响应到客户端失败(不影响provider成功判定)"

Co-Authored-By: Half open flowers <1816524875@qq.com>
Co-Authored-By: Half open flowers <1816524875@qq.com>
改进内容:
1. 增加详细的日志输出,便于诊断更新问题
2. 在每个关键步骤输出状态(开始检查、版本比较、下载链接等)
3. 增加HTTP超时时间从10秒到15秒,提高成功率
4. 添加测试脚本 test-update.go 用于验证GitHub Release状态

日志示例:
- "[UpdateService] 开始检查更新,当前版本: v1.1.15"
- "[UpdateService] ✅ 发现新版本: v1.1.15 → v1.1.16"
- "[UpdateService] ❌ GitHub API 不可达: connection timeout"

用途:
- 通过控制台日志查看器可以实时查看更新检查状态
- 用户反馈问题时可以提供详细的错误信息
- 便于开发者诊断更新失败的原因

Co-Authored-By: Half open flowers <1816524875@qq.com>
Rogers-F and others added 30 commits December 28, 2025 14:33
问题:打开编辑已启用提示词的弹窗时,显示的是 prompts.json 中的旧内容,
而不是文件(CLAUDE.md/AGENTS.md/GEMINI.md)中的最新内容

修复:openEditModal 函数改为 async,对于已启用的提示词,
先调用 GetCurrentFileContent 获取文件最新内容再显示
- 新增平台 Tab 切换(Claude Code / Codex)
- 支持用户级和项目级技能安装位置
- 新增 SkillCard 组件,支持启用/禁用切换和内容预览
- 修复跨平台切换时技能消失的 bug
- 修复 YAML front matter 中 --- 被误判为边界的问题
- 完善 i18n 国际化支持
自动更新优化:
- 优先使用静态文件检查(无限流),fallback 到 GitHub API
- CI 自动生成 latest.json 元数据文件
- 新增更新通知弹窗组件,下载完成后提示用户安装

同级轮询调度:
- 新增 RoundRobin 开关,同 Level 供应商轮流处理请求
- 与 Fixed Mode(拉黑模式)互斥,Fixed Mode 优先级更高
- 状态按 platform:level 维度独立维护

其他改进:
- 新增 OpenInExplorer 跨平台文件管理器打开函数
- 应用设置服务注入到代理服务支持运行时读取配置

版本:v2.6.8 → v2.6.9
fix(logs): sync provider dropdown with refreshed logs.
问题根因:
- 前端 CLIConfigEditor 组件使用复杂的本地注入逻辑生成预览内容
- 导致 Preview/Current 标签页显示不一致
- 保存文件后预览不刷新

修复方案:
1. 前端重构(CLIConfigEditor.vue):
   - 移除 ~160 行前端注入逻辑,改用后端 GetConfigSnapshots API
   - 添加平台感知的 hasProviderInput 验证
     - Claude/Codex: 需同时有 apiKey+baseUrl
     - Gemini: 允许任一存在
   - 添加 300ms 防抖 + 请求序号保护(防止竞态条件)
   - 保存文件后自动刷新快照数据(修复保存后不刷新问题)
   - 组件卸载时清理防抖定时器

2. 后端增强(cliconfigservice.go):
   - GetConfigSnapshots 新增 previewMode 参数
     - "current": Preview = Current(新建供应商空输入场景)
     - "direct": 模拟直连应用(ApplySingleProvider)
     - "proxy": 模拟代理启用(EnableProxy)
   - Codex auth.json 预览在 direct 模式下只保留 OPENAI_API_KEY

3. 后端辅助(geminiservice.go):
   - 添加 buildGeminiEnvContent 函数用于 Gemini 预览生成

技术要点:
- 使用 snapshotRequestSeq 计数器忽略过期响应
- fetchCLIConfigSnapshots 参数增加 previewMode
- 确保 Wails 3 RPC 参数数量匹配
问题根因:
- frontend/public/style.css 中的全局 user-select: none 在旧版 macOS WebKit 上导致
  输入框无法获得焦点和输入
- 部分 CSS 使用了 color-mix() 函数,该特性在 macOS Ventura 13.1+ (Safari 16.2+)
  才支持,旧系统会导致样式失效

修复方案:
1. 添加可编辑控件白名单恢复 user-select: text
2. 添加 -webkit-app-region: no-drag 防止 Wails 拖拽区域影响输入控件
3. 为所有 color-mix() 添加 fallback(使用 var() 或 rgba())

影响范围:
- frontend/public/style.css: 核心修复
- frontend/src/style.css: 9 处 fallback
- 组件样式: SkillCard.vue(6), Index.vue(5), ShortcutInput.vue(2), Main/Index.vue(1)

附带修复:
- CLI 工具代理注入配置的校验逻辑优化
问题根因:
- 用户创建 CLI 工具时,填写了代理注入字段(baseUrlField/authTokenField)
- 但忘记从下拉框选择目标配置文件(targetFileId 为空)
- 前端校验检测到"半填"状态后 return 提前退出
- 用户可能没注意到 toast 提示,以为保存成功了
- 重新打开后发现代理注入配置为空

修复方案:
- 在保存时,如果只有一个有效配置文件,自动补充 targetFileId
- 保留"代理注入可选"语义(默认占位行全空)
- 与后端 normalizeAndValidateProxyInjection 校验规则一致

技术细节:
- 新增 autoTargetFileId 变量(单一配置文件时自动选中)
- map 阶段检测"已填字段但未选目标"的情况并自动补齐
问题根因:
- AtomicWriteBytes 重构后错误信息丢失路径信息
- Windows/Unix 平台错误格式不一致
- Windows 重试耗尽时未保留最后错误

修复内容:
- atomic_write.go: 6 处错误信息添加 tmpPath/dir 和目标 path
- atomic_write_windows.go: 统一错误格式为 "原子替换失败 src -> dst"
- atomic_write_windows.go: 重构重试逻辑,保留 lastErr
- atomic_write_nonwindows.go: 统一错误格式,保持跨平台一致性
  实现热力图自适应容器宽度,并为图标选择添加搜索功能

  主要变更:
  - 新增 useAdaptiveHeatmap composable,封装热力图自适应逻辑
  - 热力图根据容器宽度动态计算显示列数,移除横向滚动条
  - 使用 ResizeObserver 监听容器尺寸变化,采用节流优化性能
  - 图标选择下拉框添加搜索筛选功能,支持实时过滤
  - 为供应商卡片的编辑和删除按钮添加 tooltip 提示
  - 修复图标选择器和等级选择器的按钮样式问题
  优化 GitHub Actions release 工作流,在所有构建产物文件名中包含版本号

  主要变更:
  - macOS: codeswitch-macos-*.zip → CodeSwitch-v{VERSION}-macos-*.zip
  - Windows: CodeSwitch.exe → CodeSwitch-v{VERSION}.exe
  - Windows: updater.exe → updater-v{VERSION}.exe
  - Windows: 安装器添加版本号后缀
  - Linux: CodeSwitch.AppImage → CodeSwitch-v{VERSION}.AppImage

  同步更新 latest.json 和 release notes 中的文件名引用
- 新增 formatTokenNumber 函数,支持大数值自动换算
- ≥1,000 显示为 k,≥1,000,000 显示为 M,≥1,000,000,000 显示为 B
- 保留 2 位小数精度
- 应用于表格和统计卡片中的 token 显示
- bump version to v2.6.15
- 新增 formatTokenNumber 函数到首页组件
- 供应商卡片 Tokens 显示支持单位换算
- 热力图 Tooltip 的 token 指标支持单位换算
- bump version to v2.6.16
- 添加 TOKEN 流量卡片点击弹窗,展示输入/输出 token 明细
- 缓存卡片显示缓存命中率(格式:1.23M (45.6%))
- 日志列表新增金额列,直观展示每条请求的费用
- 补充中英文国际化文案
- 将命中率与缓存数字分开显示
- 命中率使用较小字体和浅色
- 支持亮色/暗色主题
新增托盘菜单显示今日用量与预算比例的功能
- 添加 budget_total 应用设置项,支持在通用设置中配置预算总额(USD)
- 托盘菜单显示今日已用金额和预算总额
- 使用 ASCII 进度条直观展示用量占比(28 字符宽度)
- 点击托盘图标时自动刷新用量数据
- 前端增加预算输入框及国际化支持

此功能帮助用户直观监控每日 API 消费情况,便于成本控制
安全修复:
- P0-1: updater.exe 每次强制下载到随机路径并 SHA256 校验,防止本地投毒
- P0-2: updater 增加 validateTask() 强校验路径,忽略 cleanup_paths 防止提权

稳定性修复:
- P1-1: DownloadUpdate/ApplyUpdate 强制要求 SHA256,禁止无哈希降级
- P1-4: 断点续传 Range 返回 200 时删除文件从头下载,防止数据破坏
- P1-6: 新增 safeUnzip() 替代系统 unzip 命令,防止 Zip-Slip 路径穿越
- P1-2: 删除 4 处 releaseUpdateLock(),由脚本统一清理锁文件
- P1-8: macOS 重启定位 .app 使用 open -n -a;Linux 使用 APPIMAGE 外层路径
- 使用 SetEnabled(false) 替代 SetDisabled(true)
- 移除误提交的 exe 文件
新增托盘弹出窗口,提供更丰富的用量展示
- 添加独立 Tray 组件,支持实时用量、进度条、倒计时和预测
- 支持预算周期配置(每日/每周),可自定义刷新时间和刷新日
- 新增倒计时显示和消耗速率预测开关
- 托盘面板设置项移至独立分组,便于管理
- 后端增加 StatsSinceTimestamp 接口支持周期统计
- 托盘预算区域添加百分比标签显示
- 托盘面板设置移至独立 section,改善布局层级
- 修复 macOS 应用激活时自动弹出主窗口的问题
- 根据周期模式动态显示"今日预算"或"本周预算"
- 倒计时格式改为"XX天 HH:MM:SS",支持跨天显示
- 预测耗尽时间改为完整日期时间格式
- 主窗口默认宽度调整为 1400px
- 托盘窗口顶部显示 Claude Code 品牌标识
- 实时显示托管状态(托管中/未托管)及状态指示灯
- 主窗口默认高度调整为 1040px
新增用量手动调整和多维度预测方法选项,提升预算管理灵活性

**核心变更:**
1. 用量调整功能
   - 新增 budgetUsedAdjustment 配置项,支持手动补录已用金额
   - 托盘窗口和用量计算逻辑同步应用调整值
   - 前后端完整支持用量偏移计算

2. 预测方法增强
   - 新增 budgetForecastMethod 配置,支持 5 种预测算法:
     * cycle: 本周期平均速度(默认)
     * 10m: 近 10 分钟速度
     * 1h: 近 1 小时速度
     * yesterday: 昨日平均速度
     * last24h: 近 24 小时速度
   - 预测计算优化,支持跨周期数据查询和边界保护

3. 托盘窗口优化
   - 倒计时显示精度从秒级改为分钟级
   - 刷新频率从 1 秒优化为 60 秒,降低 CPU 占用
   - 预测耗尽时间显示格式优化(移除秒级显示)

4. 国际化支持
   - 新增中英文文案,覆盖用量调整和预测方法所有选项

**文件变更:**
- frontend/src/components/General/Index.vue: 用量调整和预测方法配置 UI
- frontend/src/components/Tray/Index.vue: 托盘窗口预测逻辑和性能优化
- frontend/src/locales/zh.json & en.json: 国际化文案
- frontend/src/services/appSettings.ts: 前端配置类型定义
- services/appsettings.go: 后端配置服务和默认值
- main.go: 托盘用量计算逻辑整合调整值
- version_service.go: 版本号更新至 v2.6.20
实现 Codex 平台独立的预算管理功能,与 Claude Code 完全解耦:

后端变更(services/appsettings.go):
- 新增 9 个 Codex 专属配置字段
- 添加 budget_total_codex、budget_used_adjustment_codex 等预算核心字段
- 新增预算周期配置 budget_cycle_enabled_codex、budget_cycle_mode_codex
- 支持独立的预算刷新时间和预测方法配置

前端配置界面(components/General/Index.vue):
- 添加完整的 Codex 预算配置 UI(+132 行)
- 实现与 Claude Code 相同的配置能力:预算总额、已用调整、周期模式、刷新时间
- 支持预算倒计时和预测耗尽时间显示
- 添加独立的表单验证和持久化逻辑

托盘窗口架构重构(components/Tray/Index.vue):
- 重构为工厂模式,使用 createTrayCard 函数创建独立卡片实例
- 提取平台无关的公共逻辑,支持多平台并行展示
- 每个卡片拥有独立的状态管理:used、total、forecastRate 等
- 支持 Claude 和 Codex 双卡片同时显示,各自独立计算预算数据
- 优化数据刷新逻辑,避免重复请求(refreshBusy 标志)

国际化支持(locales/*.json):
- 新增 trayPanelClaude 和 trayPanelCodex 标签
- 支持托盘窗口双平台标题区分

类型定义完善(services/appSettings.ts):
- AppSettings 接口新增 9 个 Codex 配置字段类型
- 更新默认配置值,确保类型安全

此功能使用户可以为 Claude Code 和 Codex 分别设置预算,
独立监控每个平台的使用情况,提升多平台使用体验
调整 General 组件的 panel-title 样式,改进间距和视觉层次
- 重构 padding 和 margin 设置,提升标题区域的视觉平衡
- 添加底部分割线和字间距优化,增强可读性

优化 Main 组件的等级徽章显示效果
- 改用 inline-flex 布局,确保徽章内容垂直居中对齐
- 增强选择器特异性,避免样式冲突
- 调整圆角半径和最小宽度,统一视觉风格
- 为所有等级徽章添加明确的文本居中对齐

升级应用版本至 v2.6.21
合并 GoldenTangerine 的功能增强,同时保留安全修复:

新功能:
- 自适应热力图(useAdaptiveHeatmap composable)
- 图标选择器搜索功能
- 托盘预算功能(双平台独立配置)
- Token 数值 k/M/B 单位换算
- 日志界面增强(缓存命中率、金额列)
- 构建产物添加版本号后缀

安全修复保留:
- P0-1: updater.exe 本地投毒防护
- P0-2: 任务文件本地提权防护
- P1-1/P1-4/P1-6: SHA256 强制校验、断点续传修复、Zip-Slip 防护

清理:
- 移除误提交的 exe 二进制文件
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants