Commit Graph
75 Commits
Author SHA1 Message Date
TRIPandbaiqing 859fd5370f feat(updater): Beta 渠道接通 auto-update(Builder.endpoints runtime 切换) (#465)
* feat(updater): Beta 渠道接通 auto-update(Builder.endpoints runtime 切换)

CLAUDE.md 之前的论断「tauri-plugin-updater 2.10 Builder 不暴露 endpoints()」在
2.10.1 已不成立 —— Builder 现在有 .endpoints(Vec<Url>) -> Result<Self>,build()
里 self.endpoints.unwrap_or_else(|| self.config.endpoints.clone()) 走 runtime 覆盖。

实现 channel-aware 自动更新(不 fork plugin、不写自定义下载/签名校验):

Rust(~100 行新增)
- commands.rs::app_check_update_with_channel:
  Stable → webview.updater_builder().build()?.check()(默认 endpoints 从 tauri.conf)
  Beta   → fetch_latest_beta_release() → 拼镜像 + 直连两份 -beta manifest URL
         → builder.endpoints(urls)?.build()?.check()
- AppUpdateMetadata 字段形状对齐 plugin 的 UpdateMetadata(rid + currentVersion
  + version + body + rawJson),前端 new Update(metadata) 即可复用 plugin 的
  download / install / close。
- lib.rs 注册新 command。

前端(~30 行改动)
- AutoUpdate.tsx::checkForUpdates 从 import('@tauri-apps/plugin-updater').check
  改为 invoke('app_check_update_with_channel');其余 download / install / close
  全走 plugin 原生 JS API(new Update(metadata) 后链式调用)。
- SettingsModal::BetaChannelControl 删掉「打开 GitHub 下载」按钮 ——
  auto-update 接管了,手动下载路径冗余;保留「最新 Beta 版本号 + 刷新」做信息透明。
- i18n 5 个 locale 改 betaChannelDesc 文案,把「需要手动下载安装」改成
  「自动接收最新 Beta 版本」。betaChannelDownloadBtn 等 i18n key 暂留(无用但无害)。

物理隔离仍生效:Beta tag 的 manifest 文件名带 -beta 后缀,跟 Stable 的
latest-{tgt}-{arch}.json 在 GitHub Release assets 里是分开两份;即使代码逻辑
错把 Beta URL 给 Stable 用户也是 HTTP 404,不会拿到错档。

验证:cargo test --lib serial 270 / 0 / 0;tsc clean;vite build clean。

* feat(settings): BetaChannelControl 加版本比对 + 「立即更新」按钮

之前 BetaChannelControl 在 toggle 打开后,只机械显示「最新 Beta: vX-beta-tauri」,
不管本机版本是不是已经等于那个 tag。用户报告:「显示有最新 Beta,但应该比对版本号」。

修复:
- parseVersionFromBetaTag("v1.3.4-1-beta-tauri") → "1.3.4-1"
- semverGreater(remote, local) 做 SemVer 风格比对(支持 X.Y.Z 和 X.Y.Z-N,覆盖
  本仓库实际版本格式;prerelease 按 SemVer 规则 lower than no-prerelease)
- 本机 >= 最新 → 「最新 Beta: vX」 + 蓝色「已是最新」chip
- 本机 < 最新 → 「最新 Beta: vX」 + 「立即更新」按钮(蓝色高亮)
- 「立即更新」点击 → useAutoUpdate.checkForUpdates → 走和全局「检查更新」按钮
  完全相同的 download/install 流程,UpdateDialog 直接挂在 BetaChannelControl 内部
- 用户的第二个 feature 诉求:「在 Beta 渠道旁边一键检查 + 自动更新」 = 这个按钮

i18n 5 个 locale 加 4 个 key:betaChannelUpToDate / betaChannelUpdateNow /
betaChannelUpdateNowTitle / betaChannelChecking。

* chore(release): bump 1.3.4-1 → 1.3.4-2 for Beta channel

`-2` 后缀让 appVersion.ts 的 IS_BETA_BUILD 仍判为 Beta,UI BETA 标签照常显示。
配本 PR 的 Beta auto-update + BetaChannelControl「立即更新」按钮,1.3.4-1 用户
切到 Beta 渠道后点检查会发现 1.3.4-2 并走 auto-update 流程一键升上来。

发布 tag:v1.3.4-2-beta-tauri。

---------

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-17 11:15:06 +08:00
TRIPandbaiqing 0ecb3bd5a4 chore: bump 1.3.4-1 + sidebar 底部行折成单行 (#462)
* feat(shell): sidebar 底部行折成单行(设置 + 版本)

把 sidebar 底部「⚙ 设置」和「版本 v1.3.x」从上下两行折成一行:
- 设置按钮 display 由 flex 改成 inline-flex,去掉 label 的 flex:1
  (不再撑满 sidebar 宽度)
- 版本 chip(含 BETA 标)用 marginLeft: auto 推到行尾

外观更紧凑、纵向更省、视觉重心从两行散开收到一行。

* chore(release): bump version 1.3.3 → 1.3.4-1 for Beta channel

`-1` 后缀让 appVersion.ts 的 IS_BETA_BUILD 自动判为 Beta,UI 上的
BETA 标签会自动恢复显示。bump-version.sh 不收带 dash 的 prerelease
格式,所以这次手动同步 5 个文件(package.json / package-lock.json
root + nested / tauri.conf.json / Cargo.toml / Cargo.lock)。

发布 tag 仍走 v<v>-beta-tauri:v1.3.4-1-beta-tauri。

---------

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-17 10:18:21 +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 efa94afc27 chore(release): bump version to 1.3.2-3 (Beta) 2026-05-15 12:35:02 +08:00
baiqing 5695d8c467 chore(release): bump version to 1.3.2-2 (Beta) 2026-05-15 08:42:08 +08:00
baiqing e0a48ce801 chore(release): bump version to 1.3.2-1 (Beta) 2026-05-14 15:00:15 +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 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 b4aa4972dd chore(release): v1.3.1-18 — Wayland CLI 触发修复 #420 2026-05-13 12:47:03 +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 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 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 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 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 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 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 8ea4e8932f chore(release): bump version to 1.3.0 (Stable) 2026-05-12 10:28:07 +08:00
baiqing e90fe9f7b1 chore(release): correct beta version to 1.3.0-1 (MSI requires numeric pre-release)
上一条 1.3.0-BETA 在 Windows MSI 打包阶段被 Tauri 拒绝:MSI ProductVersion
只接受 \"MAJOR.MINOR.BUILD\" + 数字 pre-release(≤ 65535)。BETA 字面被
canonicalize 时报错 \"optional pre-release identifier in app version must be
numeric-only\"。

按仓库历史 (1.2.24-7/8/9) 同体例改为 1.3.0-1,表示 1.3.0 的第 1 个 Beta。
2026-05-12 09:56:20 +08:00
baiqing 7136cf55cc chore(release): bump version to 1.3.0-BETA 2026-05-12 02:04:32 +08:00
H-Chris233 8fbb965635 Let users control LLM thinking at the provider channel
Issue #402 needs a Settings toggle that applies to every LLM runtime path without changing prompt behavior. The implementation keeps the preference in user settings, threads it through polish, translate, QA, and validation, and sends only provider-channel request fields documented by each backend instead of prompt instructions or model-name heuristics.

Constraint: Thinking controls are provider-specific request fields, not a portable prompt convention

Rejected: Prompt-level thinking instructions | changes model-facing prompts and cannot guarantee provider thinking mode

Rejected: Per-model allow/deny lists | user requested channel-level behavior and provider-side handling for unsupported models

Confidence: medium

Scope-risk: moderate

Directive: Do not add prompt injection or model-name thinking adapters for #402 without a new explicit product decision

Tested: cargo test --manifest-path openless-all/app/src-tauri/Cargo.toml --lib openai_chat_body -- --nocapture

Tested: cd openless-all/app && cargo test --manifest-path src-tauri/Cargo.toml --lib disabled_thinking_config -- --nocapture

Tested: cd openless-all/app && cargo test --manifest-path src-tauri/Cargo.toml --lib build_generate_body -- --nocapture

Tested: cd openless-all/app && cargo check --manifest-path src-tauri/Cargo.toml

Tested: cd openless-all/app && npm run build

Tested: git diff --check

Related: #402
2026-05-11 11:20:35 +08:00
baiqing 568d30d079 chore: bump version to 1.2.24-7 (Beta-7)
10 PRs landed on beta this cycle:
- #377 paste shortcut configurable (issue #360)
- #386 TS UserPreferences updateChannel alignment
- #387 focus_target leak on Processing-phase cancel
- #388 [严重] MacHotkeyAdapter::shutdown stops CFRunLoop + tap
- #389 emit_capsule window.show/hide off audio thread
- #390 QA / dictation hotkey routing race
- #391 audio-mute spawn_blocking (async hygiene)
- #392 hotkey supervisor + global dispatcher exit signal
- #393 post-audit logic-review hotfixes (QA mute .await + focus_target Processing branch)
- #394 in-process credentials cache (kills repeated Keychain prompts)

Bump 4 files: package.json, tauri.conf.json, Cargo.toml, Cargo.lock.
2026-05-10 10:34:08 +08:00
baiqing 7b39fd57aa chore: bump version to 1.2.24-6 (Beta-6)
Beta-6 包含的合并:
- #379 fix(recorder): watchdog 在 sleep 醒来后重检 stop_flag,消除停采误报
- #380 fix(commands): wrap tray refresh in run_on_main_thread 修主线程死锁
- #381 feat(ui): consolidate footer/nav, sliding indicator, hover cues, top-right saved toast
- #378 拆分 coordinator 子状态机模块(间接合入)

Tag: v1.2.24-6-beta-tauri 推到 main 后触发 release-tauri.yml Beta 流水线。
2026-05-09 16:31:32 +08:00
TRIPandbaiqing b44cb998af fix(installer): unregister TSF IME before replacing OpenLessIme.dll on upgrade (#321) (#369)
Auto-update was failing on Windows because OpenLessIme.dll is a TSF input-method
DLL: once registered, Windows maps it into every text-input client process
(browsers, IDEs, chat apps...). The installer's PREINSTALL hook tried to
overwrite the file directly while it was still mapped, hitting a sharing
violation and aborting the update.

NSIS hook (openless-ime-hooks.nsh):
- PREINSTALL now calls OPENLESS_IME_UNREGISTER_X86/X64 first to release the
  COM/TSF registration. On a fresh install this is a harmless no-op (existing
  unregister macros log the exit code without aborting).
- DLL bytes are written to OpenLessIme.dll.new and atomically renamed into
  place. If the old DLL is still locked by a TSF client process, Delete fails
  and we fall back to Rename /REBOOTOK + SetRebootFlag — Windows queues the
  replacement via PendingFileRenameOperations and the new bytes activate after
  the next reboot. Same TSF registration path is preserved, so re-registration
  in POSTINSTALL stays valid across the reboot.

WiX (openless-ime.wxs):
- UnregisterOpenLessImeX86/X64 now also fire Before InstallFiles when a
  previous version is installed (Installed AND NOT REMOVE). Original condition
  (REMOVE="ALL", Before RemoveFiles) only covered the dedicated uninstall
  sequence; auto-update / minor-upgrade skipped it entirely and ran straight
  into the same sharing violation as NSIS.

Bumps to 1.2.24-5 (Beta-5).

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-08 19:58:05 +08:00
TRIPandbaiqing 29d3a79eb6 chore: bump version to 1.2.24-4 (Beta-4) (#358)
Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-08 11:57:36 +08:00
millionart aa5add1188 [codex] fix Foundry Windows App Runtime prompt (#340) 2026-05-08 11:42:07 +08:00
TRIPandbaiqing 10440c7f72 chore: bump version to 1.2.24-3 (Beta-3) (#349)
Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-08 09:47:30 +08:00
TRIPandbaiqing 2a99d6bf6e chore: bump version to 1.2.24-2 (Beta-2) (#345)
Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-08 09:08:23 +08:00
TRIPandbaiqing 4962a661a3 chore: bump version to 1.2.24-1 (#337)
将 Beta 版本号从 1.2.24-beta.1 改为 1.2.24-1。

原因:Tauri MSI bundler 对 prerelease 段的限制比 npm/Cargo semver 严格,
要求 prerelease identifier 必须是「numeric-only and ≤ 65535」。
1.2.24-beta.1(含字母 + 多段)会让 windows MSI 构建直接报:
  failed to bundle project: optional pre-release identifier in app version
  must be numeric-only and cannot be greater than 65535 for msi target

实测后果:上次 v1.2.24-beta.1-beta-tauri tag 触发的 CI run 25501471895,
macOS arm64 / macOS x64 / Linux 都成功,只有 Windows MSI 卡在 candle 之前。

修复:
- 1.2.24-1 是合法的 npm/Cargo semver prerelease 写法( id="1" 纯数字)
- Tauri MSI 接受这种格式
- semver 排序仍然 1.2.23 < 1.2.24-1 < 1.2.24,符合渠道隔离要求
- 后续 Beta 迭代版本号: 1.2.24-2 / 1.2.24-3 / ...
- Beta 身份不靠版本字面,靠 tag 后缀 `-beta-tauri`(release-tauri.yml 检测)

5 处版本号同步:package.json、package-lock.json (root + nested)、
tauri.conf.json、Cargo.toml、Cargo.lock。CI 用的同一段 verify 通过。

合入后由维护者删旧 tag/release(已删)+ 推 v1.2.24-1-beta-tauri 触发新 CI。

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-07 22:40:18 +08:00
TRIPandbaiqing f4442e52d9 chore: bump version to 1.2.24-beta.1 (#334)
Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-07 22:04:50 +08:00
baiqing 5491ef5d33 chore(release): 1.2.23
Hotfix for 1.2.22:
- fix(recorder): macOS 麦克风停录后未释放(cpal Stream::drop 不调
  AudioOutputUnitStop,显式 pause 强制停 callback)
- fix(coord): 录音条等真实开始捕获 PCM 后再弹出,避免短录音漏首字
- fix(localasr): macOS 不再渲染 Windows 专属的 Foundry Local Whisper 卡片
- fix(hotkey): macOS 上 Alt/Meta 键标签显示 Option/Cmd 而非 Alt/Win
2026-05-07 16:57:18 +08:00
baiqing 01aa439686 chore(release): 1.2.22 2026-05-07 13:08:00 +08:00
millionart f358260866 merge upstream main into windows local asr 2026-05-06 21:28:41 +08:00
baiqing d5fa5b7df3 chore(release): 1.2.21
主要修复
─────────
- fix(windows): TSF DLL 静态链接 CRT,防 host 进程(QQ 等)私有
  MSVCP140 劫持导致切微软拼音崩溃 0xc0000005(PR #287 + #289 + Codex
  P1 review)。
- fix(windows): 移除 DisableThreadLibraryCalls — /MT 下 CRT 需要
  thread attach/detach 通知做 per-thread TLS 清理,禁用反而触发崩溃。
- fix(recording): 录音条出现时 mic 已 capture,按 Option 不再吞开头
  字。emit Recording 加 race 检查避免短按时覆盖 stop/cancel UI 信号。
- fix(startup): splash 透明背景 + 卡片化,避免长启动时左半白屏。
- fix(vault): keyring chunks 用稳定 account name —— macOS Keychain
  Always-Allow 不再因 UUID 轮换失效;不再每次 load 都尝试删 9 个
  legacy entries 触发 ACL 弹窗(与 PR #277 一起)。

新功能
─────────
- feat(security): 凭据从 plaintext JSON 迁移到平台 credential vault
  (macOS Keychain / Windows Credential Manager / Linux libsecret)。
  Windows 2560 byte 限制下用 chunked storage;partial-write safe。
  legacy 多源迁移完成后自动清理(PR #277)。

工程
─────────
- chore(ci): 暂时搁置 macos-13(Intel mac)matrix —— GH Actions
  runner pool 紧张到每次 dispatch queue 1-2h(已观测 4 次)。Apple
  Silicon 用户 dmg 仍发;Intel mac 用户保留 v1.2.20 dmg + Rosetta
  说明(issue #299)。
- chore(devex): CI 加 macOS 矩阵 + 5-way 版本号一致性校验 +
  scripts/bump-version.sh 一行同步 5 处版本号。.gitignore 加
  promo-openless-v2 / node_modules / dist / target 全局兜底(PR #294)。
- docs: docs/audit-2026-05-06.md 工程审计基线,覆盖架构 / UI bug /
  多端一致性 / IPC 1:1 校验 / P0/P1/P2 改进路径。
- chore: 9 个改进 issue (#295-#303) 跟踪 audit 列出的所有 P1/P2/P3
  问题。
2026-05-06 21:24:51 +08:00
millionart 4fa34b486e merge upstream main into windows local asr 2026-05-06 20:55:25 +08:00
millionart 2a03f15292 Merge remote-tracking branch 'upstream/main' into codex/windows-local-asr
# Conflicts:
#	openless-all/app/src-tauri/Cargo.lock
#	openless-all/app/src-tauri/src/commands.rs
#	openless-all/app/src-tauri/src/coordinator.rs
#	openless-all/app/src-tauri/src/lib.rs
2026-05-06 20:15:12 +08:00
millionart 89e48ba3b8 feat(asr): add Foundry local runtime wrapper 2026-05-06 15:43:22 +08:00
H-Chris233 579efb0546 Keep Linux vault credentials persistent
Linux credential storage must survive reboot after the legacy plaintext file is removed. The keyring linux-native feature uses kernel keyutils, so the Linux build now enables the persistent Secret Service-backed combo and the migration read fallback also considers older per-account vault entries when a current manifest is unreadable.

Constraint: credentials.json must be removed after successful vault migration.\nConstraint: keyring linux-native/keyutils is an in-memory cache across reboot.\nRejected: Keep plaintext JSON as Linux fallback | violates the vault storage boundary.\nConfidence: high\nScope-risk: moderate\nDirective: Linux credential storage must remain persistent if legacy plaintext cleanup is enforced.\nTested: cargo check --manifest-path src-tauri/Cargo.toml\nTested: cargo test --manifest-path src-tauri/Cargo.toml credential_payload_chunks_stay_under_windows_blob_limit\nTested: npm run -s build\nTested: git diff --check\nNot-tested: Manual Secret Service read/write on a desktop Linux keyring session.\nRelated: #230
2026-05-06 14:40:49 +08:00
H-Chris233 13ccf85a48 Store credentials in the system vault
Provider credentials should follow the platform credential-store threat model instead of continuing normal plaintext JSON writes. The vault now stores the existing multi-provider credentials payload in the OS credential store, migrates the legacy JSON file only when the vault has no entry, removes the legacy file after a successful write, and keeps raw credential IPC restricted to the main settings window.

Constraint: User explicitly chose Keychain/Credential Manager/Linux keyring for issue #230.

Constraint: Preserve the existing provider schema and active-provider routing with minimal frontend churn.

Rejected: Keep plaintext JSON as the documented product choice | user rejected this direction.

Rejected: Split every credential field into separate vault entries | larger migration surface and risks losing active provider state.

Confidence: medium

Scope-risk: moderate

Directive: Security-model and storage-strategy choices must be confirmed with the user before implementation.

Tested: cargo check --manifest-path src-tauri/Cargo.toml; npm run -s build; git diff --check; grep for stale plaintext/Keychain fallback wording.

Not-tested: Manual migration on macOS Keychain, Windows Credential Manager, or Linux desktop keyring.

Related: https://github.com/appergb/openless/issues/230
2026-05-06 14:39:40 +08:00
baiqing 2bd77fe87e fix(tauri): 释放 Rust crate ~2.11 — npm 端已发 2.11,旧 ~2.10 锁反向 fail
Release run 25419948896 三平台 (Linux / Win / mac arm64) 都挂在
tauri build 启动检查:

    Found version mismatched Tauri packages.
    tauri (v2.10.3) : @tauri-apps/api (v2.11.0)

根因翻转:
- 之前 (PR #281) Rust crate 漂上 2.11 而 npm 没发,所以锁 ~2.10 把 Rust
  拉下来。
- 这次 PR #286 加 @tauri-apps/plugin-dialog 时 npm 解析把
  @tauri-apps/api 升到 2.11.0(plugin-dialog 依赖 ^2.11.0),
  Rust 还锁 ~2.10 → 反向 mismatch。

修复:
- Cargo.toml 锁 ~2.11
- cargo update 让 tauri / tauri-runtime / tauri-runtime-wry 三件套都升到
  2.11.0(连带 wry 0.54.4 → 0.55.1 等 transitive 依赖)。

后续如果 Tauri 团队再发 2.12 而 npm 滞后,回头看 PR #281 同款做法处理。
2026-05-06 14:33:01 +08:00
baiqing 26ce2ff0b5 chore(release): 1.2.20
主要修复
─────────
- fix(windows): NSIS 安装包注册 OpenLess TSF DLL(含 32-bit COM 注册到
  Wow6432Node + Sysnative 绕过 32-bit installer 的 WOW64 重定向);
  改 perMachine 安装让 regsvr32 能写 HKLM。修「Windows 输入法后端:不可用」
  自 1.2.15 起的长期 bug。
- fix(local-asr): 切走/删模型/手动释放时引擎真正归还 1+ GB RAM;下载稳定性
  4 次指数退避 + Range 分块 + 取消正确传播;点击下载即崩(tokio::spawn →
  tauri::async_runtime)。
- fix(tauri): Rust crate tauri 锁 ~2.10,避开 npm 端 @tauri-apps/api
  尚未发布 2.11 导致的跨 minor 版本检查 fail。
- fix(capsule): AudioBars 用 cubic-bezier 缓动 + 0.18s transition,圆点→
  长条形变在 60Hz audio level 高频更新下平滑混合,不再阶梯式跳变。
- fix(recorder): liveness watchdog + 全局超时;watchdog 从首次回调开始计时
  避免慢启动误报(issue #238)。
- fix(windows): hotkey trigger leak、capsule 视觉异常、音量计稳定(多 PR)。
- fix(credentials): 凭据状态按 active provider 判断。

新功能
─────────
- feat(asr): 本地 Qwen3-ASR-Flash 全链路 — 模型注册表、HF/HF-Mirror 4 并发
  分块下载、Settings → 模型设置页、Coordinator 第三分支接入。
- feat(i18n): 日本語 / 한국어 完整翻译(217 string × 2 语种)+ 5 locale
  在语言名后加 Beta 标识。
- feat(translation): 输出语言扩展为日 / 韩,与翻译链路解耦。
- feat(recording): 录音时静音系统输出,多会话共享 mute guard。
- feat(i18n): 繁體中文 UI 完整 + 简繁脚本随 UI 切换同步。
- feat(settings): 合并设置内外两个「关于」(QQ 群 / 反馈 / 源码 / 隐私
  全部并入弹窗的关于)+ 一键导出错误日志(plugin-dialog 选保存位置,
  跨 macOS / Windows)。

工程
─────────
- chore(ci): release-tauri.yml + ci.yml checkout 拉 submodule,修 mac 端
  qwen-asr build 缺源文件。
- chore(release-prep): 清理 #268/#279 双 NSIS 方案残留。
- chore(deps): 引入 tauri-plugin-dialog ~2 给前端 save dialog 用。
2026-05-06 14:25:29 +08:00
baiqing 8397b9d1a5 feat(settings): 合并设置内外两个"关于" + 一键导出错误日志
用户反馈:
1. 设置侧栏内有"关于" tab,弹窗里也有一个"关于",重复入口让人混乱
2. 需要"一键导出错误日志"功能,让用户选择保存位置,跨 macOS/Windows

## 设置"关于"合并 (T2)
- Settings.tsx 删 'about' 从 SettingsSectionId / SECTION_ORDER / 渲染分支 + 整个 AboutSection 函数(保留 settings.about i18n 块以防其他引用)
- SettingsModal.tsx 的 AboutMini 接管所有内容:
  - 新增 source GitHub 链接(迁自 AboutSection)
  - 新增 QQ 群行(含 1078960553 群号 + 复制按钮,逻辑迁自 AboutSection)
  - 保留原有 docs / feedback / privacy / localFirst pill / AboutUpdateControl

## 一键导出错误日志 (T3)
- Cargo.toml + package.json 引入 tauri-plugin-dialog(拿原生 save dialog)
- lib.rs:plugin init + log_dir_path 改 pub fn 让 commands.rs 能调
- commands.rs:新增 export_error_log(target_path) — std::fs::copy
  log_dir_path()/openless.log → target_path(mac:
  ~/Library/Logs/OpenLess/openless.log,windows:
  %LOCALAPPDATA%\OpenLess\Logs\openless.log)
- ipc.ts:exportErrorLog wrapper —— save dialog 选路径 → invoke 后端复制
- AboutMini 新增"导出错误日志"行:busy / ok / err 状态 + 实际保存路径 tooltip

## 5 个 locale 同步
modal.about 块统一新增 10 个 key(保证 typeof zhCN 类型完整不破坏编译):
- source / qq / qqDesc / copyQq
- exportErrorLog / exportErrorLogDesc / exportErrorLogBtn
- exporting / exportSuccess / exportFailed

zh-CN / zh-TW / en 用产品惯用术语;ja / ko 沿用 Beta 翻译风格。

## 验证
- npx tsc --noEmit 通过(5 locale 类型一致)
- vite build 通过
- cargo check 通过(plugin-dialog 与锁定的 tauri ~2.10 兼容)
2026-05-06 14:16:42 +08:00
baiqing e090eb2a3b fix(tauri): 锁 Rust crate ~2.10 — 修 npm/Rust 跨 minor 版本检查 fail
CI release-tauri.yml 三平台 (mac arm64 / Windows / Linux) Build step 在
~10 秒内全部失败:

    Found version mismatched Tauri packages.
    tauri (v2.11.0) : @tauri-apps/api (v2.10.1)

根因:
- Cargo.toml 写 \`tauri = { version = "2" }\`,cargo 解析到 latest 2.x = 2.11.0
- npm \`@tauri-apps/api\` / \`@tauri-apps/cli\` latest 仍是 2.10.1(Tauri 团队
  把 Rust crate 发到了 crates.io 2.11,但 npm 包还没同步发 2.11)
- tauri build 启动时校验 npm 与 Rust crate 必须 major+minor 一致,跨 minor
  直接 fail——三平台都没机会跑到 bundle 阶段。

修复:
- Cargo.toml 把 \`tauri\` 锁成 \`~2.10\`,让 cargo 选 2.10.x patch 版本,
  与 npm 端 2.10.1 对齐。
- cargo update 精确下调到 tauri 2.10.3 / tauri-runtime 2.10.1 /
  tauri-runtime-wry 2.10.1(连带 wry 0.55.1→0.54.4 / tray-icon 0.23.1→0.21.3
  等 transitive 依赖一并回退,让 lock 内部一致——这也是 Cargo.lock diff 大
  的原因,所有改动都是 \`cargo update\` 自动算出来的,没有手改)。

等 Tauri 团队把 npm @tauri-apps/api 2.11 发布后,再放开 Cargo.toml 的
约束。期间 package-lock.json 保持 2.10.1,CI 走 \`npm ci\` 不会自动漂。
2026-05-06 11:55:39 +08:00
H-Chris233andOmX 1075ba463f Keep Chinese output script aligned with the selected UI locale
This change binds locale selection to a persisted chineseScriptPreference so zh-CN and zh-TW drive output script consistently.

It injects script preference into LLM context for polish/translate/QA, removes ASR language-hint submission, and applies script conversion only in pure-ASR fallback paths. It also hardens preference persistence sequencing in HotkeySettingsContext to reduce write-order races.

Constraint: Must keep output script behavior coupled to locale choice without adding a new toggle
Constraint: ASR requests should not send language parameters
Rejected: Add an independent output-script option | Conflicts with required locale-driven behavior
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Keep zh-CN=>simplified and zh-TW=>traditional mapping consistent in both Settings entry points and backend consumers
Tested: npm run -s build (openless-all/app)
Tested: cargo test -q (openless-all/app/src-tauri)
Not-tested: Live external provider E2E verification across multiple real ASR/LLM vendors
Related: #242
Co-authored-by: OmX <omx@oh-my-codex.dev>
2026-05-05 16:06:29 +08:00
baiqing 5a58f74c4a fix(local-asr): HF 下载 TLS unexpected_eof + Settings 引导改下载入口
下载层修两件事:
1. 改用 native-tls (macOS = SecureTransport) 而非 rustls:
   HF LFS CDN 经常不发 TLS close_notify 直接关 TCP,rustls 0.22+ 把这当
   致命 unexpected_eof,实测多个 .safetensors 失败。SecureTransport 容错。
   Volcengine WebSocket 不动,继续走 rustls。
2. 单文件失败自动 retry 1 次(带 1s 退避,且尊重 cancel)。
   HF 大文件偶发瞬断很常见,不让用户手点重试。

Settings 引导(按用户反馈):
- ASR 选 'local-qwen3' 时**不**渲染 API key / Base URL / Model 三个填空
- 改为 LocalAsrProviderHint 卡片:
  * 文案"本地 Qwen3-ASR 在本机运行,无需 API Key"
  * 已下载/未下载 Pill 显示当前激活模型状态
  * 一键按钮 → 派发 NAVIGATE_LOCAL_ASR_EVENT
- FloatingShell 监听同事件,关 Settings modal + 切到 'localAsr' tab
- i18n 同步 zh + en
2026-05-05 09:56:54 +08:00
baiqing bd3bac3ca6 feat(local-asr): 接入 antirez/qwen-asr 编译链路 — 阶段 1 脚手架
- vendor antirez/qwen-asr 作为 git submodule (commit b00b789)
- build.rs 用 cc 编 10 个 C 源 + 链 Accelerate (仅 macOS)
- src/asr/local/{mod,qwen_ffi,qwen_engine}.rs 包装最小 FFI 面:
  load / transcribe_audio / transcribe_stream + token 回调蹦床
- libqwen_asr.a (~434KB) 已链通,nm 验证 qwen_* 符号齐全
- Windows 端不编入,路径见 issue #256

下一阶段:模型下载管理 + IPC commands + 新页 LocalAsr.tsx + coordinator 路由
2026-05-05 09:17:32 +08:00
baiqing 149a6b8eca chore(release): 1.2.19 — Windows updater 修 NSIS+MSI 拆两轮跑 2026-05-04 23:12:55 +08:00
baiqing 429780b5e4 chore(release): 1.2.18 — Windows bundle 顺序锁 nsis,msi 让 updater 资产先落盘
历史链:
  1.2.13 ✓  无 IME wxs,MSI+NSIS 全过
  1.2.15 ✗  加 IME wxs;CI pwsh 把 JSON 引号吃掉,tauri 连 candle 都没跑
  1.2.16 ✗  shell 切 bash 后到 light 阶段,但 ICE80 触发,Repair 没 -sice
  1.2.17 ✗  Repair 加了 -sice:ICE80 修了 MSI;但 Tauri 字母序 msi→nsis 让
            MSI 先挂掉,NSIS 永远没机会跑,updater .exe(.sig) 缺失
  1.2.18    显式 --bundles nsis,msi:NSIS 先写盘产 updater 资产,MSI 再失败
            由 Repair 兜底 light.exe 重链

唯一改动:Build (Windows) 步骤两个分支都加 --bundles nsis,msi。
预留:NSIS 不读 wix.fragmentPaths,所以 .exe 暂不带 IME DLL;MSI 仍带,
后续单独 issue 跟进 NSIS IME 集成,不挂当前发版。
2026-05-04 22:56:33 +08:00