Commit Graph
205 Commits
Author SHA1 Message Date
Cooper-X-Oak 27dbeadcfd fix: make capsule click-through outside recording 2026-05-02 00:54:37 +08:00
Chris233 08e48cc852 Merge pull request #135 from H-Chris233/main
fix(polish): 调整热词注入提示措辞
2026-05-01 23:46:33 +08:00
H-Chris233 e8ba67a45f Only cache capsule geometry after a successful relayout
The capsule geometry cache must reflect only applied layout, otherwise a transient resize or position failure would permanently suppress future retries for the same monitor and translation state. The cache is now written only after the relayout call succeeds, so a failed attempt can be retried on later emits.

Constraint: Keep the fix local to the capsule relayout path.
Rejected: Cache before calling relayout | can strand the capsule on stale geometry after a transient failure.
Confidence: high
Scope-risk: narrow
Directive: Never treat capsule geometry as applied until the window manager has accepted the resize/reposition.
Tested: cargo test --manifest-path src-tauri/Cargo.toml --lib -- --nocapture
Not-tested: Live retry behavior under actual window-manager failures.
2026-05-01 23:38:24 +08:00
H-Chris233 1dfcf7f302 Avoid relayouting capsule on every audio tick
The capsule window now tracks its last applied geometry and only resizes/repositions when the monitor or translation state actually changes. That keeps steady-state level updates from churning the native window manager while preserving the current placement behavior when geometry really does change.

Constraint: Keep the fix minimal and avoid introducing a broader window-management abstraction.
Rejected: Leave the unconditional relayout in place | it adds avoidable compositor churn during recording.
Confidence: high
Scope-risk: narrow
Directive: Any future capsule geometry change should update the cached geometry key, not reintroduce unconditional relayout.
Tested: cargo test --manifest-path src-tauri/Cargo.toml --lib -- --nocapture
Not-tested: Live compositor/jitter behavior on Windows/macOS/Linux.
2026-05-01 23:33:08 +08:00
H-Chris233 320c97485c Reuse capsule height for QA anchoring
QA positioning had kept its own fixed capsule height constant after the capsule window was resized to match the visible pill. Reusing the shared capsule height source keeps the documented gap intact without widening the change surface.

Constraint: Keep the change minimal and avoid a separate geometry model for QA.
Rejected: Keep the old QA constant | would drift from the new capsule geometry again.
Confidence: high
Scope-risk: narrow
Directive: If capsule geometry changes again, update QA anchoring from the shared capsule source instead of introducing another fixed constant.
Tested: cargo test --manifest-path src-tauri/Cargo.toml --lib -- --nocapture
Not-tested: Live QA window placement on each platform.
2026-05-01 22:58:23 +08:00
H-Chris233 f62762a17f Keep capsule hitbox aligned with visible UI
The capsule window used a fixed oversized frame even when only the pill was visible, so transparent padding could block clicks on underlying apps. The runtime now resizes and repositions the capsule to the actual visible content, expanding only when the translation badge is shown.

Constraint: Keep the fix minimal and preserve the translation badge when it is actually visible.
Rejected: Add click-through behavior to transparent pixels | too risky and platform-specific for this narrow fix.
Confidence: high
Scope-risk: moderate
Directive: Keep capsule window geometry in sync with rendered content; do not reintroduce a larger transparent hitbox without a matching click-through strategy.
Tested: cargo test --manifest-path src-tauri/Cargo.toml --lib -- --nocapture; npm ci; npm run build; git diff --check
Not-tested: Live mouse hit-testing on Windows/macOS/Linux after the resize change.
2026-05-01 22:38:15 +08:00
H-Chris233 6c74bfa7ec Make hotword prompt wording more directive
The hotword injection copy now tells the model to prefer the user's spelling proactively while still avoiding unrelated mechanical replacements. That keeps the intent of issue #63 aligned with the existing prompt structure and only changes the wording that users see indirectly through polish behavior.

