baiqing
24049d9472
chore(release): bump version to 1.3.6-4 (Beta) — 回退 AURA 界面大改到旧外观、保留功能 + ASR 本地引擎可切换 + 风格页性能修复( #656 ) + macOS capsule 监听修复( #649 )
2026-06-13 14:18:23 +08:00
baiqing
760f662f73
fix(style): 风格编辑器输入框背景用主题 token,修复回退后暗色模式白底
...
beta-3 的 Style.tsx 把输入/文本域背景写死 #fff,回退后在系统暗色模式下
会显示刺眼白底。改回 var(--ol-style-input-bg)(浅色 rgba(255,255,255,.86)、
暗色 rgba(255,255,255,.04)),随主题自动跟随。Claude 审核指出。
2026-06-13 14:00:36 +08:00
baiqing
5671805a09
revert(ui): 回退 AURA 界面大改到 beta-3 外观,保留功能与今日修复
...
把 #650 引入的 AURA / 玻璃拟态界面大改回退到 beta-3 (v1.3.6-3) 的外观,同时保留
AURA 期间合入的功能与今日两处行为修复。
回退到 beta-3:
- 外壳 FloatingShell、概览 / 历史页、卡片按钮 _atoms、设置弹窗、tokens.css / global.css
- 移除随 AURA 加入的主题切换(themeMode.ts / ThemeSection.tsx)
- 设置关闭按钮去掉圆形底(beta-3 本就透明)
保留:Apple 语音、手机远程录入、安卓、划词追问等功能,后端不动。
今日行为修复:
- 风格页切换不再卡顿(prefs:changed 监听只订阅一次 + motion layoutDependency 限制 layout 重测)
- ASR 本地引擎不再锁死,可在 provider 页直接切换(Apple 语音 macOS 直接可选)
为划词追问页补回其引用的 6 个 solid / radius token,避免回退后丢色。
2026-06-13 13:48:18 +08:00
baiqing
a38d6b50e1
chore(release): bump version to 1.3.4-13 (Beta) — 设置界面重构 + 加入 Beta 渠道 / 麦克风 / 市场登录
...
本次只动版本号,逻辑改动已在 #521 落盘:
- 设置界面分节化、整体文案精简
- 「加入 Beta 渠道」迁到高级页底部、独立成节;关于页改为正式版「检查更新」按钮
- 麦克风选择改为 SelectLite 下拉(选中行实时音量条 + 打勾)
- 扩展市场 / 风格市场登录统一走共用 GithubLoginModal,弹窗尺寸不再跳动
- 弹窗动画 de-jank(去掉 blur 滤镜),各处弹窗动画时长缓动统一
- 共享 reqwest 客户端(net.rs)+ 仅连接层失败做指数退避重试
2026-05-23 08:55:35 +08:00
baiqing
99f22a6aee
fix: ASR 切换强制覆盖 endpoint/model + 重试只限连接层失败
...
处理 PR-Agent 第 8 轮:
- ProvidersSection.onAsrProviderChange: asr.endpoint / asr.model 是所有 ASR 厂商
共用的凭据槽,原「仅槽空时填」逻辑使跨厂商切换不生效(dropdown 切了、实际仍
打旧厂商地址)。改为强制覆盖预设默认值,与 onLlmProviderChange 一致。
- net.rs send_with_retry: 重试范围从 is_connect() || is_request() 收窄到只剩
is_connect()。is_request() 多为确定性失败(endpoint 配置错误等),重试 10 次
只是徒增数秒延迟才暴露错误;连接层失败才是真正瞬时、值得重试的一类。
2026-05-22 23:05:18 +08:00
baiqing
00b2bd0a8d
fix(settings): ProvidersSection 识别 sherpa-onnx-local 本地引擎
...
合并 beta 的 #504 引入了第三个本地 ASR 引擎 sherpa-onnx-local,但本分支的
ProvidersSection(早于 #504 拆出)只认 local-qwen3 / foundry-local-whisper。
sherpa-onnx-local 激活时 knownAsr 查不到 → 主 Card 回落显示 volcengine、
凭据字段也错。补齐 5 处:ASR_PRESETS 条目、visibleAsrPresets 过滤、isLocked、
anomalousNameKey、本地引擎不渲染云端凭据字段的分支判断。
2026-05-22 22:50:22 +08:00
baiqing
8986c5680b
fix(settings): performSwitch 补 catch — 本地 ASR 切换失败不再裸抛
...
LocalModelSection.performSwitch 是 async、try/finally 无 catch,而调用方
(Qwen3 / Foundry / sherpa Toggle、禁用按钮)都是 void performSwitch(...)
即发即忘。setActiveAsrProvider / updatePrefs 失败会冒成未处理的 promise
rejection。补 catch + console.error 吞掉。
2026-05-22 22:28:53 +08:00
baiqing
74be27d3e2
fix(settings): provider 切换失败按后端是否已切来决定下拉框回滚
...
上一轮加的回滚无条件把下拉退回 committed provider。但 provider 切换是多步非原子
操作:若 setActiveLlmProvider 已成功、后续 updatePrefs / setCredential 才失败,
后端 active 已是新 provider,回滚下拉到旧的反而让「下拉显示旧 / 后端用新」。
改为记 backendSwitched 标志:仅当后端切换本身没成时才回滚下拉框,让下拉始终与
后端 active 一致。ASR 同理。
2026-05-22 22:14:11 +08:00
baiqing
038744fe40
fix(marketplace): 登录成功写 prefs 失败时补回 .catch
...
重构 OAuth 登录为 GithubLoginModal 后,onLoginSuccess / MarketplaceSection
onSuccess 用裸 void updatePrefs(...) 写 marketplaceDevLogin,丢掉了重构前
try/catch 里的失败日志 —— prefs 写入失败会冒成未处理的 promise rejection。
补回 .catch + console.warn,与重构前行为一致。
2026-05-22 22:00:24 +08:00
baiqing
0689442148
test(polish): 更新 structured prompt 测试以匹配重写后的事项数规则
...
types.rs 的 STRUCTURED_BUILTIN_PROMPT「事项数 → 输出形态」规则已重写(原「≤ 2 条」
拆成「仅 1 条 / = 2 条」两档),但 polish.rs 的两个 structured_prompt 测试仍断言旧
文案,CI 的 macOS / Linux cargo test 因此变红(Windows 偶然未跑到同批次)。
同步订正断言:
- 「事项 ≤ 2 条」→「事项仅 1 条」+「事项 = 2 条」
- 「不硬塞层级」→「输出连贯段落」(仅 1 条事项 → 连贯段落,语义等价)
本地 cargo test --lib:306 passed / 0 failed。
2026-05-22 21:44:56 +08:00
baiqing
2056ad81f0
Merge branch 'beta' into feat/settings-revamp
...
解决 LocalModelSection.tsx 冲突:beta 的 PR #504(Windows sherpa-onnx 本地 ASR)
改的是 AdvancedSection.tsx,而本分支已把它拆分重命名为 LocalModelSection.tsx。
合并保留本分支的拆分 + 文案精简,并并入 #504 的 sherpa-onnx-local 引擎行、
isOnSherpaOnnx / pendingNameKey / 禁用逻辑。其余文件由 git 自动合并。
2026-05-22 21:28:30 +08:00
baiqing
15b4fb15a5
fix(net): 超时不重试 + 网络探针单发 — 处理 PR-Agent 评审意见
...
- send_with_retry 不再重试 is_timeout():reqwest 的 is_timeout 也涵盖「请求已发出、
等响应时超时」,此时服务端可能已收到并在处理,重试 POST/DELETE(marketplace
点赞 / 删除等)会重复执行。只保留 is_connect / is_request 两类「请求未送达服务端」
的重试;net.rs 文档原本宣称超时重试幂等安全 —— 该说法对超时不成立,一并订正
- check_network 改单发、不走 send_with_retry:每 30s 的状态探针走 10 次退避会在
被过滤 / 黑洞网络下把探测拖到近一分钟、状态灯像卡死;瞬时误判由下个 30s 周期
自动纠正。仍用 net::http() 共享连接池
2026-05-22 21:18:21 +08:00
baiqing
7dc1600c4c
fix(settings): 处理 PR 审核意见 — 验证失败文案 / 切换回滚 / 计时器依赖
...
- ProvidersSection: 验证失败时显示 validateFailed 文案,不再对 result.ok=false
误报「连接检查通过」
- ProvidersSection: LLM/ASR 切换失败时下拉框回滚到 committed provider,避免 UI
停在新选项而后端仍是旧 provider;去掉 handler 末尾的 rethrow —— 作为 SelectLite
onChange 是即发即忘调用,rethrow 会变成未处理的 promise rejection
- CheckUpdateButton: 自动收起计时器只依赖 status,不再因 useAutoUpdate 每次渲染
返回新 updater 对象而被反复 clear/reset
- 新增 i18n key settings.providers.validateFailed(zh-CN/zh-TW/en/ja/ko)
2026-05-22 21:09:11 +08:00
baiqing
52c49fcfad
feat(settings): 设置界面重构 — 分节化 / 精简 / Beta 渠道 / 麦克风 / 市场登录
...
将 2200 行的 Settings.tsx 单体拆为 pages/settings/ 下的按节文件(通用 / 服务 /
隐私 / 高级 / 关于),并对设置界面做整体精简与功能调整。
界面精简
- 移除各设置项冗长 / 多行描述(在 180px 标签列普遍折成多行),只留标签与控件
- 删除「个性化」独立 tab —— 仅剩字体大小一项、整页太空,并入「关于」
- 移除失效的「毛玻璃强度」滑块(其 CSS 变量无可见元素消费)
关于 / 更新
- 版本卡片图标右上方放「检查更新」按钮,固定查正式版(channel='stable')
- 「加入 Beta 渠道」迁到「高级」页底部、单独成节;开启后出现查测试版的检查按钮
- 检查中按钮内转圈;结果(已是最新 / 失败)只在按钮内呈现,卡片高度恒定,
不再因状态文字 reflow 抽搐
- Rust app_check_update_with_channel 新增可选 channel 参数,两个按钮各查各渠道;
后台 AutoUpdateGate 仍按 prefs.update_channel 走
麦克风选择
- 由全屏弹窗改为 SelectLite 下拉(与语言选择一致的「官方框」)
- SelectLite 增加 trailing / onOpenChange;新增 MicrophoneSelect —— 选中项右侧
打勾、勾左侧实时音量条
市场登录
- 抽出共用 GithubLoginModal 与 ui/Modal,扩展市场与风格市场登录统一走弹窗
- 修复风格市场登录弹窗「先小后大」尺寸跳动(各阶段固定 minHeight)
弹窗动画
- 去掉开启动画里的 blur 滤镜(卡顿 / 闪烁),改纯 opacity + transform
- 设置弹窗切 tab 内容轻微淡入;各处弹窗动画时长 / 缓动统一到 global.css
网络
- 新增 net.rs:进程级共享 reqwest 客户端(连接池复用)+ 传输层失败指数退避重试
2026-05-22 20:56:06 +08:00
baiqing and Claude Opus 4.7
82ab2439fb
chore(release): bump version to 1.3.4-12 (Beta) — 磨砂玻璃质感 + ASR/Windows/Linux 修复
...
自 v1.3.4-11-beta-tauri 以来的改动:
- feat(ui): 给划词追问框与语音胶囊加磨砂玻璃质感(#519)
- fix(linux): 修复 Linux 主窗口控件(#518 / issue #517)
- fix(windows): 缩短 Windows IME 提交超时(#514 / issue #491)
- fix(windows): 流式 SendInput 节流(#513 / issue #491)
- feat(asr): 新增更大的 Foundry Whisper 模型(#512 / issue #511)
- fix(asr): 修复智谱 ASR endpoint 处理(#510 / issue #507)
- fix(ui+network): 更新/登录/网络检测/市场加载四项修复
- fix(asr): 修复智谱批量 ASR 分片(#509 / issue #508)
本次只动版本号,逻辑改动已在上述 PR 落盘。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-22 08:52:37 +08:00
baiqing
a88860cd90
feat(ui): 给划词追问框与语音胶囊加磨砂玻璃质感
...
webview 无法模糊透明窗口背后的桌面(Tauri 上游限制 #2827/#10064/#6876),原 backdrop-filter 在 qa / capsule 透明浮窗里是死代码。改用纯静态 CSS 的「假毛玻璃」:半透明白底 + 分形噪点颗粒 + 内描边高光 + 柔和阴影,三平台像素一致、零运行时开销。
- tokens.css: 新增 --ol-frost-grain(不透明灰度分形噪点 data URI)
- global.css: 新增 .ol-frost 类,::before 叠噪点颗粒层
- QaPanel / Capsule: 外壳套用 .ol-frost,移除这两个面上死的 backdrop-filter
2026-05-21 23:26:13 +08:00
baiqing and Claude Opus 4.6
c729fc59e9
fix(ui+network): 更新/登录/网络检测/市场加载四项修复
...
1. 更新检查:超时从 8s 提至 15s,error 态展示具体错误原因 + 重试按钮
2. GitHub 登录:device flow 两个 HTTP 请求加 15s timeout,防网络差时永远卡住
3. 网络连通性:新增 check_network 命令(HEAD apic.openless.top + github.com),
PermissionsSection 从硬编码"可用"改为真实探测 + 30s 轮询 + 离线重试
4. Marketplace:加载失败卡片增加重试按钮
5. i18n:五语言新增 networkOffline / settings.about.retryBtn
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-05-20 20:49:47 +08:00
baiqing
ce6818cc6f
chore(release): bump version to 1.3.4-11 (Beta) — UI 多语言精简 + SavedToast 统一定位 + Windows 听写后 SendInput 降压
...
合并 #503(fix(windows): reduce SendInput pressure after dictation):
听写结束后降低 SendInput 调用压力,优化 coordinator/dictation/insertion 路径。
合并 #505(fix(ui): 统一 SavedToast 弹框位置与进出方向):
SavedToast 默认停靠右上角,新增 slideFrom 属性支持 right/top 两种进出方向,
SettingsModal 用 slideFrom="top" + absolute 锚定内容区。
合并 #506(refactor(ui): 精简多语言文案 + 设置/风格/市场界面与图标重构):
精简 en/ja/ko/zh-CN/zh-TW 过长功能描述文案,
风格包卡片与编辑器抽屉改用 framer-motion 进出动效,
Settings/Marketplace/shared/Icon 界面重构。
本次只动版本号,逻辑改动已在 #503 #505 #506 落盘。
2026-05-20 18:23:11 +08:00
baiqing
fbeddc5a0a
refactor(ui): 精简多语言文案 + 设置/风格/市场界面与图标重构
...
- i18n: 精简 en/ja/ko/zh-CN/zh-TW 过长的功能描述文案
- Style: 风格包卡片与编辑器抽屉改用 framer-motion 进出动效
- Settings / Marketplace / settings/shared / Icon: 界面重构
- tokens.css 与依赖随之微调
2026-05-20 16:19:27 +08:00
baiqing
1e4f6a5bed
fix(ui): 统一 SavedToast 弹框位置与进出方向
...
- 默认停靠右上角(fixed top:20 right:28),与页头「风格市场/刷新/导入ZIP」
按钮同区;淡蓝 pill、0.8s 自动收回
- 新增 slideFrom 属性:'right'(默认,屏幕右侧进出)/ 'top'(上方进出),
始终"从哪来回哪去"
- SettingsModal 用 slideFrom="top" + absolute 锚内容区,借 overflow:hidden
裁边实现"从屏幕外上方进出"
- Style 页移除 bottom-right 的 offsetStyle 覆盖,回归统一默认
2026-05-20 14:47:17 +08:00
baiqing
b5dddb496a
chore(release): bump version to 1.3.4-10 (Beta) — Windows 流式插入 12ms flush
...
合并 #502(fix(windows): buffer streaming SendInput events):
SSE delta 在 12ms 时间窗内合并后再调用 type_unicode_chunk,
显著降低 Windows 流式输入路径上的 SendInput 调用频率与 CPU 占用。
mpsc 由 tokio unbounded 切到 std sync::mpsc,typer 任务里
用 recv_timeout 实现 flush 窗口,断开/失败后仍能 drain 完剩余 delta,
并把缓冲写入逻辑抽到 flush_streaming_insert_buffer 单元函数。
本次只动版本号,逻辑改动已在 #502 落盘。
2026-05-19 21:28:15 +08:00
baiqing
fbcf4993a1
chore(release): bump version to 1.3.4-9 (Beta) — Windows capsule/QA Acrylic 回退
...
回退 #487 引入的 Windows capsule/QA 浮窗 apply_acrylic 调用 (PR #496 ),
解决浅色背景下 220×84 胶囊出现深色矩形的视觉 bug。
本次只动版本号,不携带其他逻辑改动。
2026-05-19 14:52:49 +08:00
baiqing
bd5dcb8a57
chore(release): bump version to 1.3.4-8 (Beta) + fcitx5 路径抓取/安装前缀修复
...
v1.3.4-7 显示:fcitx5 包名替换后构建本身已成功([100%] Built target openless),
但下一步立刻 exit 1。根因有两个:
1) cmake -LA 抓不到值
fcitx5 5.0.14 把 FCITX_INSTALL_ADDONDIR / FCITX_INSTALL_PKGDATADIR
设为普通变量而非 CACHE,cmake -LA 看不到 → grep 退码 1 → set -e -o pipefail
触发整步退出。
改从 configure 阶段 message(STATUS ...) 的输出抓(CMakeLists.txt 已经打印)。
2) CMAKE_INSTALL_PREFIX 默认 /usr/local 路径错
fcitx5 在 Ubuntu 上运行时只扫 /usr/lib/<arch>/fcitx5/,默认 prefix=/usr/local
会让 .deb 把插件安到 /usr/local/lib/fcitx5/,运行时找不到。
显式 -DCMAKE_INSTALL_PREFIX=/usr 强制 Debian 系标准路径。
历史 v1.3.4-3 其实也是这条 bug 路径,只是 cmake -LA 那行先挂掉没人意识到。
提取失败时打印 cmake-configure.log 末 50 行作为诊断。
2026-05-18 21:34:38 +08:00
baiqing
9bae92b4df
chore(release): bump version to 1.3.4-7 (Beta) + Linux fcitx5 包名拆分修复
...
v1.3.4-6 加的 apt-cache search 诊断揭示真因:Ubuntu 22.04 universe 在
v1.3.4-3 (Apr 2026) 之后把 fcitx5-dev 这个 meta 包移除了,源里只剩拆分后的
libfcitx5{core,utils,config}-dev 等子包。这也解释了 -4/-5/-6 为何连挂同样错误
"Unable to locate package fcitx5-dev":根本就找不到这个 umbrella 包了。
CMakeLists.txt 实际只 find_package(Fcitx5Core / Fcitx5Utils / Fcitx5Module),
对应:
libfcitx5core-dev
libfcitx5utils-dev
fcitx5-modules-dev
另外 fcitx5 CMake config 文件依赖 KDE 的 extra-cmake-modules (ECM),
和 libfcitx5config-dev 作为传递依赖一起补上。
诊断块保留(apt-cache search / os-release / sources.list.d),未来若再变包名
能立刻拿到证据。
2026-05-18 21:22:43 +08:00
baiqing
1960e0d602
chore(release): bump version to 1.3.4-6 (Beta) + 修 Linux CI fcitx5-dev 安装
...
v1.3.4-4 / -5 的 Linux 构建在 "Build fcitx5 plugin" 步骤连挂两次,
错误一致:"E: Unable to locate package fcitx5-dev"。同一 job 前面的
"Install Linux bundle deps" 步骤明明已经 apt-get update + 装好了一堆
universe 包,到 fcitx5 这步突然找不到 —— 表象与 GitHub Actions
ubuntu-22.04 runner 镜像弃用过渡期里 apt 元数据漂移的现象一致。
release-tauri.yml "Build fcitx5 plugin" 步骤增加三层防御:
1) sudo add-apt-repository -y universe(已启用则 no-op)
2) 本步骤内重新 sudo apt-get update,独立于上游 step 缓存
3) 安装失败时打印 apt-cache policy / search / os-release / sources.list.d
便于以后排查
同 commit 同时 bump 五处版本到 1.3.4-6 重发,让 PR #487/#488/#489
三个 Windows P0 修复带上 Linux 包一起进 Beta 通道。
2026-05-18 20:56:58 +08:00
baiqing
801bc0089b
chore(release): bump version to 1.3.4-5 (Beta) — Windows P0 三连修
...
包含 PR #487 / #488 / #489 三个修复,供 Windows 实机验证:
- #489 快捷键二次按键失效(toggle/stop 失灵,只能 ESC)
→ coordinator.rs hotkey_bridge_loop 改 block_on 顺序 await
- #487 capsule/qa 透明遮罩看不清
→ lib.rs Windows 下追加 apply_acrylic 兜底
- #488 autostart catch fall-through 复活主窗口(#468 残留)
→ App.tsx catch 加 return + 改善 warn 诊断
2026-05-18 20:23:18 +08:00
baiqing
cb2c233ebe
chore(release): bump version to 1.3.4-4 (Beta) — Windows #468 静默启动前端兜底
...
合并 PR #474 后随版本号一起出 Beta 包,供 Windows 端验证
startMinimized 兜底是否彻底关掉 #468 漏窗最后一公里。
2026-05-18 15:37:24 +08:00
baiqing
a4ef68237b
fix(test): Linux 加入 capsule_show_strategy NoActivate 测试断言
...
PR #451 (fcitx5 plugin) 把 Linux 加进 capsule_show_strategy_for_platform
的 NoActivate 分支,但漏改单元测试 capsule_show_strategy_matches_
platform_activation_contract 的 cfg —— 测试断言 Linux 还应该是
FallbackShow,结果 Linux CI red(Run Rust backend unit tests
panicked at coordinator.rs:3617)。
修法:测试的两组 #[cfg] 同步 Linux。同时在实现函数前加显式提示
注释:改 cfg 列表必须同步更新对应测试,防止下次再漏。
cargo test --lib capsule_show_strategy 本地通过。
2026-05-18 11:51:25 +08:00
baiqing
d1aff0f97c
Merge remote-tracking branch 'origin/main' into beta
...
# Conflicts:
# openless-all/app/package-lock.json
# openless-all/app/package.json
# openless-all/app/src-tauri/Cargo.lock
# openless-all/app/src-tauri/Cargo.toml
# openless-all/app/src-tauri/tauri.conf.json
2026-05-17 18:18:23 +08:00
baiqing
5d050d6121
refactor(insertion): 注释改写为 位置+用途+机制 结构
...
按新约定重写:删除 issue 号、Swift 原版对照、历史 trade-off 故事;
保留每段「这一段在哪里 / 做什么 / 怎么做」的最简说明。
作为后续核心代码注释统一清理的 calibration 样本。
2026-05-17 13:46:00 +08:00
baiqing
468b8bcbcb
fix(persistence): atomic_write 用唯一 tmp 文件名修 macOS 并发测试 race
...
并行 cargo test 时多个 Coordinator::new() 同时进入 StylePackStore/PreferencesStore
写流程:固定 tmp 文件 `preferences.tmp` 被互相覆盖,先 rename 的赢,后到的 rename 找
不到源文件 → ENOENT,macOS CI 偶发 `style pack store init: rename failed` panic。
改用 `<filename>.tmp-<uuid>` 让每个写者独占自己的 tmp;rename 失败时主动清理孤儿 tmp。
验证:本机 cargo test --lib(默认并行)连续 5 轮 270/0/0。
2026-05-17 13:45:46 +08:00
baiqing
d6d1fee77e
chore(repo): 移除内部 AI 协作 / 规划 / 审计文档,仅本地保留
...
公共仓库不再发布 CLAUDE.md / AGENTS.md / 内部 audit + roadmap +
github-tracking + superpowers + windows-*-tracking 等共 45 个文件。
- 全部用 `git rm --cached`,本地仍保留以供日常协作;
- `.gitignore` 加规则防止再次被 `git add` 拉回;
- 用户 docs(volcengine-setup / tauri-csp / references / 图片素材)
以及 ISSUE_TEMPLATE / workflows / pull_request_template 仍保留发布。
密钥层面审计同步完成:未发现 API key / token / 私钥泄露,
tauri pubkey 与 GitHub OAuth client_id 均为设计上公开值。
2026-05-16 22:07:30 +08:00
baiqing
e6749b1d71
chore(release): bump version 1.3.2-3 → 1.3.3 for Beta channel
...
为 v1.3.3-beta-tauri 发布周期 bump 版本,5 个版本字段同步:
- package.json
- package-lock.json (root + packages[""])
- src-tauri/tauri.conf.json
- src-tauri/Cargo.toml
- src-tauri/Cargo.lock (cargo update -p openless)
含本周期 Beta 主要改动:
- Pro 风格"清晰结构"提示词 v1.7(回 v1.3.0 设计哲学)+ Light 模式语音纠错
- 「我的发布」改为弹框形态(搜索/登录/关闭三段顶部布局,已下架 5 分钟自动消失,Modal 进入动画)
- Marketplace URL 硬编码 apic.openless.top(Settings 不再输入)
- 风格市场按钮移到 Style 页刷新左
- list cache (sessionStorage, 5min) 重开秒呈现 + optimistic UI (like/upload)
- GitHub OAuth Device Flow Phase 1(client_id Ov23liyv3nEucG7oMHNE,登录后自动填 marketplaceDevLogin)
- 上传 picker 两步式确认 + z-index 修复
2026-05-16 17:26:35 +08:00
baiqing
ec60f22761
fix(marketplace): 上传 picker 两步式确认 + z-index 修复(被「我的发布」覆盖)
...
UX 问题:用户在「我的发布」点 上传 → 选 pack 卡片 → 直接上传(无确认);
+ 弹框被「我的发布」(zIndex 50) DOM 顺序后渲染挡住。
修法:
1. Modal helper 接受可选 zIndex prop(默认 50);上传 picker 用 zIndex={60} 叠在 mypacks 之上。
2. 新 selectedUploadPackId state:点 pack 卡片切换选中(不立刻上传),蓝边 + 蓝实心圆 ✓。
3. 底部加「确定上传」按钮,未选中时 disabled;取消按钮重置选中状态。
4. openUploadPicker:更新流程下预选「建议更新」的同名本地包(多数情况下一键确认)。
5. onUpload / cancel 退出时 setSelectedUploadPackId(null) 清状态。
2026-05-16 17:18:56 +08:00
baiqing
86d89760d8
chore(oauth): 填入 GitHub App client_id Ov23liyv3nEucG7oMHNE
...
OAuth App client_id 非敏感信息,可直接 bake 进开源代码;secret 不进库。
GitHub App 的 Device Flow 行为:scope 参数被忽略,权限由 GitHub App 端配置;
其它流程跟 OAuth App 一致。
2026-05-16 17:09:00 +08:00
baiqing
54b5ec751c
feat: marketplace 按钮移到 refresh 左 + list cache 秒开 + GitHub OAuth Device Flow Phase 1
...
Style.tsx:
- 「风格市场」按钮从 PageHeader.titleRight 移到 .right 槽,放在「刷新」按钮左边(按用户需求)。
- 删除 titleRight 那块独立的 pill 按钮,与其他动作按钮统一为 Btn variant=ghost icon=cloud。
ipc.ts:
- 加 sessionStorage 缓存:readMarketplaceListCache / writeMarketplaceListCache,5 分钟 TTL。
- 加 GitHub OAuth Device Flow IPC wrappers:githubDeviceFlowStart / githubDeviceFlowPoll + 类型定义。
commands.rs:
- 新增 github_device_flow_start:调 GitHub /login/device/code,返回 user_code/device_code/verification_uri。
- 新增 github_device_flow_poll:轮询 /login/oauth/access_token,拿到 token 后调 /user,返回 login。
- GITHUB_OAUTH_CLIENT_ID 常量:留空 + 详细错误指引(去 https://github.com/settings/applications/new 注册);
支持环境变量 GITHUB_OAUTH_CLIENT_ID 覆盖(dev 方便)。
lib.rs:
- 注册 github_device_flow_start / github_device_flow_poll 到 invoke_handler。
Marketplace.tsx:
- items state 用 readMarketplaceListCache() 做 lazy init —— 重开「风格市场」秒看到上次默认视图。
- refresh() 拿到默认视图(popular + 空 query)的列表后写缓存。
- 加载 UI 改成 (loading && items.length === 0) —— 有缓存时不显示「加载中」遮挡数据。
- OAuth 状态机:idle → starting → pending (展示 user_code) → success / error。
- 「我的发布」弹框里的 @login chip 点击 → 触发 GitHub OAuth Device Flow;浏览器自动拉起 verification_uri;
轮询直到用户授权完成;拿到 login 后自动 updatePrefs(marketplaceDevLogin)。
- 新 OAuth 弹框 UI:大字号 user_code + 一键复制 + 打开浏览器 + 取消 + waiting pulse。
Phase 2 留给后续:marketplace backend 验证 GitHub JWT 防止 X-Dev-User 伪造。
2026-05-16 17:01:54 +08:00
baiqing
8df0a3e140
feat(marketplace): 硬编码云端 URL + 我的发布弹框新布局 + 已下架自动消失 + Modal 进入动画
...
commands.rs:
- 新增 MARKETPLACE_BASE_URL = "https://apic.openless.top " 常量,marketplace_url_from_prefs 忽略 prefs 强返该常量。
- 避免用户在 Settings 改错地址导致连不上;GitHub OAuth 上线后再开放白名单 / 多 endpoint。
Settings.tsx:
- 删除 marketplaceBaseUrl 输入行 + onMarketplaceBaseUrlChange callback;保留 marketplaceDevLogin 输入(OAuth 上线前的过渡)。
Marketplace.tsx:
- 「我的发布」弹框顶部改一行:[🔍 搜索...] (flex 1) + [A @login] chip + [×] 关闭。
- 第二行:计数信息(左)+ 刷新 + 上传(右)。
- 已下架包 5 分钟后自动从「我的发布」隐藏:visibleMyPacks 加 withdrawn cutoff filter;弹框打开期间 setInterval(30s) tick nowTick。
- @login chip 点击触发 toast 提示 GitHub Device Flow 开发中(下轮接入);保留 marketplaceDevLogin 作过渡身份。
- Modal 组件加进入动画:backdrop fade-in (.14s) + card scale-up (.18s, spring easing)。
- 清理:删未用的 accountTitle 变量。
ipc.ts:
- mockSettings.marketplaceBaseUrl 默认值改成 "https://apic.openless.top "(与后端硬编码一致)。
2026-05-16 16:47:41 +08:00
baiqing
b5db6482fe
feat: 我的发布 modal + Pro v1.7 默认提示词对齐 + optimistic UI
...
Marketplace.tsx:
- 「我的发布」从 sort mode 改为弹框形态(与上传/详情共用 Modal 组件),叠在风格市场页面之上。
- 弹框结构:标题 + 账户信息(avatar/login/已发布数/审核中数)+ 搜索(左上,独立 myPacksQuery state)+ 刷新 + 上传 + 单列包卡片。
- 页面右上角 上传 按钮删除,避免与弹框内 上传 重复;保留「我的发布」入口 + 刷新。
- onLike: optimistic UI —— 点击立即切红心 + 调 likeCount,服务端回来后用真实值校准,失败 rollback。解决用户点了感觉没生效的问题。
- onUpload: optimistic UI —— 拿到 200 立即把新包推到 myPacks 最前(状态用服务端返回的 'pending'),后续 1.5s/5s polling 校准真实数据。解决等 polling 才显示的「上传特别慢」感知。
types.rs:
- PolishMode::Structured 整段回归 v1.7 设计哲学:砍掉 v1.5/v1.6 的失败定义堆叠 + 判定流程 + 事项切分算法等元规则;保留简洁规则块;用高密度演示性示例让模型学结构化模式。
- PolishMode::Light 新增「# 语音纠错 + 主动推断」段(按置信度分级处理 ASR 误识别 → Token/Secret Key/Claude/Gemini 等技术词主动修正)。
polish.rs:
- 同步更新 Structured prompt 单元测试 assert,防回归到 v1.4/v1.5/v1.6 关键词。
2026-05-16 16:23:52 +08:00
baiqing
68b9af3086
feat(polish): Pro 风格"清晰结构"提示词迁移 + 配套前后端改动
...
types.rs:
- PolishMode::Structured 整段重写为 Pro 风格短版(强制结构化触发 / 场景优先级 / 输出格式 / 术语纠错 / 反 AI 自述)。
- builtin StylePack Structured 的 description / example / tags 对齐 Pro。
- Phase B 强化:任务首段加"多事项罗列";强制结构化触发新增"3+ 完整句";新增示例 3 产品 UI 反馈。
前后端配套调整(一起进迁移):
- backend: commands.rs / lib.rs / polish.rs / persistence.rs。
- frontend: ipc.ts / types.ts / pages/Marketplace.tsx("我的发布"等)/ pages/Style.tsx。
Pro pack 镜像:~/Downloads/openless-pro-packs/OpenLess-清晰结构-PRO.zip 升级到 1.4.0(旧版 .bak-<timestamp> 自动备份)。
ipc.ts mockFullStylePrompts 保持简化 dev 预览,未跟随生产 prompt(与 Tauri 生产路径解耦)。
cargo check ✓(src-tauri workspace)。
2026-05-16 14:06:22 +08:00
baiqing
37a2138537
chore(release): bump version to 1.3.2 (Stable)
2026-05-15 23:05:04 +08:00
baiqing
461a4f3fa7
fix(prompt): keep '5) 自动纠错' prefix so guard test still matches
...
CI 测 polish::tests::common_rules_include_auto_correction_and_natural_organization
hard-codes 'prompt.contains("5) 自动纠错")' 作为 guardrail;上一 commit 把前缀
改为「ASR 主动纠错」导致 4 个 mode 都失败。前缀回到「自动纠错」,新增说明
夹在括号里:'5) 自动纠错(ASR 主动纠错,按置信度分级处理)'。
2026-05-15 22:31:33 +08:00
baiqing
2b6f478018
chore(stable): disable marketplace entry + strengthen ASR correction rules
...
Marketplace entry → 灰色 pill + 点击 toast「暂时未开放」
- 风格市场云端服务尚未上线,先在 UI 层禁用入口
- 真正功能(Marketplace 组件 / IPC / backend client / MarketplaceModal)全部保留
- 后续云端就绪时改回 onClick={() => setMarketplaceOpen(true)} 即可恢复
- 配色从蓝色 pill 改为灰色,明确视觉禁用语义
ASR 主动纠错升级(吸收「完全重写」社区 prompt 的优点)
- types.rs::COMMON_RULES 规则 5 重写:
- 三级置信度策略(高 → 直接换;中 → 最优候选;低 → 保留)
- 中文音译 → 英文技术词还原(脱肯/西克瑞特/埃克塞斯 Token...)
- 技术字段大小写规范化(API/App ID/Access Key/Secret Key/OAuth/JWT/UUID 等 12+ 字段)
- 大小写敏感场景例外(代码变量 / Bash / 路径 / URL 段保留)
- 新增规则 6:禁止输出修改说明 / 原文对比 / 编造字段,所有模式无例外
- 4 个 builtin pack(Raw/Light/Structured/Formal)共享 COMMON_RULES 自动获益
2026-05-15 22:18:58 +08:00
baiqing
3cedb72a1d
feat(marketplace): derivative version + like toggle + my-pack management + UX polish
...
客户端配套 backend marketplace 更新:
衍生版本链路:
- StylePack 新增 originPackId / originAuthorLogin(仅 set_origin 通道写入,
普通 save 路径不会清掉)
- marketplace_install 拉 detail → 安装后写 origin 绑定
- marketplace_upload 把 originPackId 塞到 multipart;本地原创首发后回写自己
的远端 id 当 origin,让同设备后续走 supersede
- 卡片 / 详情 / 本地列表都加「衍生自 @<author>」绿色 pill;过滤掉自己 != 衍生
点赞 + 我发布的:
- 新增 marketplace_my_likes IPC(GET /me/likes)→ likedIds Set
- 心形 ♥/♡ + 红色已赞 + spring 缩放动画
- 排序栏第 3/4 项「我赞过的」/「我发布的」客户端 filter
发布流程:
- 编辑器 dirty 时自动 save 再 upload,不再阻塞
- 内置 pack 双层禁发(按钮 disabled + handler early return)
- 上传 picker 过滤 builtin
- 失败 toast 6s 自动消失
- Style 页 toast 改右下角,避开「导入 ZIP」按钮
风格市场弹窗:
- 整合到 Style 页面 modal(左侧 nav 去掉 marketplace tab)
- 右上 32×32 圆角 X 按钮;左上「@<login>」登录身份 pill
- 内容区右下角小 toast,从右滑入 / 停留 / 向右滑出
- 详情页右下「🗑 撤回发布」(仅作者可见,confirm 后 DELETE /packs/:id)
2026-05-15 19:14:46 +08:00
baiqing
9e119e2a2f
fix(marketplace): stale detail response guard (pr_agent #444 round 3)
...
跟 round 2 同类 race condition:openDetail 用户快速点两张卡片时,先点 A 的
detail response 可能晚于 B 到达 → 覆盖 B 的 detail / Install / Like 作用错对象。
修:复用 useRef seq token 模式,detailSeqRef 单调递增,response 比较 seq 丢
弃 stale。逻辑跟 refresh() 完全对称。
2026-05-15 14:52:22 +08:00
baiqing
4af7fec82f
fix(marketplace): UUID-v4 whitelist on pack_id + stale-response guard (pr_agent #444 round 2)
...
pr_agent 提的两个真问题:
1. Security: arbitrary file write —— marketplace_install 用 backend-controlled
pack_id 拼临时文件路径。若 backend 被攻陷返回路径遍历 id,可写客户端任意位置。
修:4 个 marketplace_* IPC 全部加 is_valid_session_id() UUID-v4 白名单
校验(跟 read_audio_recording 同套 boundary 校验)。
2. Race condition: 搜索 refresh 旧请求晚到覆盖新结果。用户连续输入时体验差。
修:useRef 单调递增 seq token,response 到了 check seq 是否最新,stale 直接丢。
cargo test 263 全过;tsc 0 error。
2026-05-15 14:48:05 +08:00
baiqing
242f7ef8cd
feat(marketplace): one-click publish + Settings marketplace config (goal 2.e)
...
Goal 2.e 一键发版到云端:
- Style.tsx 详情页加「发布到风格市场」按钮(在导出 ZIP 旁),
调既有 marketplace_upload IPC。disabled 直到用户在 Settings 配 GitHub login。
- Settings.tsx 加「风格市场」折叠区:marketplaceBaseUrl + marketplaceDevLogin
两个 input。base URL 空 = localhost:8090 dev 默认;生产填 https://api .<domain>。
- 5 语言 i18n(zh-CN/en/ja/ko/zh-TW)补全 marketplace 相关 settings 文案
cargo test 263 全过;tsc 0 error。
2026-05-15 14:25:51 +08:00
baiqing
c9c126730c
feat(marketplace): Phase A — 客户端 Marketplace tab (Goal 1)
...
围绕 user goal 1 (a-e) 实现:
- (a) 后端验证:5 个 marketplace_* IPC,HTTP 通过 reqwest 调 backend
- (b) 上传与拉取无问题:marketplace_install / marketplace_upload 复用本地 ZIP IPC
- (c) 单独弹窗:详情 + 上传选包器走 Modal 半透明背景中央卡片
- (d) 搜索框:顶部 input 300ms 防抖 + server-side ?q= 过滤
- (e) 按排名推荐:默认 sort=popular(按 like_count DESC)
后端 IPC(commands.rs):
- marketplace_list / detail / install / upload / like
- HTTP base URL 走 prefs.marketplace_base_url(默认 http://127.0.0.1:8090)
- dev-mode auth 走 prefs.marketplace_dev_login → X-Dev-User header
- install 路径:下载 ZIP 到 temp → 调既有 import_from_zip → 删 temp
- upload 路径:export 本地 pack → multipart POST → 后端入审核队列
UserPreferences 加两个字段(5 处 wiring:struct/Wire/Default×2/Deserialize):
- marketplace_base_url (空 = localhost:8090 默认)
- marketplace_dev_login (空 = 上传按钮 disabled)
前端:
- types.ts 加 MarketplaceListItem / MarketplaceDetail
- ipc.ts 加 5 个 wrapper + mock fixture(vite dev 模式仍可演示 UI)
- pages/Marketplace.tsx (~350 行) UI:搜索 / 排序 toggle / 卡片 grid / 详情弹窗 / 上传选包器
- FloatingShell.tsx + state/useAppState.ts 加 marketplace AppTab
- 5 语言 i18n 补全 nav.marketplace + marketplace.* 子树(en/zh-CN/zh-TW 完整,ja/ko nav 本地化 + 子树 fallback en)
cargo test 263 全过;tsc 0 error。
2026-05-15 14:02:55 +08:00
baiqing
efa94afc27
chore(release): bump version to 1.3.2-3 (Beta)
2026-05-15 12:35:02 +08:00
baiqing
55c0c64671
fix(llm): don't retry on timeout to avoid duplicate billing (pr_agent #443 round 2)
...
pr_agent #443 review 指出 Duplicate Request 风险:
> Retrying after send() fails can submit the same LLM request twice if the
> first attempt already reached the provider but the connection dropped
> before a response was returned. For non-idempotent completion calls, that
> can mean duplicate billing and two completions for one user action.
事实分析 reqwest::Error 各 variant:
- is_connect() → TCP 握手没建立,server 不可能收到 → 安全 retry
- is_request() → HTTP 请求层错误(构造问题),server 没收到完整请求 → 安全 retry
- is_timeout() → client 设置的 timeout 到了,server 可能已经收到并在处理
(非幂等 completion 调用)→ 不安全 retry,会重复 billing
修法:从 retry 触发条件移除 `|| e.is_timeout()`。timeout 直接返回
LLMError::Timeout,不再重试。
user 实际看到的失败模式是 "error sending request"(reqwest::is_connect),不在
被移除范围内,覆盖率不变。
注:pr_agent 同轮提的 "Ticket compliance ❌ Not compliant 442" 是 false positive
—— pr_agent 把 PR description 里提到的 #442 当成本 PR 的 ticket id;#442 是另一
个独立 PR(A-D 默认值 / 提示词重构),已 merge。
cargo test 263 全过。
2026-05-15 11:43:39 +08:00
baiqing
eb5430dc4a
fix(llm): retry transient network errors once before failing polish
...
用户反馈日志显示 streaming polish 偶发失败:
[coord] streaming polish FAILED: network error:
error sending request for url (https://api.deepseek.com/v1/chat/completions )
诊断:失败发生在 reqwest `request.send().await` 阶段(不是 HTTP 4xx/5xx),
属于 connect / request / timeout 三类 transient 错误。同一 session 内大量
polish 调用成功,证明网络没断、是间歇性抖动。
修法:抽 `send_with_transient_retry` helper,首次失败 + 错误是 transient
(is_connect / is_request / is_timeout)→ sleep 500ms 重试一次。retry 第二次
失败按原 LLMError::Timeout / Network 返回。HTTP 4xx/5xx 走 response.status()
分支不受影响。
适用范围:3 处 reqwest send 都用 helper:
- chat_completion_messages_streaming (SSE 流式,line 720)
- chat_completion_messages_streaming 的非流式兄弟 (line 591)
- send_chat_request 一次性 chat 调用 (line 517)
retry 安全前提:传入 RequestBuilder body 必须是内存型(json/form),用
`try_clone()` 复制;3 处都满足。对流式路径 retry 安全是因为失败发生在 SSE
开始前 → on_delta 必然未被调用 → 不会重复输出。
注:Codex OAuth 路径(line 1085)使用独立 client,结构不同,本 PR 不动;
后续如有相同抖动反馈再扩展。
cargo test 263 全过。
2026-05-15 11:37:34 +08:00
baiqing
0db0ce4e5e
feat: streaming-on by default, structured default mode, agent-style hotword block in middle
...
围绕 user 反馈(用户主动测试后给的迭代清单)做 4 项调整:
A. streaming_insert 默认 false → true
- 流式落字感知延迟低,所有 fallback case 都已经接好
- CJK IME / Codex / Gemini provider 自动回落到一次性路径,对存量用户无感
- 影响 mock + test fixture 一并更新
B. default_mode: PolishMode::Light → PolishMode::Structured
- 新装用户开箱默认走清晰结构 mode,对多事项口述场景更合适
C. 热词与纠错模块从「prompt 末尾」移到「ROLE_BLOCK 之后」
- 新增 types.rs::HOTWORDS_PLACEHOLDER = "{{HOTWORDS}}"
- default_style_system_prompt_for_mode 拼接顺序:
ROLE_BLOCK + {{HOTWORDS}} + task_and_example + COMMON_RULES + OUTPUT_BLOCK
- polish.rs::build_hotword_block 统一生成 agent-style 错别字纠正 + 热词列表文本
(明确告诉模型「转写来自 ASR 可能含错别字」,比旧的「热词:...」措辞更强)
- polish.rs::compose_system_prompt 找占位符替换;用户自定义 prompt 无占位符 + 热词
非空 → 末尾追加(兼容历史);空热词 → 原 prompt 不变(保留旧测试断言)
- preview 跟 system prompt 用同一段文本,消除「设置看一段,发给 LLM 是另一段」不一致
D. Style Pack 新建预填示例 prompt
- Style.tsx 新增 NEW_PACK_PROMPT_TEMPLATE 含 # 角色 / {{HOTWORDS}} / # 任务 /
# 通用规则 / # 输出 4 段结构,用户照着改即可
- 让用户看到 placeholder 怎么用,决定是否保留/移动/删除
cargo test 263 全过;tsc 0 error。
测试反馈:本地构建 1.3.2-2 装到 /Applications 跑通 A-D 全部功能,无回归。
2026-05-15 11:26:49 +08:00
baiqing
1234dcd9c0
fix(asr): shorten 403 message to '凭据被拒(403)'
...
原文案带 Settings 引导 + SAUC 资源说明,capsule 上显得拥挤。简化到 5 个字 + 状态码,原因留在错误类型 doc comment 里。
2026-05-15 09:28:07 +08:00
baiqing
5c9ebe1930
fix(asr): surface Volcengine 403 as 'credentials rejected' instead of raw HTTP error
...
用户反馈"豆包云端语音连接不了",日志显示 9 次相同的:
[coord] open ASR session failed: connection failed: HTTP error: 403 Forbidden
原因不是网络不通(网络通到 Volcengine 才会有 HTTP 状态码),而是凭据被拒:
App ID / Access Token 错、或账号没开通 SAUC bigmodel 资源。当前 capsule
显示原始 `HTTP error: 403 Forbidden`,用户看不懂、客服需要解释一遍。
修法:在 volcengine.rs 加 classify_connect_error 函数,握手收到 401/403 时
转成新的 VolcengineASRError::AuthRejected(status) variant;它的 thiserror
display 直接是中文「凭据被拒(HTTP 403):请检查 Settings → 凭据 → Volcengine
的 App ID 和 Access Token,或确认账号已开通 SAUC bigmodel 资源」。
coordinator 沿用原有错误透传路径,capsule 文案自动从英文变中文具体引导。
其它握手错误(DNS / TLS / connection refused)仍走 ConnectionFailed,文案不变。
cargo test 258 全过。
2026-05-15 09:20:43 +08:00
baiqing
5695d8c467
chore(release): bump version to 1.3.2-2 (Beta)
2026-05-15 08:42:08 +08:00
baiqing
3125de88fb
fix: normalize TOCTOU NotFound in read_audio_recording (round 3)
...
pr_agent round 3 提的 Missing-file handling 兜底:
read_audio_recording 在 exists() 检查后到 tokio::fs::read 之间,文件可能因
prune(条数 cap / retention 清理 / 用户手动删)而消失。原实现把 NotFound 错
格式化成 'read wav failed: No such file...' 这种 OS 原文,前端字符串匹配
'recording not found' 接不住,UI 显示一次 generic error 而不是隐藏按钮。
修法:read 失败时显式判 ErrorKind::NotFound → 返回跟 exists() 失败同样的
'recording not found' 字符串。前端单条 catch 就稳,不依赖本地化 OS 错误。
注:pr_agent 同轮提的 "Build break"(arch.lock() 返回 Result)是 false positive
—— recorder.rs 用 parking_lot::Mutex 而非 std::sync::Mutex,.lock() 直接返回
MutexGuard 无 Result。本地 cargo test 258 全过、3 平台 CI build 都绿可证。
cargo test 258 全过。
2026-05-14 21:31:47 +08:00
baiqing
67d1277361
fix: address pr_agent Stale closure + Missing file check (round 2)
...
pr_agent 二轮 review 又提了 2 个 issue,本 commit 解决:
Stale closure (AutoUpdateGate.tsx)
- 原 useEffect 依赖 [enabled],tick 闭包捕获渲染时的 u;u.status 变化时 tick
读不到新值,极端时序下 60min interval 触发的 tick 可能在用户已经手动打开
UpdateDialog 的情况下错过 busy 检查,并发触发第二次 checkForUpdates。
- 修:useRef(u) + 每次渲染同步 uRef.current = u;tick 读 uRef.current 始终拿
最新 useAutoUpdate 返回值,避免 stale 状态判断。
Missing file check (History.tsx)
- hasAudioRecording 只代表「录音时 wav 写盘成功」,但 audioRecordingMaxEntries
/ historyRetentionDays 之后 prune 可能已删 wav。前端无条件渲染按钮 → click
→ 后端返回 'recording not found'。属于 UX 不优雅(功能有 error UI 兜住)。
- 修:父组件加 audioMissingIds: Set<string>;AudioRecordingPlayer 加 onMissing
回调,遇 'not found' 错误时调用父让 id 加入 set;导出按钮 catch 同样错误
也 mark missing;按钮组渲染条件改为 hasAudioRecording && !audioMissingIds.
has(id),一次点击后永久隐藏,不再让用户撞同样的 error。
cargo test 258 / tsc 0 error。
2026-05-14 21:15:18 +08:00
baiqing
13839a2fd4
fix: address pr_agent Wrong Flag + Missing Audio review
...
pr_agent review #436 提了两个跟 has_audio_recording 字段相关的 issue,本 commit
全部修复:
Wrong Flag (dictation.rs:1551 polish 收尾路径)
- 原实现:has_audio_recording: Some(prefs.record_audio_for_debug)
以「开关是否打开」当真值。但 Recorder::start 内部 WavArchiver::create 可能失败
(recordings/ 创建不出 / 权限不足 / 磁盘满),开关 on 但 wav 没真写盘时,前端会
渲染播放按钮、点击得到 'recording not found'。
- 修法:Recorder::start 返回值加第三个 bool = archive_active。Inner 加
audio_archive_active: AtomicBool 字段,begin_session 时写入。history 写入路径
读这个字段而不是 prefs,反映真实写盘状态。
Missing Audio (dictation.rs:1233 empty-transcript 失败路径)
- 原实现:has_audio_recording: None,即使开关 on 也强行 None。但磁盘上 wav 仍存在
(recorder 已走完整段录音)。讽刺的是:ASR 没识别到文字恰好是用户最想听原始录音
诊断的场景。
- 修法:empty-transcript 路径同样用 inner.audio_archive_active.load(...)。
与 polish 路径一致。
副作用最小:
- SessionState 不动(不污染 10 个构造点)
- 改 Inner 加一个 AtomicBool(2 个构造点已补)
- Recorder::start 返回元组扩第 3 项;3 个调用点(dictation/QA/preview)都已更新
cargo test 258 全过。
2026-05-14 20:56:05 +08:00
baiqing
366f6c38eb
feat: polish hotword overrides, audio archive, auto-update check
...
围绕"ZIP 误识别 + AI 日报反馈"一波集中改动,共 7 项:
polish 提示词
- COMMON_RULES 规则 2 加热词例外(热词列表正确写法优先于"原样保留")
- 规则 5 自动纠错补英文短词同音示例(ZIP/VIP)
- 规则 2 显式举例带次版本号产品名(GPT-5.6 / Claude 4.7 / iOS 26.1)不省略小数
- Structured mode 主题数上限放宽给"多条独立新闻/日报"场景
- Structured mode 要求主题标题保留关键实体名
- 热词块尾部加「优先于规则 2」强约束
History 详情面板
- 修复复制按钮没 await 没反馈的 bug(1.5s 显示"已复制")
- 加 AudioRecordingPlayer(按需加载 wav → Blob → 原生 audio controls)
- 加导出录音按钮(anchor.download 触发浏览器下载)
Settings 新增
- 自动检查更新开关(默认 on,启动延 4s + 60min interval)
- 历史条数上限输入框(5–200,留空 = 200)
- 保留原始录音开关 + 录音条数上限输入框
录音归档(debug 开关版)
- recorder.rs WavArchiver(Drop 时回填 RIFF/data header)
- DictationSession.has_audio_recording 字段;history.id 与 SessionId 对齐
- persistence.rs 加 recordings_root / recording_path_for_session
- prune_recordings 双重 cap(days + count),仅扫 .wav,metadata 失败按过期处理
IPC 安全 + 性能
- read_audio_recording 改 async + tokio::fs::read 防阻塞主循环
- session_id 白名单 UUID-v4 字面校验 + 2 个单测覆盖路径越界
后续待优化(review 标记 H2 / M1 / M3):
- prune 在录音前调用,cap 边界少裁 1 条(最多多 1 个文件,不爆盘)
- WavArchiver Drop unwinding 时 header 长度兜底(QuickTime 可能拒播)
- has_audio_recording 跟磁盘脱钩(前端 catch 'recording not found' 已兜住)
cargo test 258 全过;tsc 0 error;5 语言 i18n 完整。
2026-05-14 20:27:05 +08:00
baiqing
e0a48ce801
chore(release): bump version to 1.3.2-1 (Beta)
2026-05-14 15:00:15 +08:00
baiqing
883ff74cf4
docs(marketplace): add style pack marketplace planning doc
...
预留风格包市场的 HTTP API + IPC 契约 + DTO + 鉴权/缓存/安全策略。
IPC stub 未实装;后端 endpoint 选型 + 服务端工程化待定。
2026-05-14 14:59:36 +08:00
baiqing
477e6da93d
feat(style-pack): rework UI + template-create path
...
UI:
- 「原文」改成标题旁的 pill 切换器,与 builtin 卡分离
- builtin 卡片按 light → structured → formal 排序,followed by imported 包
- 「+ 新建风格包」tile 固定在网格末位
- imported 卡片右上角换成红色 trash 删除按钮(builtin 显示装饰 sparkle 图标,无 delete)
- builtin 卡片背景做灰底处理;编辑按钮 disabled,"只读"
- 编辑按钮挪到底部,紧接「导出」右边
后端:
- 新增 IPC create_style_pack_from_template / persistence.create_from_template,「+」走这条路径直接落盘
- 编辑面板出场加 modal-backdrop-out / modal-drawer-out 两个 keyframe
清理:
- 删除 Settings.tsx 里 PR #429 留下的"润色 System Prompt 已迁移"死告示卡
- 删除 11 个相关 i18n key 跨 5 种语言
- 删除卡片上的「轮换 ON/OFF」按钮 + 编辑面板里同款 + metaStatus item
- BusyAction 移除 'toggling' 变体
- 删除 BUILTIN 选中态与 active 共用 highlight 的 bug
- SavedToast 统一替换 inline notice/error banner
2026-05-14 14:59:31 +08:00
baiqing
f89fd2ed22
chore(release): merge beta for Stable 1.3.1
2026-05-14 12:58:48 +08:00
baiqing
eca6fae8c0
chore(release): bump version to 1.3.1 (Stable)
2026-05-14 12:58:30 +08:00
baiqing
d3f56c2926
chore(release): v1.3.1-20 — Wayland callout 三命令 + Qwen3-ASR 长语音修复
...
- PR #433:Wayland callout 补全 --toggle-qa / --cancel-dictation
三命令并列 + 五语言同步翻译
- PR #434:本地 Qwen3-ASR 末段静默 padding 修末 chunk 丢内容;
动态超时 max(15, ceil(audio_s × 0.6) + 10) 修长录音超时
2026-05-13 23:11:13 +08:00
baiqing
41d2d9aa86
fix(local-asr): 修复 Qwen3-ASR 长语音末段丢内容 + 长录音超时
...
两个独立缺陷一并修:
缺陷 1(主要,丢内容):transcribe_stream 内部按 2s chunk 切片;
用户说完最后一个字立刻松键时录音缓冲没有任何静默尾巴,末 chunk
< 2s 拿不到静默帧 → C 引擎不收尾 → 该 chunk 转写结果被丢弃。等
5-10 秒静默再松键时由于尾部静默被录进缓冲反而正常。
修复:local_provider.rs transcribe() 把 PCM 转 f32 后追加 0.5 秒
(8000 个 f32 零值 @ 16kHz)静默,给 C 引擎收尾信号。duration_ms
仍按原始缓冲长度计算,padding 不计入。
缺陷 2(次要,长录音超时):COORDINATOR_GLOBAL_TIMEOUT_SECS = 15s
固定值;用户 RTF ≈ 0.3、慢机可达 0.5,60s 录音需 ~18s 转写就直接
超时。
修复:新增 local_qwen_transcribe_timeout(audio_secs) -> Duration,
公式 max(15, ceil(audio_s × 0.6) + 10);只在 Local Qwen 路径用
(Volcengine / Whisper / Bailian / Foundry / QA 路径不动)。配套
LocalQwenAsr::buffer_duration_ms() 不消费缓冲地读取音频时长。
加 4 条单测覆盖公式:短录音兜底 15s、长录音线性放大、ceil 部分秒、
0 秒边界。39 条 coordinator 测试全过。
2026-05-13 22:42:42 +08:00
baiqing
15c2ce560e
feat(wayland): callout 补全 --toggle-qa / --cancel-dictation 命令
...
#420 评论里 aeoform 反馈 1.3.1-19 在 Wayland 下 callout 只展示 --toggle-dictation
一条,没有提及 QA 触发用 --toggle-qa、取消用 --cancel-dictation。
把单条命令展示改为三条命令并列,每条独立"复制"按钮 + 用途短标签
(开始/停止录音、打开/关闭 QA 面板、取消当前录音)。GNOME / KDE 步骤
改为"重复添加 1-3 组";Hyprland / sway 步骤给出三行示例 + 帮助区
启用 pre-line 渲染多行配置片段。
5 份 i18n 文件(zh-CN 源、en / zh-TW / ja / ko 同步翻译)同步新增三条
label key 并更新步骤文案。后端 CLI 三条命令早已实现(cli.rs:41-43),
本次只补前端提示。
2026-05-13 22:38:30 +08:00
baiqing
38f202a010
chore(release): v1.3.1-19 — SelectLite zoom 偏移 + 闪动修复(PR #428)
...
bump 1.3.1-18 → 1.3.1-19,6 处版本号手动同步(bump-version.sh regex 不收
Beta 版本号):package.json / package-lock.json (root+nested) / tauri.conf.json
/ Cargo.toml / Cargo.lock(openless)。
[变更]
- SelectLite 下拉位置在 html.zoom != 1 下不再右偏(fontScale 的 large 档影响
最大);CSS zoom 在 WKWebView 下让 getBoundingClientRect 返回 post-zoom
坐标但 position:fixed 用 pre-zoom 坐标,positionPopover 现在补偿 zoom 转回。
- 下拉打开瞬间的位置闪动消除(popoverMounted state 触发 useLayoutEffect 同步
二次定位,替代 requestAnimationFrame 的 post-paint 校正)。
- 移除 macOS 走原生 <select> 的旁路分支,三平台统一自定义 popover。
2026-05-13 14:27:34 +08:00
baiqing
424d9738d9
fix(SelectLite): zoom 补偿修位置偏移 + 同步二次定位消除闪动 + 三平台统一
...
[zoom 偏移 — 真凶]
fontScale.ts 通过 html.style.zoom 整体缩放页面(small=.9 / medium=1 / large=1.1)。
WKWebView 在 zoom 下双标:getBoundingClientRect 返回 post-zoom(视觉)坐标,
而 position:fixed 的 left/top/width 被当 pre-zoom(布局)坐标处理。直接
`left = rect.left` 让 popover 视觉位置 = rect.left × zoom,右偏
rect.left × (zoom-1) 像素。trigger 越靠右、zoom 越大,偏移越大。
修法:positionPopover 拿到 rect 后,把视觉坐标除以 zoom 转回布局坐标再
setAnchor,浏览器渲染时 ×zoom 后回到正确视觉位置。这是 v1.3.1-17 注释里
那句"WKWebView 里 portal+position:fixed 的自定义 popover 位置漂移反复修
不干净"的真正根因——前几位修过的人没意识到 zoom 是分母。
[闪动]
之前 setPopoverRef 用 requestAnimationFrame 在 popover mount 后再校正一次
位置,但 RAF 在 paint 之后触发,导致「兜底位置 paint → 校正位置 paint」
两帧闪动。短选项尤其明显(fallback popoverHeight=280 vs 真实 60~100px 让
flipUp 决策反转)。改用 popoverMounted state 翻 useLayoutEffect 的依赖,
两阶段定位都同步在 paint 前完成,用户只看到一帧最终位置。
[移除 mac native 分支]
v1.3.1-17 因为上述偏移修不干净,把 macOS 改走原生 <select>(NSPopUpButton)。
zoom 补偿到位后自定义 popover 在 mac 上对齐 trigger,删掉 mac 原生分支
(含 detectOS import),三平台统一走自定义实现,视觉/键盘交互一致。
2026-05-13 14:10:04 +08:00
baiqing
1d0f01a4b5
chore(release): 补齐 package-lock.json 到 1.3.1-18
...
上一次 bump 漏改了 package-lock.json 的 root + nested version,
导致 beta push CI 的 'Verify version sync across all 5 files' 步骤红。
release-tauri.yml 已基于 v1.3.1-18-beta-tauri 出包成功,本 patch 只
为修复 CI 元数据对齐,不影响已发布产物。
2026-05-13 13:55:00 +08:00
baiqing
b4aa4972dd
chore(release): v1.3.1-18 — Wayland CLI 触发修复 #420
2026-05-13 12:47:03 +08:00
baiqing
effa12e5f1
fix(hotkey): Wayland 下用 CLI 触发录音,修复 #420
...
Wayland 协议禁止应用监听非聚焦窗口键盘事件,原 rdev 路径必然失效。
保留 X11 rdev 不动;Wayland 下走 stub HotkeyAdapter(不监听键盘),
通过 tauri-plugin-single-instance 把 `openless --toggle-dictation`
等 CLI 命令的 argv 转给主实例 coordinator,由桌面环境快捷键设置
绑定该命令实现全局触发。Settings → 录音 mount 时 invoke
is_wayland_cli_mode 拉状态,显示绑命令引导 callout
(GNOME / KDE / Hyprland / sway 四段步骤)。
新增:
- src-tauri/src/cli.rs — CLI intent 解析 + 10 个单测
- docs/issue-420-wayland-hotkey-research.md — 方案调研文档
改动:
- hotkey.rs Linux 分支:Wayland 检测命中走 WaylandCliAdapter stub
(不再硬拒绝 wayland_unsupported)
- lib.rs:single-instance 回调路由 argv → dispatch_cli_intent
- commands.rs:新增 is_wayland_cli_mode IPC command
- coordinator.rs:dictation_phase_for_cli + cli_toggle_qa_panel
暴露 CLI 入口,复用现有状态机
- Settings.tsx:WaylandHotkeyCallout 组件 + invoke pull 模型
- i18n × 5 locale:settings.recording.wayland.* 共 14 个键
macOS CGEventTap 和 Windows RegisterHotKey 路径零触碰。
2026-05-13 12:34:52 +08:00
baiqing
c5bdb02595
chore(release): v1.3.1-17 — Mac native select + 胶囊白底升 0.85 + ASR 行清理
...
[SelectLite]
- macOS 走原生 <select>(NSPopUpButton),不再用自定义 portal popover——
WKWebView 里 portal+position:fixed 的位置漂移问题反复修不干净
- Win/Linux 仍用自定义 popover:popover 锁到 trigger 宽(width 不再用 minWidth),
避免内容撑大跑出 trigger 范围
- positionPopover 横向 maxLeft 用 rect.width,两帧 left 一致
[Capsule]
- pill 白底 alpha 0.62 → 0.85(用户:"让白色更白一些")
- cancel/confirm 按钮保持 1.3.0 stable 取值;thinking 字号 17/weight 600/cap-shine
动画保留
- 此前 v1.3.1-9 ~ v1.3.1-15 多轮 alpha 微调 / NSVisualEffectView 实验全部回退
[Settings ASR 行]
- 下拉只保留云端 provider,删 disabled 的本地引擎条目
- 本地引擎激活时下拉锁住 + 显示一行"ASR 提供商已被接管"提示
- i18n 五语言加 settings.providers.asrProviderTakenOver
[版本]
1.3.1-8 → 1.3.1-17,四处版本号同步
2026-05-12 21:58:51 +08:00
baiqing
40c39e11d3
chore(release): v1.3.1-8 hotfix — SelectLite 死锁 + 玻璃统一
...
[CRITICAL fix: SelectLite 所有下拉打不开]
v1.3.1-7 (PR #426 ) 我引入了 deadlock:
- anchor 初始 null + portal 条件 `open && anchor && createPortal(...)`
- 我删了 useLayoutEffect 在 open=true 时调 positionPopover
- 改成 popoverRef callback ref(只在 DOM mount 时 fire)
- 但 popover DOM 挂载条件依赖 anchor 非 null → anchor 永 null → 死锁
用户报"所有竖向切换横幅的界面全都打不开了"——LLM 供应商 / ASR 提供商 /
paste shortcut / mirror / language / polish mode 等 SelectLite 下拉全部
点击无反应。这是我的 review 失误,深表歉意。
修:加回 useLayoutEffect 在 open=true 时调 positionPopover 一次(用 trigger
宽 fallback 立即设 anchor),保留 callback ref RAF 在 popover mount 后用
真实宽精确重定位。两步合并:anchor 立即不为 null → portal 渲染 → callback
ref 触发 → 重新精确定位。
[玻璃统一处理]
用户:"现在完全没有磨砂玻璃的效果,应该把底下的细控组件、边栏以及盖栏
等设置的边栏采用同一种方式处理"。
之前 main content (`<main>`) 用 `var(--ol-surface)` 完全不透明白底,跟透明
sidebar 视觉割裂。改成 `rgba(255,255,255,0.62)` + `backdrop-filter blur(18px)
saturate(170%)`,跟 sidebar 一起坐在 WindowChrome 磨砂底板上,全应用一块
连续玻璃。
[版本]
1.3.1-7 → 1.3.1-8,6 处版本号同步。
2026-05-12 19:38:29 +08:00
baiqing
5aafc29ee5
chore(release): bump version to 1.3.1-7 (Beta) + Capsule 磨砂玻璃 + thinking 黑底
...
[bump] v1.3.1-6 → v1.3.1-7。本版本含 PR #426 merged(SelectLite 位置/动画/
滚外关)+ 本 commit 的两件用户实机 surface:
[Capsule 磨砂玻璃 Windows 路径打开]
之前 Capsule.tsx Windows 路径 useBackdrop = os !== 'win' 强制关掉 backdrop-filter,
让 Windows 胶囊看上去就是白色 pill 没玻璃感。WebView2 现在支持 backdrop-filter,
打开让 Windows 玻璃感对齐 macOS:
- Pill: backdrop-filter blur(28px) saturate(180%)
- CircleButton (cancel): blur(12px) saturate(160%)
[Thinking 字体重做]
- 字号 17 保持,字重 700 → 600 稍细
- 底字浅亮黄 #FCD34D → var(--ol-ink) 黑(用户:"亮黄太显眼,黑底更稳")
- 中段扫光 var(--ol-blue) 深蓝不变(继续作为高对比"滑动"标志)
2026-05-12 19:16:24 +08:00
baiqing
167ceb297b
fix(SelectLite): 位置错位 + 加关闭动画 + 滚外部自动收缩
...
用户在 macOS 上反馈 LLM provider 下拉 3 个问题:
1. 位置完全错位(popover 跟 trigger 不对齐)
2. 没有关闭动画
3. 在 popover 外滚动应自动收缩,但当前会跟着 trigger 重定位
[位置错位根因]
positionPopover useCallback deps [],useLayoutEffect 在 open=true 时 fire
一次 —— 此时 popoverRef.current 还没挂载,popoverWidth 用 trigger.width 兜底。
Popover mount 后真实宽度 ≠ trigger 宽(长选项撑大),但 effect 不再重算。
修法:popoverRef 改用 callback ref,每次 popover DOM mount 时 RAF 推到下一帧
重算 anchor,拿到真实 popover 宽。同时 positionPopover 用 max(trigger 宽,
popoverRect 宽) 保证 popoverWidth 不低估。
[滚动外部 → 关闭]
之前 useLayoutEffect 监听 scroll 事件做 reposition。改成监听 'scroll' + 'wheel'
capture phase,target 在 popover 内(popoverRef.contains)保留打开(长列表
内部 scroll 不关),target 在外部 → closeMenu。同时 window resize 也强制关闭。
[关闭动画]
加 leaving state 让 popover 在 unmount 前播 ol-select-pop-out 反向 keyframe
(opacity 1→0 + translateY 0→-4 + scale 1→.98,跟入场对偶)。140ms 后真正
unmount + 清 anchor / highlight。
2026-05-12 19:02:43 +08:00
baiqing
ca5cb5277a
chore(release): bump version to 1.3.1-6 (Beta)
...
PR #425 合并后 bump。本版本相对 v1.3.1-5-beta 累积:
[胶囊动画]
- 入场 .26s → .38s,cubic-bezier(.16,.86,.32,1.18) 更强 spring overshoot
- 出场 .24s → .36s(EXIT_ANIM_MS 同步加到 360),cubic-bezier(.55,.06,.68,.19)
慢启动加速收尾的平滑曲线,让用户能看清"左右收缩 + 下移 + 淡出"
- thinking 字号 14 → 17,字重 500 → 700,浅亮黄底字 + 深蓝扫光
[LocalAsr Windows Qwen3]
- 删除顶部"白底显眼"提示 banner(已 inert + 灰显,banner 多余)
- Windows 列表为空时不再画 placeholder Card,简化为空白占位
- 千问3 ASR 标题加 amber 小 badge "实验性"
- 5 个 locale 新加 i18n key qwenExperimentalBadge
[polish prompt 反 AI 自述]
- OUTPUT_BLOCK 新加"# 反 AI 自述式表达(强约束)":禁词列表 +
保持原句人称视角 + 直陈原意不扩写
- Light task 加"工程化直陈"段
- Formal task 加"工程化正式"段(不展开为商务铺垫)
- Structured task 加"判断事项的标准"4 种独立事项形态,事项 ≥3 强制双层
即使输入听起来像顺着说下来的口播
2026-05-12 18:44:42 +08:00
baiqing
960889da7c
fix(polish): Structured prompt 加强"判断事项标准",提升结构化稳定性
...
用户报 Structured 模式不稳定 —— 同样输入有时双层 list 有时连贯段落。
失败示例:用户口述 4 个独立反馈(千问3 提示样式 + 让它消失 + 改实验性 +
其他没问题)输出成连贯段落,没归类成双层 list。
LLM 判断"事项数"时可能要求用户明说"第一""第二""另外"等连接词,
口语化输入没这些就误判为"一段连贯陈述"。
加强:Structured task block 顶部新加"默认行为:双层 list。判断事项的标准":
列出 4 种独立事项的形态(可独立成句的陈述、独立请求/建议、状态判断/结论、
针对模块的描述/要求),明确"事项数 ≥3 强制双层化,即使输入听起来像顺着
说下来的口播"。
跟前面 commit 35d53b8b 的"不可降级到轻度润色 + 多个组合需求处理规则"
形成三重 sticky:
- 规则 1:不可降级到轻度润色(事项 ≥3 必须双层)
- 规则 2:多组合需求按大类按口述顺序排
- 规则 3(本 commit):明确"事项"的判断标准,不依赖用户的连接词
2026-05-12 18:32:01 +08:00
baiqing
cb5b544c0f
fix: LocalAsr 灰显去 banner + 千问3 加实验性标签 + polish 反 AI 自述
...
[LocalAsr Windows 灰显简化(用户:"白底太显眼")]
- 删除顶部 qwenUnavailableOnWindows banner Card(白底浅橙 noise)
- 列表为空时的 placeholder Card 改成纯空 <div minHeight:60>,不再二次重复 banner 文案
- 灰显 + inert + opacity 已自我解释,不需要 banner 引导
[千问3 标记为「实验性」(用户拍板)]
- LocalAsr.tsx 在 qwenTitle 前加 amber-300 小 badge "实验性"
- 5 个 locale 新加 i18n key `qwenExperimentalBadge`:
- zh-CN: 实验性
- en: Experimental
- ja: 実験的
- ko: 실험적
- zh-TW: 實驗性
[polish 反 AI 自述(用户:"直抒胸臆,不加多余话;不要 AI 输出式语言")]
- OUTPUT_BLOCK 新加 "# 反 AI 自述式表达(强约束)" 子段:
- 禁词列表:"我们看了一下""我们发现""经过分析""综合来看""总体而言"
"整体来说""依我所见""根据情况""从结果来看"等代入第三方/自述视角的语句
- 保持原句的人称视角,原句没有"我们"就不引入
- 直陈原意,不扩写
- 不加修饰副词或铺垫句("值得一提的是""值得注意""值得考虑"等)
- Light task block 加 "**工程化直陈**" 段:
- 开发协作 / 任务清单 / 技术沟通 / 工作汇报场景按主谓宾陈述
- 不加修饰副词、铺垫句、AI 自述
- 输出长度尽量贴近原句字数 ± 20%
- 新增示例:用户原话"嗯我们目前看了一下没什么大问题就是缓存策略可能要改一下"
→ 输出"目前没什么大问题,缓存策略需要调整"(不引入"我们看了一下")
- Formal task block 加 "**工程化正式**" 段:
- 正式 ≠ 扩张;不展开为商务铺垫
- 不加"经过分析""综合来看""值得注意的是"等代入第三方视角的语句
- 输出长度 ± 30% 以内,不让正式化扩张到两倍长度
- 新增示例:用户原话"嗯这次发版前我们看了一下其实问题不大但还是建议把缓存改一改"
→ 输出"本次发版整体问题不大,建议调整缓存策略"(不写"我们看了一下""经过评估")
2026-05-12 18:27:33 +08:00
baiqing
80e840341b
fix(capsule): 入场出场动画加慢加曲线 + thinking 字号/颜色重做
...
用户在 v1.3.1-5 装机后反馈:
1. 胶囊入场效果不错但希望"再慢一点 + 曲线感"
2. 出场动画"看不到" —— 240ms 太快感知不到
3. thinking 字体"不明显",希望字大 / 色亮 / 滑动清楚
改动:
- @keyframes capsule-in: .26s → .38s,cubic-bezier(.16,.86,.32,1.18)
spring overshoot 更强,"从中心冒出向左右生长"更弹更曲线
- @keyframes capsule-out: .24s → .36s,cubic-bezier(.55,.06,.68,.19)
慢启动 + 加速收尾的平滑曲线,让用户能看清"左右收缩 + 下移 + 淡出"
- EXIT_ANIM_MS: 240 → 360 同步加长,避免定时器先于动画结束 unmount
thinking 配色(用户拍板,参考 d 项):
- fontSize 14 → 17(更大)
- fontWeight 500 → 700(更粗)
- 两侧底字:浅亮黄 #FCD34D (amber-300)
- 中段扫光:深蓝 var(--ol-blue) (≈ #2563EB)
- 浅黄暖底 + 深蓝扫光对比强烈但不刺眼,扫光滑过感清晰
2026-05-12 18:18:05 +08:00
baiqing
1a810c1c67
chore(release): bump version to 1.3.1-5 (Beta)
...
PR #423 合并后 bump。本版本相对 v1.3.1-4-beta 累积:
[3 个 dev task] (worktree-isolated dev agents + 3 个 reviewer)
- 胶囊动画:进入从中心冒出向左右生长,退出左右收缩 + 淡化 + 下移
- Windows 千问3 ASR 灰显 disabled + 不可激活提示 banner
- 5 个 SVG 重画:translate / vocab / history / overview / selectionAsk
[review feedback fix]
- Capsule EXIT_ANIM_MS / INITIAL_VISIBLE_STATE 抽 const
- Qwen3 disabled 区加 inert 让键盘 Tab 跳过
- overview icon 加 sparkline 数据线区分 layout icon
- selectionAsk 气泡尾巴拉到 y=23 防 viewBox 24 底裁切
[用户实机 surface]
- Vocab 词条大椭圆真根因:父 flex minHeight 拉伸子 item,加
alignSelf:flex-start 阻止
- Windows 原生顶栏 vs 玻璃色差:caption color 0xFFFFFF → 0x00F7F5F5
跟 glass 起始色一致;glass alpha 0.78 → 0.92 压色差
[polish prompt 反降级]
- Structured task block 加"不可降级到轻度润色"和"多个组合需求归类规则"
2026-05-12 17:46:25 +08:00
baiqing
76e0723613
fix(polish): Structured prompt 加强反"降级到轻度润色" + 组合需求归类规则
...
用户报 DeepSeek V4 Flash 走 Structured 模式时仍只做轻度润色(标点 + 断句
+ 去口癖然后输出一段连贯段落),没有按双层 list 结构化输出。模型能力较
弱时容易把"清晰结构"理解成"清楚地表达"而非"双层归类"。
加两条新规则到 Structured task block:
1. **不可降级到轻度润色** —— 明确禁止只补标点然后输出连贯段落,最低
输出形态是双层 list。即使原文听起来连贯,事项 ≥3 都必须双层化。
2. **多个组合需求处理规则** —— 用户原话:"当用户提出多个组合需求时,
要分别归入不同大类,并且按照顺序把这些组合需求做结构化整理"。
写进规则:按语义/领域分大类,按口述顺序排,每个大类用 (a)(b)(c)
子项,不允许合并丢失或重排到错误大类。
加在原有 # 任务(清晰结构) 标题之后、"**重要前提**"之前。前后顺序与
其他段落兼容,不动 ROLE_BLOCK / COMMON_RULES / OUTPUT / 示例。
2026-05-12 17:32:54 +08:00
baiqing
35d53b8be2
polish: 集成 review 反馈 + 用户新 surface 的 Windows 视觉修复
...
review 阶段标的 4 个 High 全部处理,加上用户在 v1.3.1-4 装机后新报的 2 个
Windows 视觉问题,本 commit 一次性收:
[review-capsule High]
- Capsule.tsx 抽 EXIT_ANIM_MS / INITIAL_VISIBLE_STATE 两个 const,去掉
`240` magic number + `isTauri ? 'idle' : 'recording'` 字面量重复
- 修正退出动画调度的 race 描述注释(cleanup clearTimeout 阻止 fire,
不是"定时器仍会触发")
[review-qwen3 High]
- LocalAsr.tsx Windows Qwen3 disabled wrapper 加 `inert` HTML5 属性,
让键盘 Tab 也跳过 disabled 区域(仅靠 pointerEvents:none 不挡键盘 +
aria-disabled 不传给后代)。两个 wrapper 都加。@ts-expect-error
注释解释为何这里需要绕过 TS lib.dom 旧版未收录 inert 属性。
[review-icons 2 High]
- Icon.tsx `overview`: 在三个 dashboard tile 顶部加 sparkline 数据线
区分 layout icon(之前几乎一样,14px nav 视觉无法分辨)
- Icon.tsx `selectionAsk`: 气泡尾巴 y=24 → y≈23,避免 strokeLinecap
round + strokeWidth 1.5 出 viewBox 底边被裁
[用户新 surface — Vocab 词条大椭圆]
- Vocab.tsx VocabChip 加 `alignSelf: 'flex-start'`。真根因(之前 PR
#422 误判为 button user-agent appearance):父 flex 容器 minHeight: 80
让 flex item 默认 align-self: stretch 把单个 chip 拉伸到 80px 高,
borderRadius:999 渲染成超大椭圆。alignSelf:flex-start 阻止拉伸。
[用户新 surface — 顶栏 vs 玻璃色差]
- lib.rs DWMWA_CAPTION_COLOR 从纯白 0xFFFFFF → 0x00F7F5F5
(rgb 245,245,247) 跟 WindowChrome glass linear-gradient 起始色一致
- WindowChrome.tsx glass alpha 0.78 → 0.92(PR #422 为加强玻璃感降的,
现在为压缩色差升回去,玻璃感由 backdrop-filter blur+saturate 提供)
后续:用户希望调研"完全取消 Windows 原生顶栏(像微信那样自绘)"——
属于 v1.3.1-6 级别 large rewrite,单独追。
2026-05-12 17:31:41 +08:00
baiqing
f44eb5958c
feat(icons): redraw translation / vocab / history / selectionAsk SVGs
2026-05-12 17:26:52 +08:00
baiqing
a981815b8b
feat(localasr): Windows 端千问3 ASR 改为灰显 disabled + 提示
2026-05-12 17:26:52 +08:00
baiqing
ad6cd93b10
feat(capsule): center-grow entry + contract-fade exit animation
2026-05-12 17:26:52 +08:00
baiqing
a7a9284db6
chore(release): bump version to 1.3.1-4 (Beta)
...
PR #422 合并后 bump。本版本相对 v1.3.1-3-beta 累积修复:
- Windows 默认字号 'large'(fontScale.ts UA 检测)
- Windows 原生标题栏底色刷成白色,与 sidebar 视觉统一(DWM CAPTION_COLOR)
- 全平台玻璃统一:WindowChrome 撤销 PR #419 留下的"Windows 100% opaque +
无 backdropFilter"分支,两平台用同一半透明 background + blur saturate(190%),
alpha 0.92 → 0.78 让玻璃感更明显但不过透
- Vocab 词条大圈再次根治:global.css button reset 补加 outline:none /
min-width:0 / min-height:0 / box-sizing:border-box
- polish ROLE_BLOCK 撤销 b2325a27 回滚,恢复 7e60bdb5 8-条规则状态
- polish ROLE_BLOCK 「意图难判」规则改为强制结构化(用户拍板的新版)
2026-05-12 17:00:05 +08:00
baiqing
76a4a4131f
fix(polish): ROLE_BLOCK"意图难判"规则改为强制结构化
...
旧版(7e60bdb5 引入):"意图难以判断 → 只做句子层面整理(标点、断句、
口癖去除)"——这条 safety net 在 Structured 模式下会让 LLM 退回 Light/Raw
行为,导致"清晰结构"模式对意图不明的输入不输出双层 list。
新版(用户拍板):意图难判时**强制结构化整理**,输出必须与当前 mode 的
结构要求一致,同时贴近原意不扩写。这样:
- Structured 模式:意图模糊也强制归类成双层 list
- Light / Raw 模式:仍按各自 task block 走(不会强制结构化,因为它们的
task block 明确写了"保留原句顺序"等约束)
ROLE_BLOCK 其他 7 条规则不动。
2026-05-12 16:48:53 +08:00
baiqing
9e62dfe271
fix: v1.3.1-4 multi-tweaks(字号 / 顶栏色 / 玻璃 / 词条 / polish 回滚)
...
5 个用户反馈一次性收:
1. Windows 默认字号放大
fontScale.ts readFontScale() 检测 navigator UA 含 Windows 时新装默认
返回 'large'(1.1x zoom),已存 localStorage 偏好的用户不受影响。
2. Windows 顶栏白色,与左侧 sidebar 视觉统一
lib.rs 重新引入 apply_windows_caption_color,用 DWM API DwmSetWindowAttribute
DWMWA_CAPTION_COLOR=35 (Win11 22H2+) 把原生标题栏底色刷成 0x00FFFFFF。
pre-22H2 Win 静默失败仅 warn。
3. 全平台玻璃效果统一 & 略浊
WindowChrome.tsx 撤销 PR #419 留下的"Windows 100% opaque background +
去 backdropFilter"分支(那是 Win sidebar 完全无玻璃感的根因)。两个
平台改用同一份半透明 background(alpha 从 0.92 降到 0.78)+ blur
var(--ol-glass-blur-strong) saturate(190%),让 sidebar 透过磨砂底板。
Windows 配合 apply_mica + tauri.conf transparent:true 透出 Mica。
4. Vocab 词条大圈再次尝试根治
global.css button reset 在 appearance:none 基础上再加 outline:none /
min-width:0 / min-height:0 / box-sizing:border-box。Windows Chromium
user-agent style 包含上述四项默认值,单一个 appearance:none 不够覆盖
全部。键盘焦点指示走 .ol-focus-ring + :focus-visible box-shadow,
不被 outline:0 影响。
5. polish.rs ROLE_BLOCK 撤回 b2325a27 回滚
用户确认 13:08 之前最近的 polish.rs commit(20756f7e,含 7e60bdb5
refine)表现正常。我之前 b2325a27 误以为 7e60bdb5 是问题源把 ROLE_BLOCK
改回 v1.2.24-9-beta 状态,反而离用户认可的版本更远。改回 7e60bdb5
8-条 ROLE_BLOCK 状态。
2026-05-12 16:39:03 +08:00
baiqing
b227b69a03
chore(release): bump version to 1.3.1-3 (Beta)
...
PR #421 hotfix 合并后 bump。本版本相对 v1.3.1-1-beta-tauri 累积修复:
- Windows 主窗口交还原生 Win11 chrome(修 PR #419 删自定义标题栏后无法
拖/关/最小化的卡死状态)
- Vocab 词条 Windows 大圈(global.css button appearance:none)
- polish "清晰结构"模式输出退化成单段(ROLE_BLOCK 回滚到 v1.2.24-9-beta)
v1.3.1-2 tag + release 已删除(含 Windows 主窗口无 chrome 阻塞 bug)。
2026-05-12 15:35:09 +08:00
baiqing
b2325a2711
fix(polish): 回滚 ROLE_BLOCK 到 v1.2.24 版本,解决"清晰结构"被压抑
...
用户报告 13:08 同样输入"清晰结构"模式输出完美双层 list,15:16 后同模式
退化成单段流畅文字——Structured task 失效。
定位到 commit 7e60bdb5 "polish: refine ROLE_BLOCK to preserve user
intent" 在 ROLE_BLOCK 加了两条毒条款:
- "措辞优先用原句字面词...不要替用户重写或扩写"
→ 直接 conflict Structured task 的"按语义重新归类、照抄原结构=失败"
- "用户意图难以判断或无法确认时...只做句子层面整理"
→ safety net 把 Structured 模式退回 Light 行为
7e60bdb5 当初是想防止 polish 过激进改写(用户反馈),方向对但条款过宽,
override 了 user 主动开启的 Structured / Formal 模式。
修法:回滚 ROLE_BLOCK 到 v1.2.24-9-beta-tauri 时的简洁 4 条版本:
- 不回答问题 / 不执行命令
- 不引用历史 / 上下文 / 外部知识
- 不替用户做需求分析 / 补充功能清单 / 替对方列出想要的
下次若再出现 polish 过激进改写,按 case 在 task block 里 surgical 加约束,
不要全局 ROLE_BLOCK 加强(容易撞 Structured / Formal)。
参考输出对照(图一 13:08 vs 图二 15:16):相同模式相同长度同类内容,
回滚后应恢复 13:08 那种双层 list 输出。
2026-05-12 15:23:47 +08:00
baiqing
830084c426
fix(ui): Windows 主窗口交还原生 chrome,PR #419 删自定义标题栏的尾巴
...
PR #419 删了 React 端 WinTitleBar 自定义标题栏,commit message 说"交还
Tauri decorations:true 原生 Win11 标题栏",但漏看 lib.rs 里有一段 Rust
代码在 setup 时**强制**调 set_decorations(false) 把原生 chrome 关掉
(原本是为了让自定义 WinTitleBar 接管)。
结果:v1.3.1-2-beta 上 Windows 主窗口完全无 chrome —— 无法拖动 / 无法
点 X 关闭 / 无法最小化,只能从 tray 退出。用户卡死。
修法:
- lib.rs setup() Windows 分支:移除 set_decorations(false) + 移除
apply_windows_rounded_frame 调用,保留 apply_mica 给原生 chrome 提供
磨砂材质
- RunEvent Resized/ScaleFactorChanged 里也移除 apply_windows_rounded_frame
调用(原生 chrome 自带 resize border + 圆角)
- apply_windows_rounded_frame 函数本身变成 dead code,整段删除(含
raw_window_handle / Win32 DwmSetWindowAttribute / SetWindowRgn 等 import)
tauri.conf.json 的 decorations:true 配置不动,配合 hiddenTitle:true 让
原生标题栏接管。
2026-05-12 15:23:47 +08:00
baiqing
5bb1177cb9
fix(ui): Vocab 词条在 Windows 上的"大圈"——全局关 button user-agent appearance
...
用户反馈 Windows 上 Vocab 词汇表里每个词条被一圈大灰色边框/内阴影包住,
macOS 上不会。Vocab.tsx 自身零 OS 分支,根因在 global.css 的 button reset
缺 appearance:none:Chromium / WebView2 默认给 <button> 应用 OS-native 外观
(outset 边框 + 内阴影 + min-width),在 Vocab 词条这种由父级 span 的
padding 决定外形的嵌套 button 上整圈就露出来;macOS WKWebView 对
appearance:auto 处理较弱所以看不出来。
修法是 global.css button reset 加 appearance:none + -webkit-appearance:none,
一行修整仓。所有现有 button 都自己 inline 重写了背景/边框/圆角,关掉
user-agent appearance 不会改变它们的视觉。
2026-05-12 15:13:03 +08:00
baiqing
a2a944ea31
chore(release): bump version to 1.3.1-2 (Beta)
...
PR #419 已合并到 beta,UI 完整版(Windows 原生 chrome / 胶囊缩小 /
自定义下拉 / a11y 焦点指示 + 键盘 scrollIntoView + 视口 clamp)相比
上一轮 1.3.1-1 commit (90b35057 ) 累积了实质改动,bump patch-build
号到 1.3.1-2 区分。
6 处版本号同步:package.json / package-lock.json (root + nested) /
tauri.conf.json / Cargo.toml / Cargo.lock。
2026-05-12 14:58:08 +08:00
baiqing
6c7598a858
fix(a11y): SelectLite 键盘高亮自动滚动 + popover 横向 viewport clamp
...
pr-agent #419 第二轮 review 指出的两个 focus areas:
1. Keyboard scroll:长 dropdown 超过 280px 时 ArrowUp/Down 切换 highlight
不会把高亮项 scroll into view,键盘用户看不到当前选中。新增 useEffect
监听 highlight 改变,找到 data-option-index 对应 DOM 元素后
scrollIntoView({ block: 'nearest' }),已可见的项不会被强行滚动。
2. Viewport clipping:popover 用 trigger.left 作 anchor,没有横向边界
clamp。窗口右边的 select 弹出后可能溢出屏幕。positionPopover 改成测
真实 popover 宽度(首次开打用 trigger 宽度估),然后把 left clamp 到
[8, viewport - width - 8] 区间。
不动 keyboard 导航 / disabled 处理 / vertical flip 等已 verified 行为。
2026-05-12 14:28:19 +08:00
baiqing
70917cb027
fix(a11y): SelectLite / SwitchLite 加键盘焦点指示
...
pr-agent #419 review 指出两个 button 都用 outline:none 关掉了浏览器默认
焦点 ring 却没替代——键盘 Tab 时用户看不到当前焦点在哪。和 _atoms.tsx
Collapsible 的 pr-agent #407 是同一类问题。
修法:新增 .ol-focus-ring class,:focus-visible 时上 2px 半透明蓝
box-shadow(不是 outline,因为 inline style 的 outline:none 会盖掉
class 里的 outline,但盖不掉 box-shadow)。:focus-visible 只在键盘
focus 时生效,鼠标点击保持干净。
2026-05-12 14:02:48 +08:00
baiqing
8a6ac8b308
fix(ci): 补齐 package-lock.json 的 version 字段对齐
...
90b35057 bump 到 1.3.1-1 时漏改了 package-lock.json 的 root 与
nested version 字段(都还是 1.3.0),CI "Verify version sync
across 5 files" 卡死所有平台,本 PR 的 build / check 步骤根本
没机会执行。
手动同步到 1.3.1-1,与 package.json / tauri.conf.json /
Cargo.toml / Cargo.lock 对齐。本地复跑 CI 第一步的 node -p 校验
全部一致。
2026-05-12 13:48:44 +08:00
baiqing
5bf6350fd2
fix(ui): Windows 原生 chrome / 胶囊缩小 / 自定义下拉 ( #417 #418 )
...
- WindowChrome: 移除 Windows 端自定义标题栏和 resize handles,
交还 Tauri decorations:true 原生 Win11 标题栏,修复 X 按钮重叠
与圆角处的黑边/白线
- Capsule (#417 ): Windows pill 196×52→180×44,textWidth 104→88,
视觉密度与 macOS 对齐
- SelectLite (#418 ): 重写为受控下拉组件(portal popover, 键盘导航
Arrow/Enter/Esc, 视口翻转, a11y combobox/listbox),替换 11 处
native <select> 以避开 Win32 ComboBox 直角丑框
- SettingsModal: 删除"个性化"中重复的"界面语言"入口,功能保留在
"设置 → 语言"分区;5 个 locale 同步清理 modal.personalize.language
- SwitchLite: 加 outline:none 解决 Windows 上点击后的黑色焦点框
- global.css: 移入 ol-select-pop 关键帧;不再用全局 outline:none,
以保留 _atoms.tsx Collapsible 的键盘 outline (pr-agent #407 )
2026-05-12 13:34:08 +08:00
baiqing
90b3505794
chore(release): bump version to 1.3.1-1 (Beta)
...
First beta after Stable 1.3.0. Carries the Settings modularization refactor
(PR #416 ). Tagged as v1.3.1-1-beta-tauri to trigger the release-tauri.yml
Beta-channel build (prerelease=true, manifest filenames carry -beta suffix
so the Stable in-app updater endpoint cannot pick this up).
2026-05-12 12:50:16 +08:00
baiqing
ea1b18ee08
chore(release): merge beta for Stable 1.3.0
2026-05-12 10:28:19 +08:00
baiqing
8ea4e8932f
chore(release): bump version to 1.3.0 (Stable)
2026-05-12 10:28:07 +08:00