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 改进

新增功能:
- Gemini CLI 供应商管理(支持 OAuth/API Key/PackyCode 认证)
- ccswitch:// 深度链接协议支持,可一键导入供应商配置
- 供应商端点速度测试服务
- 自定义提示词管理(支持 Claude/Codex/Gemini 平台)
- 环境变量冲突检测(防止配置干扰)

优化改进:
- 扩展供应商配置支持模型白名单和映射功能
- 增强供应商降级策略的灵活性
- 完善前端界面和国际化翻译

作者:Half open flowers <1816524875@qq.com>
- 新增 Gemini CLI、深度链接、速度测试等新功能说明
- 修复下载链接指向正确的仓库地址
- 优化文档结构和格式
- 添加技术栈和 License 信息
- 使用 Site 字段替代不存在的 OfficialSite
- 移除对 Model/HaikuModel/OpusModel/Notes 字段的引用
- 使用 SaveProviders 替代不存在的 AddProvider 方法
- 修复 ID 类型转换(int64 -> string)
- 移除不支持的 SingleInstanceLock 和 CustomProtocols API
- 移除不支持的 app.Emit 和 WailsEvent
- 修复 speedtestservice 的 makeRequest 返回值处理
- 修复 DeepLinkImportDialog 的导入路径
- 移除 main.go 中未使用的 strings 导入
- 为所有新服务添加 Start/Stop 方法(Wails 生命周期必需)
- 修复 Gemini 前端 newProvider null 检查
- 移除 App.vue 中深度链接相关代码(后端不支持)
- 所有服务现已完全符合 Wails 3 规范
- 移除 .gitignore 中对 frontend/bindings 的忽略
- 提交手动创建的绑定文件,确保 CI 构建时类型可用
- 包含 GeminiService 和 DeepLinkService 的完整类型定义
- 将 GeminiProvider 改为 BindingGeminiProvider
- 将 GeminiPreset 改为 BindingGeminiPreset
- 统一使用类型推断而非直接导入类型
关键问题:
- applyPortableUpdate 在 os.Exit(0) 前未删除 .pending-update
- 导致重启后再次触发更新,陷入死循环