Constraint: Keep the change minimal and avoid changing the surrounding prompt architecture.
Rejected: Broaden the prompt or add new prompt sections | unnecessary for this issue.
Confidence: high
Scope-risk: narrow
Directive: Keep future hotword guidance user-facing and proactive, but still avoid blanket replacement language.
Tested: cargo test --manifest-path src-tauri/Cargo.toml polish::tests -- --nocapture; cargo check --manifest-path src-tauri/Cargo.toml
Not-tested: Live LLM output quality against the updated prompt wording.
2026-05-01 22:25:37 +08:00
baiqing 110332580a chore: release 1.2.11 2026-05-01 21:37:59 +08:00
baiqing 65c9707029 fix(qa): Windows preset 用 Ctrl+Shift+ 替代 Cmd+Shift+
issue: Windows 用户在划词追问设置页看到的 dropdown 全是 Cmd+Shift+...,
选了之后 prefs 写入 modifiers:['cmd', 'shift'],后端 global-hotkey crate
把 cmd 翻译成 Win 键 → Win+Shift+; 大概率被 OS 占用 / 注册失败 → 浮窗永远不弹。

修:SelectionAsk.tsx 按 detectOS() 区分 preset。
- macOS:Cmd+Shift+;/// (维持现状,Cmd 是 macOS 主修饰键)
- Windows:Ctrl+Shift+;/// (Ctrl 是 macOS Cmd 的对等键)

为什么**不**用 Fn+Shift+/:Windows 的 Win32 全局热键 API
(RegisterHotKey 和 WH_KEYBOARD_LL)都收不到 Fn 的虚拟键码——Fn 是
硬件级 modifier,在 OS 内核 / 键盘驱动之下被吃掉。Linux 同理。

后端 types.rs::QaHotkeyBinding::default() 已经按平台返回正确默认值
(macOS=cmd+shift+;, Windows=ctrl+shift+;),本次只补前端 preset 的平台分流。
2026-05-01 21:29:32 +08:00
baiqing 541e07018a chore: release 1.2.10 2026-05-01 21:19:58 +08:00
TRIP 277f50a6f6 Merge pull request #133 from Cooper-X-Oak/codex/fix-deepseek-model-reference
fix(llm): 更新 DeepSeek 模型引用名
2026-05-01 21:19:38 +08:00
TRIP 60b75de65e Merge pull request #129 from Cooper-X-Oak/codex/fix-volcengine-seedasr-resource
fix(asr): 适配火山 2.0 资源 ID 并稳定保存凭据
2026-05-01 21:19:22 +08:00
Cooper-X-Oak 5815b7022c fix(llm): 更新 DeepSeek 模型引用名 2026-05-01 19:56:05 +08:00
baiqing 27a954e90b chore: release 1.2.9 2026-05-01 19:55:59 +08:00
baiqing a7813094b0 Merge pull request #124 from Cooper-X-Oak/codex/volcengine-asr-field-mapping
fix(settings): clarify Volcengine ASR credential mapping

火山 ASR credential 字段命名统一:App Key/Access Key/Resource ID → 用
volcengine* 前缀的 i18n key 标明对应 APP ID/Access Token/Resource ID,
加 mappingNote 一行说明 Secret Key 当前不需要、Resource ID 默认值。

