Skip to content

feat(ui): UI 刷新——A 清爽浅色,接入 11 个参考组件 - #26

Closed
haliChina wants to merge 16 commits into
SECTL:masterfrom
haliChina:feat/ui-refresh
Closed

haliChina wants to merge 16 commits into
SECTL:masterfrom
haliChina:feat/ui-refresh

Conversation

@haliChina

Copy link
Copy Markdown

改动概览

  • 新增 src/renderer/src/components/ui/Bits.tsx:20 个自研 UI 组件(参考 rareui / assistant-ui / reactbits 的设计语言),零新增 npm 依赖(Electron 打包友好)
  • App.tsx:聊天界面接入 8 个组件
  • SettingsApp.tsx:HookSidebar 侧导航 + AnimatedCounter 余额动画
  • styles.css:追加约 130 行组件样式,设计 token 统一(主蓝 #2383E2、文字 #171717、次要 #838A95、分割线 #EBEDF1)

组件落点

组件 参考来源 落点
ScrollProgressIndicator rareui 消息流顶部细进度条
MatrixOrb rareui 空状态球体动画
DeleteButton rareui 会话删除(两段式确认,替代 window.confirm)
HookSidebar rareui 设置页侧导航(钩式选中 + 三组分区)
AnimatedCounter rareui 官方服务余额数字滚动
VoicePill reactbits 流式录音状态 pill(红点呼吸 + 电平条)
ThoughtLine reactbits 生成态“正在思考/正在调用工具”折叠线
DaySeparator assistant-ui 消息按天分隔(今天/昨天/日期)
MessageActions assistant-ui 消息 hover 操作行(复制→✓ 就地确认)
ErrorStateCard assistant-ui 桥接未加载错误态卡片
branched-menu 增强 reactbits 模型子菜单 › chevron 指示

另 9 个组件(ToolErrorCard / GuardrailNotice / StoppedRunTag / SpeakerTag / VoiceNote / MessageQueue / ComputerUseCard / RegenerateMenu 等)已在 Bits.tsx 备好,后续按需接线。

质量约束

  • 全部动画尊重 prefers-reduced-motion
  • 交互状态文字 + 形状双通道表达,触屏目标 ≥44px
  • aria-pressed / aria-current / role 等语义完整

验证

  • GitHub Actions「Build desktop applications」三平台:tsc 类型检查 ✅ 单元测试 ✅(run 36903027070)
  • 本地 tsc -p tsconfig.json 与 CI 结果一致

haliChina and others added 16 commits September 29, 2026 00:11
…d fallback

Architecture:
- New provider-agnostic ASR layer (src/asr/): types, manager with fallback
  chain (third-party -> official -> local), settings + presets, WAV encoder
- Local sherpa-onnx: resilient loader (createRequire/require/import),
  lazy model init, robust path resolution, Electron-safe resourcesPath access
- Official relay: connect timeout, ordered start-before-audio, expected
  close after 'Done' no longer reported as error
- New third-party OpenAI-compatible ASR (Xiaomi MiMo ASR / SiliconFlow /
  Groq presets): chunked partial flush, final on stop, connectivity probe
- main.ts: speech IPC async + speech:test/speech:chain, configureSpeech on
  boot and settings save, OAuth PKCE flow deduplicated into electron/oauth.ts
- electron.vite: externalizeDepsPlugin keeps sherpa-onnx on-disk intact
  (fixes packaged local model load failure)

Fixes:
- Add-model button used window.prompt, which Electron does not implement;
  replaced with an inline input row (enter to add, esc to cancel)
- '妯″瀷璇锋眰澶辫触' garbled error string corrected to '模型请求失败'

UI:
- New 语音识别 settings section: provider choice, presets, endpoint
  fields, .env-backed key, connectivity test; preload bridge extended
- README rewritten for the multi-provider speech input

Tests: 150 pass / 0 fail (WAV, ASR settings, manager fallback chain,
OpenAI HTTP session lifecycle, plus full legacy suite regression)
- resilience.ts: 错误分类(quota/auth/rate_limit/network)、健康记忆持久化(.model-health.json)、
  指数退避冷却(5min起,quota类60min)、planModelChain 多轮模型切换;适配阿里云百炼赠送资源包耗尽场景
- tool-guard.ts: Codex 风格敏感操作硬匹配(删除/格式化/强推/注册表/管道执行/越界写),
  桌面弹窗三选(拒绝/允许一次/总是允许此类,按 工具+命令族 签名),CLI 终端 y/N,非 TTY 默认拒绝
- hallucination.ts: 重复循环/工具失败却称成功/引用不存在材料 三信号检测,随会话显示提醒条
- config.ts: 提供商环境变量名自动生成(SECAGENT_名_API_KEY),摘除全部手写 env 输入框;
  ASR 密钥统一 SECAGENT_ASR_KEY;同 env 多提供商拒绝保存
- asr/manager.ts: 识别链 3 连败 5 分钟冷却
- paths.ts: 数据目录迁移到平台约定位置(APPDATA/Library/XDG),旧目录自动迁移
- settings UI: 模型稳定性/安全与检测 两组开关
- README 全面重写;补 ci.yml

tsc 0 错误,node --test 174/174 通过
将 MIN_CLASSISLAND_VERSION 从 2.1.1.0 下调到 2.0.0.0。依据 ClassIsland
(HelloWRC/ClassIsland) 源码验证:
- 插件 manifest.yml 声明 apiVersion: 2.0.0.0,正好满足 ClassIsland
  2.0.0.0 起在 PluginService.InitializePlugins 中强制要求的
  apiVersion >= 2.0.0.0,也满足 PluginMarketService 的市场显示过滤;
- 插件用到的宿主 API(AppBase、IAppHost、IProfileService、
  IComponentsService、IExactTimeService、ComponentSettings、
  CommonDirectories、AddSettingsPage 等)在 2.0.0.0 标签均存在且未变化。

同步更新 OobeWizard 错误提示与 classisland 测试。
…present

Previously the four dual-end linkage apps (ClassIsland / Class Widgets /
SecRandom / ICC-CE) were force-listed on the OOBE plugins page regardless
of detection, so e.g. Class Widgets appeared as "detected" on machines
that never had it installed.

A card now appears only when there is real evidence for it:
- the app was auto-detected, or
- its SecAgent-side connector is already installed, or
- an installation target was found or manually picked.

The empty state keeps a manual "choose executable" entry point so
non-standard installs remain configurable, and the install-all button is
disabled when nothing qualifies.
Add secscore-connector.test.ts covering the four user-facing prompts
from the issue (query score, batch add points, group add points, top
scores) plus a duplicate-name error branch. The connector is a pure
Sync-Server client, so the tests mock both layers: the model (scripted
OpenAI-compatible SSE tool-call turns) and the SecScore backend (an
in-memory fake Sync Server implementing /v1/classes, /v1/snapshot,
/v1/sync and /v1/operations). The plugin package under test is pinned
as fixtures under src/test-fixtures/secscore-connector/ so upstream
changes to tool keys, argument names or Skill auto-load patterns fail
these tests.
- pi-tools: 抽出共享 readImageFile/resolveWorkspacePath/MAX_IMAGE_BYTES
- config: OFFICIAL_VISION_MODEL 虚拟识图模型、resolveModelConfig(非变异)、
  resolveVisionAgentConfig(显式配置优先,官方模式自动回落 virtual-vision)
- runtime: visionAgent 子代理(专用系统提示词、无工具、低思考强度),
  secagent__look_at_image 仅在识图模型可用时注册;图片只进子模型不回主模型
- main: 模型列表标记 vision 虚拟模型(不进主下拉);session.vision-model 日志
- UI: 主模型选择过滤 vision;设置页新增识图模型下拉(未配置=不启用)
- runtime.test: 识图工具三用例(成功分发/未配置报错/入参校验)

tsc 0 错误
- vision 子代理构造漏了第 6 参 allowEmptyTools=true,
  导致 run() 因空工具列表直接抛"没有已启用且可发现的 MCP 工具",
  错误被当作工具结果回传主模型(tsx 验证:runtime 10/10 通过)
- 移植 config.test:visionModelId 持久化/显式配置不改源/过期 id 返回
  undefined/官方模式回落 virtual-vision/自定义模式不回落
- 移植 model-provider.test:无工具子代理将用户附件编码为 OpenAI image parts

tsx 全量 194/194 通过
PR SECTL#14 测试移植时把测试文件的 import 行一并追加到了文件尾部,
与文件头部原 import 形成重复标识符;tsx 不做类型检查所以本地
测试通过,但 tsc(CI)报 TS2300。删除尾部重复 import。
原脚本两次 $(mktemp -d) 生成不同目录,doctor 在空 workspace
必然报"未找到配置"退出 1。改为共享 SMOKE_WORKSPACE。
doctor 按设计要求 secscore MCP 已启用且可达,fresh init 的
workspace 必然失败;上游 master 同样如此。冒烟改为
init + mcp list(只读、无网络、无密钥依赖)。
Co-authored-by: traeagent <traeagent@users.noreply.github.com>
- ASR: 新增小米 MiMo 提供方 (chat/completions + input_audio 专用协议)
- ASR: 新增本地增强 SenseVoice 附加包提供方 (local-pro) 与 fetch 脚本
- ASR: 自定义回退链 / 教室噪声档 (远场 VAD + 阈值 + 超级热词) / 音频设备选择
- TTS: 提供方重构到 src/tts/ (Edge/Windows SAPI/MiMo/CosyVoice + 失败回退链)
- TTS: settings 完整块持久化, 云端密钥入 .env (MIMO_TTS_API_KEY / BAILIAN_TTS_API_KEY)
- UI: SelectCombobox/PresetCombobox 改原生 select/datalist (修复希沃触屏点选失效)
- UI: 图片按钮直接 onClick; 提供商弹窗支持从 /v1/models 拉取模型列表
- IPC: tts:test/chain/voices + models:fetch

注: tsc 全量验证进行中, 剩余 electron/tts.ts 与 providers.ts 的少量类型适配
(WindowsSapiTtsProvider 类名 / TtsProvider.test() 补齐 / Edge Buffer 转换)。
- electron/tts.ts: WindowsSapiTtsProvider 类名修正 + managerCache 结构对齐 TtsManagerOptions
- tts/providers.ts: 四引擎补齐 TtsProvider.test() 连通性探测 + Edge Buffer 转换修正
- config.ts: readSettings 的 tts 载荷走 normalizeTtsBlock (provider/chain/voice 默认值完整)
- SettingsApp.tsx: tts 链 includes() 联合类型收窄
- 验证: node_modules/typescript/bin/tsc --noEmit → 0 错误
- bailian.test: duplex 握手参数补 language_hints:['zh'] (config.language 现在透传到 run-task)
- settings.test: MiMo 预设改为验证 MIMO_ASR_DEFAULTS (专用协议,不在 /audio/transcriptions 预设表)
- settings.test: normalizeSpeechSettings 期望值补默认 mimo 块 (开箱默认端点)
- 新增 components/ui/Bits.tsx:20 个自研组件(rareui/assistant-ui/reactbits 复刻,零新增依赖)
- App.tsx:ScrollProgress/MatrixOrb/DaySeparator/ThoughtLine/VoicePill/DeleteButton/MessageActions/ErrorStateCard 接入聊天界面
- SettingsApp.tsx:HookSidebar 侧导航 + AnimatedCounter 余额动画
- styles.css:+130 行新组件样式,设计 token 统一(主蓝 #2383E2)
@haliChina haliChina closed this Oct 1, 2026
@haliChina

Copy link
Copy Markdown
Author

傻逼GLM开错了

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.

1 participant