修复方案:
- 在 os.Exit(0) 前删除 .pending-update 标记文件
- Windows 安装版和便携版都已修复
- 新增 versionservice.ts 绑定以修复版本服务调用
- 新增 models.ts 包含 ClaudeProxyStatus 类型定义
- 修复 DeepLinkImportDialog.vue 中的类型兼容问题
- 更新 Go 后端版本号
- 更新 macOS Info.plist 版本信息
- 更新前端 package.json 版本号
- 删除手动创建的绑定文件,改用本地类型定义
- 修复 DeepLinkImportDialog 的导入方式
- 修复 version.ts 直接使用 Call.ByName
- 修复 claudeSettings.ts 本地定义 ClaudeProxyStatus 类型
- 添加 Gemini API 代理路由(/v1beta/* 和 /v1/*)
- 实现 Gemini 代理管理(EnableProxy/DisableProxy)
- 支持 Gemini 供应商复制功能(DuplicateProvider)
- 将 Gemini 集成到主界面为第三个 tab(与 Claude/Codex 并列)
- 前端支持 Gemini 的完整卡片功能(编辑、删除、复制、拖拽、启用/禁用、统计)

技术细节:
- Gemini 使用字符串 ID 而非数字 ID
- 通过修改 ~/.gemini/.env 的 GOOGLE_GEMINI_BASE_URL 来启用代理
- 代理支持流式响应(:streamGenerateContent)
- 与 Claude/Codex 使用相同的优先级分组和降级策略

Author: Half open flowers <1816524875@qq.com>
- 前端:添加本地 GeminiProvider 类型定义,避免依赖 CI 生成的 bindings
- 后端:在 geminiservice.go 中添加缺失的 time 包导入

修复的错误:
- Module has no exported member 'GeminiProvider'
- undefined: time

Author: Half open flowers <1816524875@qq.com>
- 移除不存在的 SaveRequestLog() 调用,改用 defer + xdb.Insert 保存日志
- 移除不存在的 xrequest.StreamTransfer(),改用 io.Copy 处理流式响应
- 与 proxyHandler 使用相同的日志保存模式
- 修复所有编译错误

Author: Half open flowers <1816524875@qq.com>
问题分析:
- /v1/*any 通配符路由会覆盖 Claude 的 /v1/messages
- 导致 Claude 代理功能失效,应用无法正常工作

解决方案:
- 将 Gemini 路由改为 /gemini/v1/*any 和 /gemini/v1beta/*any
- 更新 buildProxyURL() 返回 http://127.0.0.1:18100/gemini
- 确保三个平台的路由互不冲突:
  * Claude: /v1/messages
  * Codex: /responses
  * Gemini: /gemini/v1/* 和 /gemini/v1beta/*

Author: Half open flowers <1816524875@qq.com>
- 添加侧边栏组件 Sidebar.vue,支持 9 个导航入口
- 新增 Prompts 管理页面,支持三平台提示词 CRUD
- 新增速度测试页面,支持多端点并发延迟检测
- 新增环境变量检测页面,扫描冲突的环境变量
- 添加 CodeMirror 6 Markdown 编辑器组件
- 重构 App.vue 布局,集成侧边栏
- 添加 TypeScript 绑定和国际化文本
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 防止文字竖排
Rogers-F and others added 30 commits December 17, 2025 18:07
问题根因:
- zh.json 中 components.mcp.import.placeholder 包含复杂多行 JSON 字符串
- 该字符串含有大量转义字符和嵌套引号
- 通过 vue-i18n 传递给 BaseTextarea 的 placeholder prop 时导致渲染失败

修复方案:
- 将复杂 JSON 示例改为简单描述性文字
- 恢复完整的 BatchImportModal 实现

测试记录:
- v2.5.30: 纯 HTML slot → 显示正常
- v2.5.31: BaseTextarea + BaseButton → 显示正常
- v2.5.36: ref="textareaRef" → 显示正常
- v2.5.37: i18n placeholder(复杂 JSON)→ 渲染失败
- v2.5.38: i18n inputDesc(简单文本)→ 显示正常
- v2.5.39: 完整实现 + 简化 placeholder → 待验证
问题修复:
- 内置 MCP 服务器(reftools、chrome-devtools)现在可以正确删除
- 采用 tombstone 机制:删除的内置服务器名称记录在 deletedBuiltins 数组中
- loadConfig 加载时检查 tombstone,不再强制恢复已删除的内置服务器
- 配置文件格式升级为 {servers: {}, deletedBuiltins: []},向后兼容旧格式

新增功能:
- 新增 Gemini CLI MCP 平台支持
- MCP 服务器现在可以同时启用 Claude Code、Codex 和 Gemini CLI
- 配置自动同步到 ~/.gemini/settings.json
- Gemini 使用 httpUrl(而非 url)字段,适配其特殊配置格式

技术细节:
- ensureBuiltInServers 接受 deletedBuiltins 参数并跳过已删除项
- 新增 syncGeminiServers、geminiConfigPath、buildGeminiEntry 函数
- normalizePlatform 支持 gemini/gemini-cli/gemini_cli 别名
- 前端 McpPlatform 类型和 platformActive 函数已更新
新功能:
- 支持将供应商配置直接应用到 CLI 工具,无需启用本地代理
- 三平台统一实现:Claude Code、Codex、Gemini CLI
- 闪电按钮 UI:卡片右侧显示直连应用按钮
- "使用中"状态徽章:显示当前直连应用的供应商

实现细节:
- 以 CLI 配置文件为状态真源,实时读取判断当前使用的供应商
- 代理/直连互斥:代理启用时禁止直连操作
- URL 标准化:使用 TrimRight 处理多尾斜杠场景
- Provider Key 唯一性:Codex 平台使用 ID 后缀避免冲突

技术改进:
- 新增 directapply_helpers.go 共享辅助函数
- 修复 Gemini GetDirectAppliedProviderID 不再依赖 Enabled 状态
- JSON/TOML 解析错误正确返回而非静默忽略
主要改动:
- CLIConfigEditor 新增 Preview/Current 双 Tab 切换
- 重构配置快照接口,支持当前磁盘 vs 激活后预览对比
- Token 迁移:code-switch → code-switch-r
- 向后兼容:ProxyStatus() 同时检查新旧两个 token

技术细节:
- GetConfigSnapshots() 返回 currentFiles/previewFiles 双数组
- codexsettings.go: 循环检查 code-switch-r 和 code-switch
- customcliservice.go: 鉴权字段兼容两种 token
- cliconfigservice.go: currentMode 计算兼容两种 key

影响范围:Codex/Custom CLI 代理状态检测
问题:Gemini 供应商编辑时 API Key 被禁用,与 Claude/Codex 行为不一致
修复:移除 Gemini 特殊的 disabled 限制,统一三平台行为
清理:删除不再使用的 i18n key (apiKeyReadonlyHint)
- 新增 RetryWaitSeconds 配置项,控制同 Provider 内重试间隔
- 重构三个 handler 的拉黑模式逻辑,实现内部重试循环
- 修复配置读取兼容性:先用默认值初始化再 JSON 覆盖
- 修复 Gemini 非流式 responseWritten 语义:先读 body 再写 header
- 修复 Gemini 重试时 HttpCode 残留问题
- emitChanges 清理残留的旧自定义字段 key
- updateCustomFieldKey 空值时删除 editableValues 中的旧 key
- 防止 watcher 复活已删除的字段
问题:
1. 空 key 导致行消失
2. 实时校验阻断输入路径
3. v-for 使用 index 作为 key 导致 DOM 不稳定
4. Others 标签页保存 CLI 配置静默失败

修复:
- 引入 keyDraft 实现草稿编辑,blur 时才提交校验
- 使用稳定的 field.id 作为 v-for key
- extractCustomFields() 复用已有 ID,保留空 key 草稿行
- updateCustomFieldValue() 对未提交草稿行不触发 emit
- commitCustomFieldKey() 校验失败时回滚 keyDraft
- Index.vue 添加平台白名单,仅 claude/codex/gemini 调用 saveCLIConfig
新增功能:
- WSL 网络设置:支持在 WSL 中自动配置 Claude/Codex/Gemini CLI
- 非破坏性合并:字段级更新配置文件,保留用户其他设置
- 代理状态管理:记录启用前基线,禁用时精准恢复

技术要点:
- jq/python3 处理 JSON,AWK 处理 TOML/.env
- 原子写入(tmp + mv)+ 双文件回滚机制
- Symlink 保护:拒绝修改符号链接,避免破坏 dotfiles
- 全 TOML header 变体覆盖(bare/quoted/subtable/inline comment)
1. 修复 WSL 设置间距不一致问题
   - 将 NetworkWslSettings.vue 中的单个 section 拆分为两个独立 section
   - 每个设置组现在有正确的间距,与其他设置页面一致

2. 修复打开设置时 CMD 弹窗问题
   - 将 networkservice.go 中所有 exec.Command 调用替换为 hideWindowCmd
   - hideWindowCmd 在 Windows 上设置 HideWindow: true 隐藏命令窗口
问题:wsl --list --quiet 命令在 Windows 上输出 UTF-16 LE 编码,
而代码按 UTF-8 处理导致每个字符后面出现方框(NUL 字节)

修复:
- 添加 decodeUTF16LE() 函数正确解码 UTF-16 LE 输出
- 处理 BOM 头(0xFF 0xFE)
- 正确解析发行版名称如 Ubuntu-24.04
问题1: 点击"立即配置"按钮失败
- 根因: WSL 继承 Windows HOME 环境变量导致路径错误
- 修复: 在配置脚本开头使用 getent passwd 获取正确的 Linux home

问题2: WSL 自动配置开关排版与拉黑开关不一致
- 根因: NetworkWslSettings.vue 缺少 toggle-with-hint 样式
- 修复: 补充缺失的 CSS 样式定义
问题: 复杂 shell 脚本通过 bash -c 参数传递时,AWK 中的 $0 等
变量被 Windows 命令行错误解析

修复: 改用 stdin 传递脚本到 bash,避免参数转义问题
- runWSLCommand: bash -c script → bash (stdin: script)
问题: Gemini 供应商的 API Key 编辑后保存无效
- 后端 UpdateProvider 强制保留旧 API Key
- 前端编辑模式下 API Key 输入框被禁用

修复:
- 后端: 仅当新 API Key 为空时保留旧值,否则允许更新
- 前端: 移除编辑模式下的输入框禁用限制
问题:
1. 编辑后 enabled 被强制设为 false,导致当前启用的供应商被禁用
2. UpdateProvider 只发送部分字段,导致 partnerPromotionKey/category 等丢失

修复:
- 添加 originalProvider 存储编辑前的完整对象
- 更新时使用 ...original 展开保留所有字段
- 保持 enabled: original.enabled 不变
- 合并 envConfig 而非覆盖
问题1:提示词管理页面无法感知外部文件修改
- 用户直接修改 CLAUDE.md 后,应用内不显示更新
- 根因:PromptService 只在启动时加载一次配置,缺少反向同步机制

修复方案:
- 新增 lastWriteTime 字段用于回环检测(区分应用写入和外部修改)
- GetPrompts 返回前检测文件 mtime,若有外部修改则自动回填到已启用提示词
- 新增 getPromptFilePathReadOnly 避免读取时创建目录的副作用
- 使用 100ms 容差处理时间精度问题

问题2:CLI配置编辑器应用后不刷新
- Current Tab 编辑后点击应用,显示成功但内容不更新
- 根因:依赖 computed 属性获取最新内容存在时序问题

修复方案:
- 直接从 nextConfig.rawFiles 获取最新内容,避免依赖 computed 重新计算
问题:打开编辑已启用提示词的弹窗时,显示的是 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: 统一错误格式,保持跨平台一致性
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