Settings.tsx 冲突解决:保留 #124 的多行 JSX + volcengine* key 写法
(main 上 #122 加的 appIdLabel 等老 key 留着不删,避免影响其他引用)。
2026-05-01 19:43:10 +08:00
Cooper-X-Oak 46134eb6b2 fix(settings): align Volcengine labels with console 2026-05-01 19:35:51 +08:00
Cooper-X-Oak f0eba9ea36 fix(settings): clarify Volcengine ASR credential mapping 2026-05-01 19:35:51 +08:00
TRIP 949c51199f Merge pull request #121 from Cooper-X-Oak/codex/windows-current-caret-insertion
fix(windows): 粘贴前校验原目标窗口已恢复
2026-05-01 19:34:06 +08:00
TRIP 6614fe2c15 Merge pull request #120 from Cooper-X-Oak/codex/windows-asr-final-timeout
fix(windows): ASR final result 等待加超时保护
2026-05-01 19:32:51 +08:00
TRIP b79a1e76b4 Merge pull request #119 from appergb/feat/selection-voice-qa
feat: 划词语音问答(Selection + Voice Q&A)— closes #118
2026-05-01 19:32:18 +08:00
Cooper-X-Oak f14811c47e fix(asr): 适配火山 2.0 资源 ID 并稳定保存凭据 2026-05-01 19:24:21 +08:00
Chris233 b7fda0d18e Merge pull request #126 from Cooper-X-Oak/codex/volcengine-guide
docs: 新增火山 ASR 极简配置指南
2026-05-01 18:03:10 +08:00
baiqing fab31d23e1 Merge remote-tracking branch 'origin/main' into feat/selection-voice-qa
# Conflicts:
#	openless-all/app/src-tauri/src/lib.rs
2026-05-01 17:47:26 +08:00
baiqing 6e49281519 feat(qa): v2 多轮对话 + 流式输出 + macOS 浮窗修复
issue #118 v2 完整闭环。

## 多轮对话
- QaSessionState 加 messages: Vec<QaChatMessage> + panel_visible flag。
- Cmd+Shift+/ 现在 toggle 浮窗可见性(不再启动录音);浮窗可见时 rightOption
  路由到 QA recording,不可见时仍是主听写。open_qa_panel / close_qa_panel 分离。
- 第一轮 user message 嵌选区原文(# 选区原文 / # 我的问题),之后只送提问。
- 前端 QaPanel 渲染气泡列表(user 蓝色靠右 / assistant 灰色 markdown 靠左)。

## 流式输出
- chat_completion_history → chat_completion_history_streaming:开 stream:true
  + SSE chunk 解析,on_delta 回调把每 chunk emit 成 qa:state{kind:"answer_delta"}。
- 前端 streamingAnswer state + StreamingAssistantBubble(带蓝色闪烁 caret)。
- answer 事件落定后清空 buffer,最终 messages 接管。

## macOS 浮窗修复(v1 一直存在的雷)
- capabilities/default.json 加 "qa" 到 windows 数组。否则前端 listen("qa:state")
  被 Tauri 权限拦截,浮窗永远收不到事件。
- show_qa_window 用 NSWindow.orderFrontRegardless 替代 window.show()
  (后者在 macOS 走 makeKeyAndOrderFront 抢 frontmost)。这样 capture_selection
  的 AX read / Cmd+C fallback 能稳定从原 app 读到选区。
- 所有 ObjC msg_send 必须 wrap 进 app.run_on_main_thread —— macOS 26 对
  NSWindow 主线程要求是硬断言(违反直接 SIGTRAP)。
- NSWindow.movableByWindowBackground=YES:浮窗任意空白处可拖。
- QA hotkey 注册在主线程:global-hotkey crate 在 macOS 用 Carbon
  RegisterEventHotKey,事件回调要靠主 run loop dispatch。

## 胶囊状态同步
- QA 录音 / 转写 / 思考 同步推 capsule:state,让用户在底部胶囊也看到状态。
- schedule_capsule_idle 同时检查 dictation 和 QA 都 Idle 才隐藏,避免旧
  dictation Done timer 把 QA 的胶囊误关。
- open_qa_panel 进入时先 emit Idle 清掉 dictation 残留 message + insertedChars。

## 设置页
- SelectionAsk 独立成一级 tab;预设减到 4 个 cmd+shift+ 系列(Option 跟主听写
  共用,不放进 QA hotkey)。
- howto / hotkey / privacy 文案重写,反映 v2 的「先开浮窗、再 Option 录音」流程。
- prefs 默认 qaHotkey = cmd+shift+;。

## 后续路线图
- docs/qa-reasoning-roadmap.md:思考能力 v2.2 设计稿(C 路线 reasoner model
  切换 + reasoning_content delta + 折叠思考块)。
2026-05-01 17:40:22 +08:00
Cooper-X-Oak b8e43c8a0c docs: link Volcengine guide from README and usage 2026-05-01 17:35:23 +08:00
Cooper-X-Oak 57efa8e64d docs: add OpenLess settings screenshot 2026-05-01 17:34:17 +08:00
Cooper-X-Oak a24ac6e380 docs: add simple Volcengine ASR setup guide 2026-05-01 17:31:31 +08:00
Chris233 6ef2374e9c Merge pull request #122 from H-Chris233/main
feat(settings): 增加供应商鉴权与模型拉取
2026-05-01 17:19:42 +08:00
H-Chris233 1967ba75b2 Prevent stale provider model selections
Validation could leave a previously fetched model list visible after credentials changed or validation failed, and model selection updated before persistence completed. Clear stale models before validation and only reflect selected models after the credential save succeeds.

Constraint: Address review feedback without changing provider discovery scope.

Confidence: high

Scope-risk: narrow

Tested: npm run build

Tested: git diff --check
2026-05-01 17:16:18 +08:00
Chris233 0284ff7b92 Merge branch 'appergb:main' into main 2026-05-01 15:33:21 +08:00
H-Chris233 2fc4299f06 Keep provider validation messages locale neutral
The credential validation IPC returned Chinese success text that Settings rendered directly. Return a structured model count instead and let the frontend localize success or empty-list states through existing i18n resources.

Constraint: Review comment requires locale-neutral validation output.

Rejected: Returning message keys from Rust | model count is simpler and keeps presentation entirely in the frontend.

Confidence: high

Scope-risk: narrow

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

Tested: npm run build

Tested: git diff --check
2026-05-01 15:29:38 +08:00
Cooper-X-Oak c177634a0c test(windows): allow manual speech in real ASR smoke 2026-05-01 15:11:40 +08:00
Cooper-X-Oak f5f6a7f5b1 test(windows): align real ASR smoke hook log pattern 2026-05-01 15:04:35 +08:00
Cooper-X-Oak 6232c491fd fix(windows): guard paste by restored target 2026-05-01 14:09:00 +08:00
Cooper-X-Oak e2774da2c7 fix(windows): bound ASR final result wait 2026-05-01 14:00:35 +08:00
baiqing 78ff8113eb feat(qa): 拆出"划词追问"独立 tab + 修 Windows CI Send 错误
UI 拆分(用户面)
  - 新一级 tab "划词追问"(NAV 在"翻译"后面),icon 是 stroke 文本+问号
  - 新页 src/pages/SelectionAsk.tsx:3 个 Card——触发快捷键预设(含 Cmd+Option
    chord 选项 + 4 个三键预设 + 不启用),保存历史 toggle,使用方法 5 步说明 +
    浮窗位置/生命周期块 + 隐私契约块
  - Settings → 录音 删去 qaHotkey + qaSaveHistory 两行(已搬到新 tab)
  - i18n 加 nav.selectionAsk + 完整 selectionAsk.* 命名空间(zh+en),
    删 settings.recording.qa{Hotkey,SaveHistory}* 旧 keys
  - useAppState.ts AppTab 加 'selectionAsk'

Windows CI fix(PR #119 失败原因)
  - qa_hotkey.rs::Inner 含 GlobalHotKeyManager → Windows 上含 HHOOK 这种
    *mut c_void 不实现 Send/Sync,导致 coordinator.rs:1998 的 async_runtime::spawn
    捕获 Arc<Inner> 时 Windows 编译失败(macOS 编译过)
  - 加 unsafe impl Send + Sync for Inner,与现有 hotkey.rs::CallbackContext 同款
    做法(OS 句柄实际跨线程安全,crate 没标)

不动后端 hotkey 实现
  Cmd+Option chord 选项 UI 已暴露但底层 global-hotkey crate 不支持
  modifier-only chord(需要 CGEventTap 自己写状态机),UI 上加 ⚠️ 警告说明
  "需要 v1.2.9+ 才支持"。当前默认仍为 Cmd+Shift+;。
2026-05-01 13:37:13 +08:00
baiqing e68b29d5a3 chore(qa): 集成 — 对齐 Rust↔TS 事件 payload 字段名
前后端 agent 各自实现完整路径后联调出 4 处契约不齐:

1. selectionPreview → selection_preview(snake_case 对齐 issue #118 spec)
2. answer payload `text` → `answer_md`,去掉前端用不到的 question 字段
3. error payload `message` → `error`
4. recording / transcribing / thinking 三个进度态合并为前端能识别的
   `loading`,避免前端 fall-through 渲染成空 AnswerView

外加 QaPanel 收到 idle 时直接 return,不替换 pinned 用户正在读的 answer
(idle 语义是"会话状态机回到 Idle",不 pin 时后端自己 hide 窗口)。

cargo check + npm run build 全绿,16 warnings 全是 pre-existing。
2026-05-01 13:17:09 +08:00
baiqing 1a0efe402c feat: 划词语音问答前端 — closes #118 前端部分
- 新增 qa 浮窗(tauri.conf.json windows[2]):380x280 无装饰磨砂玻璃
- 新增 QaPanel.tsx:loading skeleton / answer markdown / error 三态
  - marked@^11 渲染 markdown,注入轻量排版 CSS
  - Esc / 失焦 / 30s 超时自动 dismiss(Pin 时跳过)
  - 监听 qa:state + qa:dismiss 后端事件
- App.tsx 路由:?window=qa → QaPanel
- types.ts:QaHotkeyBinding + UserPreferences.qaHotkey/qaSaveHistory
  以及 QaStatePayload(snake_case 字段对齐 Rust)
- ipc.ts:getQaHotkeyLabel / setQaHotkey / qaWindowDismiss / qaWindowPin
  以及 mockSettings 默认 cmd+shift+;
- Settings 录音区新增「提问模式快捷键」下拉(4 预设 + 不启用)
  与「保存 Q&A 历史」开关
- i18n:zh-CN + en 同步新增 qa.* 与 settings.recording.qa* 文案
2026-05-01 13:14:11 +08:00
baiqing e5740298fa feat: 实现划词语音问答(QA)后端 Rust 路径
issue #118 后端实现:用户按 Cmd+Shift+;(macOS)/ Ctrl+Shift+;(Windows)
触发,捕获前台 app 当前选区文本,同时进入语音录音;再次按下停止后将
ASR 转写 + 选区文本送给 LLM,把 Markdown 答案显示在 QA 浮窗。

主要改动:
- types.rs:新增 QaHotkeyBinding 类型 + UserPreferences.qa_hotkey /
  qa_save_history 字段,serde(default) 兼容老 preferences.json。
- qa_hotkey.rs:新模块,用 global-hotkey crate 注册组合键并通过 mpsc
  发 QaHotkeyEvent::Pressed 边沿事件,drop 时反注册。
- selection.rs:新模块,三级 fallback 抓选区
  (macOS AX kAXSelectedText → Cmd+C / Ctrl+C 模拟复制 → Linux 返回 None),
  超 4000 字符截断为首尾各 2000 + […truncated…],模拟复制后还原原剪贴板。
- polish.rs:新增 OpenAICompatibleLLMProvider::answer_with_selection 方法
  + qa_system_prompt / qa_user_prompt,复用现有 chat_completion + context_premise。
- coordinator.rs:新增 QaSessionState(独立 phase 枚举,不抢 dictation 状态)+
  qa_hotkey supervisor / bridge 线程 + begin_qa_session / end_qa_session /
  cancel_qa_session 全流程;静默录音不调 LLM,prefs.qa_save_history=false 时
  不写 history.json。
- commands.rs / lib.rs:暴露 get_qa_hotkey_label / set_qa_hotkey /
  qa_window_dismiss / qa_window_pin IPC,新增 show_qa_window /
  hide_qa_window helper(label="qa",380×280,紧贴胶囊上方 8pt)。

CLAUDE.md 红线:
- macOS hotkey 走 global-hotkey crate(内部 Carbon RegisterEventHotKey),
  不引入 rdev,不破坏现有 CGEventTap dictation 路径。
- show_qa_window 不调 NSApp.activate,避免抢前台 app 焦点导致 Cmd+C 选区
  捕获失败。
- bundle id / dictionary.json 不动;新模块依赖只通过 types.rs。
- ASR / LLM 失败保持「用户的话不丢」语义,前端浮窗收 error 状态自行处理。

cargo check + 现有 coordinator 测试 + 新增 6 个 qa_hotkey/selection 单测
全部通过;pre-existing 15 warnings 不涉及(仅多 1 个 source_app 暂未读
取的 dead-code 警告,是给前端 agent 预留的字段)。
2026-05-01 13:14:11 +08:00
TRIP 5650a9a1bc Merge pull request #117 from appergb/feat/front-app-context
feat: 跨 App 语气适应(前台 App 注入 LLM context)
2026-05-01 12:53:47 +08:00
baiqing 3ad57983d8 feat: 跨 App 语气适应(前台 App 注入 LLM context)— closes #116
参考 Wispr Flow / Superwhisper Super Mode / Typeless 的"按应用调整语气"
设计:begin_session 捕获前台 app 标签 → polish/translate 调用前作为
"# 上下文\n当前前台应用:…" 拼到 system prompt 头部,让 LLM 自行根据
app 类型调风格,不维护硬编码 app→style 表。

实现
  - coordinator.rs::capture_frontmost_app(macOS NSWorkspace 拿
    localizedName + bundleIdentifier;Windows GetWindowTextW 拿前台
    HWND 标题;Linux/其他平台 None)
  - SessionState 加 front_app: Option<String>,begin_session 填充
  - polish.rs::polish/translate_to 新增 front_app: Option<&str> 参数
  - 原 working_languages_premise 提升为 context_premise,两个字段
    一起拼成 # 上下文 块
  - repolish 路径独立调用 capture_frontmost_app(不沿用原 session 的
    上下文,因为用户重新润色时所处的 app 可能已经不同)

Out of scope(v1)
  - 不读 AX 焦点元素的 selectedText(隐私 + Electron app 兼容性差)
  - 不维护 app→style 映射表(让 LLM 自己理解)
  - Linux 实现跳过

NSWorkspace 是 macOS 公开 API,无需额外权限;Windows 复用现有
foreground HWND 路径,也不增加权限要求。
2026-05-01 12:41:30 +08:00
Chris233 da31f67b3f Merge branch 'appergb:main' into main 2026-05-01 11:38:05 +08:00
TRIP 39c4633fbd Merge pull request #115 from appergb/chore/release-1.2.8
chore: release 1.2.8 + zh-CN Access Key label 精简
2026-05-01 11:29:29 +08:00
baiqing 1992647040 chore: release 1.2.8 + i18n cleanup
火山引擎 ASR Access Key 字段 zh-CN label 从 "Access Key(访问密钥)"
精简为 "Access Key",与英文版统一、与 App ID 改名风格一致,
去掉对用户的视觉干扰。后端 keychain account 名 volcengine.access_key 不变,
老用户凭据保留。

bump version 1.2.7 → 1.2.8(package.json / tauri.conf.json / Cargo.toml / Cargo.lock)。
2026-05-01 11:24:16 +08:00
H-Chris233 2bb2930f6c Let users verify provider credentials before dictation
Provider setup needed an explicit way to validate OpenAI-compatible credentials and discover account models without forcing manual model IDs. Add minimal IPC commands for /models checks and a small Settings UI control that preserves manual entry when discovery fails.

Constraint: Do not leak API keys in logs or user-visible provider error bodies.

Rejected: Full provider-specific SDK integrations | OpenAI-compatible /models covers the configured providers with less scope.

Confidence: medium

Scope-risk: moderate

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

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

Tested: npm run build

Tested: git diff --check
2026-05-01 11:14:16 +08:00
TRIP b7e934a8b9 Merge pull request #113 from appergb/fix/translation-mode-and-codex-fixes
feat: 翻译模式 + Codex 后审修复 + 胶囊翻译指示器
2026-05-01 10:18:29 +08:00
baiqing bf335da697 feat: 翻译模式 + Codex 后审修复 + 胶囊翻译指示器
翻译模式(issue #4)
  按住录音键时随时按一下 Shift(任一侧)→ 录音结束后走"翻译输出"管线,
  按"翻译"页中选定的目标语言翻译后插入到光标。
  - hotkey.rs 三平台(CGEventTap / Win32 hook / rdev)都监听 Shift down 边沿,
    通过新增的 HotkeyEvent::TranslationModifierPressed 上报
  - coordinator.rs 加 translation_modifier_seen 标志位(begin_session 重置);
    end_session 路径根据它 + 非空 target_language 选 polish 或 translate
  - polish.rs 抽 chat_completion 共享通道;新增 translate_to + translate_system_prompt;
    working_languages 作为 system prompt 头部前提注入两条管线
  - types.rs::UserPreferences 加 working_languages(默认 ["简体中文"])+
    translation_target_language(默认空)
  - Settings.tsx 删除原来的录音 section 翻译配置;新建 Translation.tsx 一级页(在风格下面),
    含工作语言多选 + 目标语言下拉 + 5 步使用指南
  - 新增 capsule.tsx 翻译徽章:"● 正在翻译" 蓝色药丸,绝对定位在 pill 上方 8px,
    opacity + translateY transition 平滑出入;CapsulePayload 加 translation: bool
  - capsule 窗口高度 96 → 110 给 badge 让出空间
  - 内置 SUPPORTED_LANGUAGES 列表(15 种自然语言原生名)

Codex 后审修复(基于 4f45dee main 上跑的整体审查)
  - tauri.conf.json 主窗口 decorations 由 #108 设的 false 还原为 true,
    Windows-only 在 lib.rs::setup 里 set_decorations(false),让 macOS 拿回原生红黄绿
  - coordinator.rs::SessionState 加 session_id;spawn_recorder_error_monitor
    捕获当前 id,迟到的 cpal 错误若 id 不匹配直接 drop,不会误中止后续 session
  - volcengine.rs 把 spawn-per-chunk 模式改成单 mpsc worker 串行 send,
    彻底消除跨 consume 调用的 writer 锁 race(之前的 fix 仅在 burst flush 内部有效)

附带修复
  - insertion.rs Windows/Linux 粘贴后剪贴板恢复加用户开关 restore_clipboard_after_paste
    (issue #111),默认 true 保留现行行为;关掉后听写文本留剪贴板,paste 失败时可手动 Ctrl+V 找回
  - SettingsModal 内容区改为 flex column + overflow:hidden,X 按钮 + 标题固定,
    只 section 内容区滚动;Settings.tsx 嵌入模式右栏独立 scroll
  - Settings → 提供商:火山引擎 "App Key" 文案改为 "App ID"
    (keychain account name 不变,老用户凭据不丢)
  - i18n 增加 capsule.translating / nav.translation / translation.* 完整命名空间
2026-05-01 10:10:23 +08:00
TRIP 4f45dee2d0 Merge pull request #109 from H-Chris233/main
[谨慎发布,需要测试]fix(recorder): 上报录音流运行期错误
2026-05-01 08:14:14 +08:00
TRIP 769fbdffde Merge pull request #108 from Cooper-X-Oak/codex/windows-ui-fixes
fix(windows): polish capsule and custom titlebar shell
2026-05-01 08:14:09 +08:00
TRIP 27aa005bec Merge pull request #106 from Cooper-X-Oak/codex/fix-windows-gnu-export-ordinal
fix(windows-gnu): 禁止 MinGW 为 cdylib 自动导出符号
2026-05-01 08:14:03 +08:00