TRIP and sim
a5a9c7f0b5
test: pin local tsx runner ( #828 )
...
Co-authored-by: sim <sim@local>
2026-07-15 13:44:39 +08:00
TRIP and sim
d6ca07a6b2
fix(android): break IPC settings barrel cycle ( #827 )
...
Co-authored-by: sim <sim@local>
2026-07-15 13:20:57 +08:00
Chris233
c645b16851
Disable background scrolling when settings open ( #776 )
...
Fixes #580 : prevent background thin-scroll areas from scrolling/bleeding through when the Settings modal is open. Adds data-ol-settings-open={settingsOpen ? 'true' : undefined} to the main FloatingShell div and corresponding CSS in tokens.css to set overflow:hidden and hide WebKit scrollbars when the attribute is present. Also adds settings-modal-scroll-isolation.test.mjs to assert the attribute placement and CSS selectors.
2026-07-14 19:34:11 +08:00
TRIP and sim
fa53f47f08
fix(security): redact Less Computer approval tokens ( #820 )
...
Co-authored-by: sim <sim@local>
2026-07-14 19:07:20 +08:00
TRIP and sim
6aaae670b0
fix(security): bound style-pack ZIP imports ( #819 )
...
* fix(security): bound style pack archive imports
* fix(security): validate physical ZIP directory entries
---------
Co-authored-by: sim <sim@local>
2026-07-14 19:02:03 +08:00
145a0ea17d
feat(asr): add ElevenLabs Scribe v2 provider ( #807 )
...
* fix(asr): 完善 ElevenLabs Scribe 接入
* fix(asr): omit ElevenLabs word timestamps
* fix(qa): treat ElevenLabs cancellation as idle
---------
Co-authored-by: Chris233 <h-chris233@outlook.com >
Co-authored-by: sim <sim@local>
2026-07-14 15:29:16 +08:00
TRIP and sim
66d084792f
fix(security): patch RustSec dependency advisories ( #809 )
...
Co-authored-by: sim <sim@local>
2026-07-14 14:54:05 +08:00
TRIP and sim
ef6f1fadb4
fix(cask): update Homebrew package to v1.3.14 ( #802 )
...
* fix(cask): point Homebrew to v1.3.14
* fix(cask): declare Monterey requirement
---------
Co-authored-by: sim <sim@local>
2026-07-14 14:43:36 +08:00
yuanchenglu and Chris233
6140a4b243
fix(linux): prevent startup panic from unrealized capsule GDK window | fix(linux): 修复胶囊窗口因 GDK 未实例化导致的启动崩溃 ( #792 )
...
* fix(linux): prevent startup panic from unrealized capsule GDK window | fix(linux): 修复胶囊窗口因 GDK 未实例化导致的启动崩溃
On Linux X11, when the capsule window is created with `visible: false` +
`transparent: true` in tauri.conf.json, its underlying GDK window is never
realized. The subsequent call to `capsule.set_ignore_cursor_events(true)`
triggers a panic inside tao's Linux event loop (event_loop.rs:457) because
`window.window().unwrap()` returns `None` for an unrealized GDK window.
The fix follows the same approach as voicebox PR#837 (PhamBit):
force GDK window realization before calling set_ignore_cursor_events, by
first moving the window off-screen and calling show(). The window is then
repositioned correctly by the existing position_capsule_bottom_center()
call and hidden as normal.
Refs:
- https://github.com/jamiepine/voicebox/pull/837
- https://github.com/tauri-apps/tao/issues/635
在 Linux X11 上,tauri.conf.json 中定义的 capsule 窗口设置了
visible: false + transparent: true,导致其底层 GDK 窗口从未被实例化。
随后调用 capsule.set_ignore_cursor_events(true) 时,tao 的 Linux 事件循环
(event_loop.rs:457) 因 window.window().unwrap() 返回 None 而 panic 崩溃。
修复方法参考 voicebox PR#837:在设置鼠标穿透前先将窗口移出屏幕并
调用 show() 强制 GDK 实例化,后续由原有的 position_capsule_bottom_center()
重新定位并隐藏。
* fix(linux): realize hidden capsule without showing it
---------
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-14 10:52:39 +08:00
bigsong and Chris233
6e79a0c289
feat(asr): 百炼 ASR 支持 fun-asr-flash 并统一三协议为单一入口 ( #793 )
...
* feat(asr): 百炼 ASR 支持 fun-asr-flash 并统一三协议为单一入口
* fix(asr): harden DashScope model routing and transcription
* fix(asr): address Bailian protocol review feedback
---------
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-14 10:51:36 +08:00
bigsong and Chris233
3f51edafab
fix(local-asr): 本地 Qwen3 模型在云端 provider 下误标「当前使用」 ( #794 )
...
* fix(local-asr): 本地 Qwen3 模型在云端 provider 下误标「当前使用」
* fix(local-asr): sync active provider preference
---------
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-14 10:51:00 +08:00
a77cbd4722
fix(dictation): 转写阶段可中断——按 Esc 立即取消在途 ASR 请求 ( #798 )
...
* fix(dictation): 转写阶段可中断——按 Esc 立即取消在途 ASR 请求
进入 Processing(转写)后,end_session 已把 ASR 句柄从 inner.asr 槽 take 走,
cancel_session 走的 cancel_asr_for_session 是 no-op,够不到在途请求:用户按 Esc
后仍要等整段转写跑完才停,且结果被静默丢弃,白等一场。
改为把转写与「用户取消」轮询用 tokio::select! 赛跑:命中取消即 drop 掉 transcribe
future(中断 reqwest HTTP / 停止等待流式最终结果 / 停止本地转写),再显式
cancel_active_asr 促流式 WebSocket 立即关闭,然后 finish_cancelled_processing 收尾
静默返回。覆盖云端流式 / 云端批量 / 本地引擎全部 provider。
顺带删除 Foundry / Sherpa / Apple Speech 分支里各自的 if cancelled 早退补丁——
取消现在由外层 select! 统一处理,那些分支已冗余。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* fix(dictation): clean up cancelled ASR sessions
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-14 10:05:36 +08:00
a49d02b908
fix(settings/overview): 清理 Windows 上不适用的 UI 选项/标签/布局 ( #799 )
...
* fix(hotkey): Windows 移除 Command 单键预设
Windows 没有 Command 键,leftCommand/rightCommand 会被映射到 Win 键,而单按 Win
弹出开始菜单,实际无法作为录音热键。从 Windows 的 available_triggers 里删掉这两个
预设,前端「常用单键」chip 便不再展示;不影响 HotkeyTrigger 枚举本身与已有绑定。
Fixes #784
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* fix(settings/overview): 清理 Windows 上不适用的 UI 选项/标签/布局
- #783 补齐 hotkey.triggers 缺失的 leftShift/rightShift/leftCommand i18n(5 语言);
之前缺 key 导致预设 chip 渲染成裸串 "hotkey.triggers.xxx"(用户看到的 "host…")
- #786 移除「粘贴快捷键」里的 Shift+Insert (xterm/urxvt) 选项——这组设置只在 Windows
出现,而该选项是 X11 终端专用,放 Windows 上纯误导
- #785 删除「自动更新」下方错位的 hotkey statusHint(本属快捷键区,误挂到启动组)
- #780 「胶囊确认插入 ✓」速查行改为仅 macOS——Windows/Linux 胶囊无此按钮
- #781 「年度活动」卡片补 marginBottom,与上方卡片 18px 节奏一致
- #782 「近 7 天」卡片加 overflow:hidden,窗口过小时柱状图不再溢出卡片圆角外
Fixes #783 , #786 , #785 , #780 , #781 , #782
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* fix(settings): migrate removed Windows paste shortcut
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-14 10:04:56 +08:00
01bff73cbe
fix(prefs): 解析失败时逐字段抢救+备份,避免升级改 schema 静默清空设置 ( #791 )
...
* fix(prefs): 解析失败时逐字段抢救+备份,避免重构改 schema 静默清空设置
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* fix(prefs): harden corrupt preference recovery
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-13 10:57:44 +08:00
414acf0dc7
feat(settings): 设置项悬停显示功能说明,降低 Less Computer / 录音胶囊等的理解门槛 ( #777 )
...
* feat(settings): 设置项悬停显示功能说明,降低 Less Computer / 录音胶囊等的理解门槛
页面瘦身后设置页描述小字全部隐藏,Less Computer、录音胶囊这类光看名字
猜不出用途的功能只剩一个标签,理解成本高。本次把已有的 desc 文案以
Tooltip 形式挂回标签文字上:
- Tooltip 新增 wrap 模式,整句说明允许换行(默认 nowrap 不变)
- SettingRow 的 desc 恢复生效:悬停标签文字弹出说明,虚线下划线 +
help 光标做「可悬停」暗示,布局保持紧凑
- SectionTitle 新增 hint,Less Computer / Claude 控制台 / 录音与输入
三个板块标题接上已有的 desc 文案
- 录音与输入里录音胶囊 / 录音方式 / 首选麦克风 / 录音时静音 /
插入剪贴板等行补传现成的 i18n desc
文案全部复用现有 i18n key,五种语言无需新增翻译。
* feat(settings): Less Computer 快捷键提示补一句「功能说明参见高级设置页」
通用页 Less Computer 那行原提示只讲快捷键用法,补一句指向「高级」设置页
的功能说明入口,降低理解门槛。5 语言同步。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* fix(settings): make hints accessible and viewport-safe
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-12 21:44:09 +08:00
695813074f
feat(ux): 三个小改进——Esc 立即收起胶囊 / 概览复制按钮 / 历史页 ⌘R 刷新 ( #790 )
...
* feat(capsule): Esc/主动取消时胶囊立即消失(取消延迟 2000ms→0)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* feat(overview): 「最近识别」每行加复制按钮(Btn children 改可选)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* feat(history): ⌘R 刷新历史列表(拦截整页 reload,仅重拉 listHistory)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* fix(dictation): finish cancelled processing sessions
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-12 21:42:50 +08:00
bigsong and Chris233
9ed34dabea
feat(asr): 新增百炼 Qwen3-ASR-Flash 实时供应商(OpenAI Realtime WS 协议) ( #775 )
...
* feat(asr): 新增百炼 Qwen3-ASR-Flash 实时供应商(OpenAI Realtime WS 协议)
bailian.rs 头注释预留的 follow-up 协议线:/api-ws/v1/realtime,与经典
/api-ws/v1/inference 并列为独立供应商 bailian-qwen3-realtime。
- asr/qwen_realtime.rs:新客户端。base64 JSON 事件流 + server_vad 自动断句,
按序收集 completed 句段;session.finish 冲刷尾段后回 session.finished。
关键协议行为均经 2026-07 线上实测:尾段冲刷(说到一半松手不丢字)、
纯静音验证干净返回、language 省略走自动检测、业务空间专属域名
(wss://{WorkspaceId}.cn-beijing.maas.aliyuncs.com)同样承载此路径。
- coordinator / asr_wiring / dictation / qa_session / resources:与 Bailian
分支同构接线(流式 WS + DeferredAsrBridge)。
- 验证与拉取模型:真实 WS 连通性检查;协议头校验(qwen3EndpointSchemeInvalid)。
- 前端:ASR 预设下拉新增一项;i18n 5 语言。
测试:cargo test 573 passed(新增 18 个客户端单测);npm run build 通过。
* fix(asr): harden qwen realtime protocol
---------
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-12 20:15:04 +08:00
b8acb9bdcc
feat(hotkey): 录音方式新增「自动」——短按=切换式,长按=按住说话 ( #789 )
...
* feat(hotkey): 录音方式新增「自动」——短按=切换式,长按=按住说话
在「切换式 / 按住说话」外新增第三种录音方式 Auto:按下即开录,
松手时按按住时长判定语义 —— 短按(< 350ms)锁存为切换式(保持
录音,下次按下再停),长按(>= 350ms)当作按住说话(松手即停)。
已锁存后再次按下即停。
实现要点:
- HotkeyMode 新增 Auto 变体(前后端类型同步)
- Coordinator 在 handle_pressed/handle_released 解释边沿:按下记录
press_at,松手用 elapsed() 判定短/长按
- 判定在松手处理时测量,会被 begin_session 阻塞 bridge 的时长抬高;
350ms 阈值下仅当冷启动 >= 350ms 时短按可能误判为长按(可恢复),
常见快速启动下判定正确。该权衡避免改动跨平台的 P0 串行化热键路径
- 设置页新增第三个分段选项;标签/使用提示与 5 种语言 i18n 补齐
- 新增 2 个单元测试覆盖短按锁存 / 长按结束
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
* fix(hotkey): preserve auto press duration across queueing
* fix(hotkey): compile timestamped edges on all targets
* test(hotkey): add Windows edge assertion helper
* fix(hotkey): show auto mode in shortcuts settings
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-12 20:14:01 +08:00
Duyi-Wang and Chris233
ef1561ebf7
fix(asr): 修复 Windows 本地长语音只识别前段 ( #769 )
...
* Fix long Windows local ASR transcription
* fix(asr): enforce total chunk timeout budget
* fix(asr): align Foundry native runtime versions
---------
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-12 15:29:47 +08:00
Haoqian and Chris233
f2c23723ee
fix: preserve active style across settings saves ( #747 )
...
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-11 13:02:38 +08:00
bigsong
4242020ae9
fix(asr): 百炼连接检查修复验证必败(EmptyAudio)并真实校验连通性与协议头 ( #773 )
...
三个缺陷叠加导致「阿里云百炼实时 ASR」的连接检查完全不可用:
1. 「验证」必然失败:只发 1 个 100ms 静音块就 finish-task,DashScope 对
<200ms 音频必返回 task-failed: EmptyAudio(2026-07 实测边界:100ms 拒、
200ms 起收)——有效凭据也永远显示「操作失败」。改为发送 500ms 静音。
2. 「拉取模型」假成功:直接返回硬编码列表、不发任何网络请求,Key/endpoint
全错也显示成功。现在先执行与「验证」相同的 WebSocket 连通性检查
(百炼无模型列表接口,列表本身仍为静态)。
3. 接口地址误填 https://(百炼控制台兼容模式/专属域名地址)时,WS 握手报的
"URL scheme not supported" 被前端兜底成笼统「操作失败」。现在验证入口
校验协议头必须为 ws:// / wss://,返回专用错误码
bailianEndpointSchemeInvalid,前端映射为含默认 wss 地址的明确提示
(en / zh-CN / zh-TW / ja / ko)。
测试:cargo test 555 passed;npm run build (tsc + vite) 通过;
DashScope 线上协议行为已用独立脚本实测确认。
2026-07-11 00:37:15 +08:00
TRIP and sim
d8789c783d
feat: 统一聊天面板(官方 shadcn)+ 1.3.14 审计修复批 + CVE 补丁 ( #767 )
...
* fix(deps): patch tauri-plugin-shell CVE (GHSA-c9pr-q8gx-3mgp)
@tauri-apps/plugin-shell (npm) 与 tauri-plugin-shell (crate) 的声明下限
——npm `^2.0.1`、crate `"2"`——都落在 GHSA-c9pr-q8gx-3mgp 影响范围
(`< 2.2.1`,CRITICAL:`open` 端点作用域校验绕过,可致 RCE)。本项目
src/lib/ipc/utils.ts 正是通过该 `open` 端点打开外链,属受影响用法。
两个 lockfile 实际已解析到 2.3.5,但清单声明的下限仍是漏洞版本,供应链
扫描(SkillSpector SC4)因此读取到 2.0.1 报警。此处仅把两侧声明下限抬到
最新安全版 2.3.5,使清单与锁定版本一致、扫描不再命中;解析版本不变,无
运行时行为变化。
Closes #668
* fix(audit): 1.3.14 审计修复一批(Apple Speech 取消/IME 保存锁死/侧向键卡死/火山429 等)
- CRIT Apple Speech 取消/超时不终止 SFSpeechRecognitionTask(SendableTask+cancel_flag+[task cancel]+100ms 轮询)
- HIGH windows_ime 未安装分支反致设置保存事务锁死(抽纯函数 keyboard_list_pref_short_circuit)
- HIGH 侧向键 Released 卡死自愈 + macOS flags 类位竞态 + Linux 显式拒绝
- HIGH coordinator/hotkey_loops unused_assignments clippy 回归
- MED 火山 429 限流不重试(RateLimited)/ Heatmap clamp / 授权失败反馈 / SendInput 分类单一真相 / SendInputOptions 收敛
- 清理 删死码 ?? '重启' / side_aware 死字段 / 孤儿 MarketplaceModal
cargo test 552-0 / npm build 绿。windows cfg 部分需 CI 四平台验证。
* feat(chat): 统一聊天面板组件库——官方 shadcn base 组件按 CLI 规则内嵌
@shadcn/react 官方 primitive + base-rhea registry 原文内嵌 components/chat/ui/
(message-scroller/marker/bubble/message/card/empty/input-group/button/input/
textarea/spinner,仅按 CLI 规则改 import 路径;button 保留 3 行 React18 inert
归一)。Tailwind v4 作用域隔离:utilities source(none) + @source 只扫聊天文件、
无层导入压过 global.css;官方主题 shadcn/tailwind.css + tw-animate-css。
胶囊同款思考动画(orbFeed 单 GL 源镜像多头像)、GitHub 头像(CSP img-src 放行)、
出现/消失生命周期 hook。平台门控:非 darwin 构建 DCE 掉 Less Computer chunk。
删除旧自制 Marker/MessageScroller 组件。
* feat(panels): QA/LC 浮窗重写为官方 message-scroller-demo 同款骨架
Card + Empty + InputGroup + MessageScroller 官方组合;QA=Message 带头像形态
(右 GitHub / 左旋转 orb),LC=Marker 工具行形态(无头像)。
语音状态只在输入区:录音红光/转译黑光绕输入组跑圈,问题落定即停;
思考头像行门控在用户消息落定之后(修「AI 头像先出现、动画抽搐」)。
LC 事件空轮自愈 + mount 后 less_computer_sync 重放(webview 冷加载丢
user 事件导致「后端在跑前端空白/用户的话不显示」)。纯白背景、官方
24px 圆角、出现/消失动画(chat-panel:shown/closing)。
* fix(backend): 聊天面板后端配套——命令注册/非激活面板/事件缓冲/生命周期
- 恢复桌面 invoke_handler 的 qa_submit_text / qa_toggle_recording(此前删
qa_window_pin 时误删相邻项,真机报 Command qa_submit_text not found)
- QA/LC 窗口转非激活 NSPanel(胶囊同管线:NonactivatingPanelMask +
CanJoinAllSpaces|FullScreenAuxiliary),chat_panel_focus_keyboard 改主线程
makeKeyAndOrderFront:打字不激活 app、主窗口不再被带出、frontmost 保持
用户原 app(划词选区在多轮期间仍可读)
- Less Computer 事件按全局单调 seq 写入环形缓冲(fresh user 清空、cap 2048
丢最旧),新命令 less_computer_sync 供前端 mount 重放(仅 less-computer
窗口可调);附 2 个单测
- show/hide 生命周期:show 发 chat-panel:shown 并作废挂起 hide;hide 先发
chat-panel:closing、240ms 后真正隐藏(AtomicU64 世代防快速关-开竞态)
- QA/LC 窗口统一固定 420×540;删除 qa_window_pin / less_computer_window_resize
整链(无消费方)
---------
Co-authored-by: sim <sim@local>
2026-07-06 22:21:16 +08:00
2e3c0f5c29
fix(windows-ime): stop explorer.exe AppHang from IME pipe server shutdown ( #764 )
...
OpenLessIme.dll is a system-wide TSF keyboard TIP, so CTF loads it into
every process that has text input (explorer.exe, the taskbar, ...) and
runs it on that process's UI thread. The per-process pipe server blocked
on a synchronous ConnectNamedPipe, and Deactivate() -> Stop() joined that
worker from the host UI thread, relying on a racy CancelSynchronousIo +
self-connect WakePipe() to unblock it. When both lost the race the worker
re-entered ConnectNamedPipe forever and join() froze the host UI thread
indefinitely -> explorer.exe AppHangB1 (taskbar unresponsive, Explorer
restarts). WER reports for the reported hangs show OpenLessIme.dll loaded
in explorer.exe, and disabling the TSF profile stops the hang.
Make every pipe wait deterministically cancelable: open the pipe with
FILE_FLAG_OVERLAPPED and wait on {io_event, stop_event} via
WaitForMultipleObjects. Stop() now just signals stop_event and joins, so
it returns at once, never blocks the host UI thread, and leaks no worker
thread. Connect/read/write go through WaitForClient / RunOverlapped, which
CancelIoEx + drain the overlapped op before the stack OVERLAPPED / buffer
go out of scope. Removes the racy WakePipe / CancelSynchronousIo /
pipe_handle_ / pipe_mutex_.
Pipe name, JSON wire protocol and the Rust client (windows_ime_ipc.rs)
are unchanged.
Fixes #665
Fixes #707
Co-authored-by: appergb <lubaiqing9@gmail.com >
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-06 20:08:29 +08:00
TRIP and sim
95e4cdf203
fix(audio-cue): recover when resume() is rejected or wakes non-running ( #757 )
...
Long sessions park the shared AudioContext in 'suspended' / WebKit
'interrupted' after the system audio session is repeatedly preempted by
ASR and recording. The earlier fix only recreated a 'closed' context: a
rejected resume() was swallowed and a resume() that resolved without
reaching 'running' scheduled voices on a frozen currentTime, both of
which leave the start cue permanently silent until the app restarts.
Treat both "won't wake" states as recoverable — discard the dead context
and retry once on a fresh one, bounded to avoid infinite recreation. The
decision is extracted into the pure, unit-tested cueActionAfterResume.
Co-authored-by: sim <sim@local>
2026-07-06 20:01:40 +08:00
7de0c04ba5
docs: 用协调沉降定律重构 README 能力/增强叙事,凸显开屏即授权完基础设施 ( #765 )
...
- 新增「从工具到基础设施 / From tool to infrastructure」专章:把 OpenLess 定位为
消灭「想法 → 干净文字」之间每一次协调的基础设施——语气沉降成风格包、专有名词
沉降成词典热词、文字落点沉降成插入协议、模型与凭据沉降进系统保管库,开屏授权
一次即为默认协议。
- 改写「更新亮点(增强)」与「当前状态(能力)」两节开场,从功能罗列改为「你授权
一次之后就不必再操心的基础设施层」;其余条目与版本号(v1.3.6)保留不动。
- 中英双 README 同步(README.md + README.zh.md),纯文档改动,不涉及代码/版本门禁。
Co-authored-by: sim <sim@local>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com >
2026-07-05 21:28:36 +08:00
f77bc8fccd
feat(asr): enable speaker diarization to filter non-primary speakers ( #760 )
...
Open volcengine streaming ASR's `enable_speaker_info` flag so each
returned utterance carries a speaker label. Then in the result
assembly, group utterances by speaker, pick the one with the longest
total speaking time as the "primary speaker", and only concatenate
their text — dropping utterances from other speakers (e.g. a
colleague interjecting while you dictate).
This is a heuristic quick-win for the "only transcribe my voice"
request; it does not yet do enrolled voiceprint verification. If no
speaker labels are present, behavior is unchanged (all utterances
concatenated).
Co-authored-by: Shicongcoding <Shicongcoding@users.noreply.github.com >
Co-authored-by: Claude Opus 4.8 <noreply@owtffssent.com >
2026-07-05 11:26:23 +08:00
TRIP and sim
3ca6883d3a
fix(deps): patch tauri-plugin-shell CVE (GHSA-c9pr-q8gx-3mgp) ( #763 )
...
@tauri-apps/plugin-shell (npm) 与 tauri-plugin-shell (crate) 的声明下限
——npm `^2.0.1`、crate `"2"`——都落在 GHSA-c9pr-q8gx-3mgp 影响范围
(`< 2.2.1`,CRITICAL:`open` 端点作用域校验绕过,可致 RCE)。本项目
src/lib/ipc/utils.ts 正是通过该 `open` 端点打开外链,属受影响用法。
两个 lockfile 实际已解析到 2.3.5,但清单声明的下限仍是漏洞版本,供应链
扫描(SkillSpector SC4)因此读取到 2.0.1 报警。此处仅把两侧声明下限抬到
最新安全版 2.3.5,使清单与锁定版本一致、扫描不再命中;解析版本不变,无
运行时行为变化。
Closes #668
Co-authored-by: sim <sim@local>
2026-07-05 00:40:23 +08:00
351e0211bd
集成 1.3.14 → beta(主窗 UI 大改 + 一批 fix/feat) ( #761 )
...
* fix(insertion): macOS 让「恢复剪贴板」开关真正生效,修复被回退的 #525
#525 的 macOS 剪贴板恢复(commit 4b4d219)被 Android 移植 commit 1ea467a
连同 cfg 门控一起回退:整套恢复机制被重新 #[cfg] 排除出 macOS,macOS insert()
退回「只写剪贴板 + Cmd+V」,于是设置里的「恢复剪贴板」开关在 macOS 上完全无效
——无论开关开还是关,剪贴板都被留成转写文字。
- 把共享的剪贴板恢复机制(ClipboardRestorePlan / schedule_clipboard_restore /
restore_clipboard_after_delay / should_restore_clipboard 等)的 cfg 从
not(any(macos,android,ios)) 放宽为 not(any(android,ios)),重新纳入 macOS
(移动端仍排除;Windows/Linux 不变)。
- macOS insert() 改为:保存原剪贴板 → 写转写文字 → Cmd+V → 仅当「恢复剪贴板」
开关开启且粘贴成功时按 CLIPBOARD_RESTORE_DELAY 延迟恢复;粘贴失败则保留转写
文字供手动粘贴、不恢复。开 = 恢复,关 = 保持现状,开关说了算。
- 删除随之失效的 macos_insert_status_after_paste;恢复相关单测在 macOS 也运行。
Windows/Linux 专用项(insert_with_clipboard_restore / paste_keys /
simulate_paste(shortcut) / 其 insertion_success_status 变体)的 macOS 排除保持不变。
* fix(less-computer): 护栏 sudo/dd/chmod/chown 等设为不可批准,修批准注入畸形规则 (#679 )
旧审批流对所有命中 pattern 一律 format!("Bash({p}:*)") 生成 allow 规则:
- 对带空格/参数的子串("sudo " → "Bash(sudo :*)","dd if=" → "Bash(dd if=:*)",
"chmod -r 777 /"、"chown -r")生成的串既不等于 deny "Bash(sudo:*)" 等(故 deny
没被移除、批准静默失效),又把畸形规则注入了 allowed_tools。
改为:新增 guard::deny_rule_for_pattern(pattern),把「可批准」命令(rm -rf / git
push --force / git reset --hard / git clean 等)映射到其在 default_deny_rules 里的
**精确** deny 规则;提权/毁盘/系统级命令(sudo / dd / mkfs / chmod / chown / shutdown
/ reboot / 管道执行 / fork 炸弹)返回 None = 不可批准,即使被批准也保持拦截
(fail-closed),不再注入畸形 allow。审批流用 filter_map 取精确规则,移除的 deny 与
加入的 allow 严格一致。
附单测:每个可批准 pattern 的映射规则确实存在于 default_deny_rules;危险系统命令一律
不可批准。
* fix(ui): unify macOS shell top inset with sidebar/background surface
The 28px top inset that clears the macOS overlay traffic lights sat on the
content wrapper with no background, so it exposed the lighter WindowChrome
glass (--ol-window-bg) as a full-width band above the sidebar and panel —
reading as an extra top row that the Windows build (no inset) doesn't have.
Paint that wrapper with the same --ol-app-shell-bg the sidebar/background
already use, so the inset blends into one continuous surface with the panel
card floating on top. One property; token carries its own light + dark
values; no layout, token, or other UI changes.
* fix(capsule): 胶囊跟随鼠标光标所在屏,修复多屏/多 Space 只在第一块屏显示
多屏 + 多桌面下胶囊只出现在第一块屏、其他屏闪一下就消失。根因:定位
(position_capsule_bottom_center) 用 AX caret 选屏,多数 App 取不到 caret 矩形就
跌回胶囊自己的 current_monitor(第一块屏);而去重缓存 capsule_layout_snapshot 也
用 current_monitor,与定位看的不是同一块屏 → 胶囊一落第一块屏即被判“无变化”跳过
重定位,被锁死。两条路都没跟踪鼠标。
- 新增 mouse_cursor_point():CoreGraphics CGEventGetLocation 取光标,坐标系与 AX
一致、零权限、永远可用
- focused_input_target_monitor → capsule_target_monitor,选屏改“光标优先”(caret
仅兜底),选屏循环抽成 monitor_for_anchor_point
- 定位与去重快照统一走 capsule_target_monitor,彻底消除不一致
- 保留 CAN_JOIN_ALL_SPACES(Spaces 契约强制且本就正确:帧落在光标屏→只那块屏显示)
- 扩展 macos-capsule-spaces 契约测试,grep 守护“光标优先 + 两路共用同一函数”
Windows 路径未动(本就跟随输入 App 屏且快照一致)。
验证:cargo check + lib 纯函数单测 + check:macos-capsule-spaces 全过。
* feat(less-computer): 边缘发光改用 EdgeGlow 式四层模糊堆叠 + iridescent 配色
把 Less Computer 全屏彩虹边缘发光从原来「两条都带模糊的软光带」改成
EdgeGlow(github.com/vector4wang/EdgeGlow,MIT)的实现方式,让彩虹「实线」
更清晰、发光更有层次。
- 4 层模糊堆叠:最内一条 0.5px 锐利彩虹实线(对应 EdgeGlow blur=0 那层,
定义边缘),外面叠 3 层逐渐变宽、变虚的光晕(blur 3/8/15px),得到
霓虹灯管式发光。原生用 CAShapeLayer + 高斯模糊,这里用 CSS「边框遮罩环
+ filter:blur」等价复刻。
- 配色移植 EdgeGlow 默认的 iridescent(Apple Intelligence 高饱和霓虹:
紫→蓝→青→绿→金→橙→红→粉),按 12 段均匀铺满 360°。
- 流光整圈 8s/圈通过 --lcg-angle 旋转(只动渐变角度不动元素形状,GPU 友好),
光晕层各带不同周期呼吸;实线用 normal 保色准,光晕用 screen 叠加增亮。
保留 issue #470 的隐藏即卸载发光层(零 GPU)逻辑、pointer-events:none、
prefers-reduced-motion 降级与 --lcg-radius 圆角变量。纯视觉、仅 macOS、单文件。
* fix(vault): Windows 凭据读取瞬时失败重试,修概率性「火山引擎未配置」
Windows Credential Manager(CredReadW)在登录后/并发下读 manifest+各 chunk 条目
时可能瞬时失败。任一条目读失败会让整组凭据看起来为空 → load_keyring_credentials
返回 Err → load_credentials 回退到空默认值 → 概览页显示「火山引擎未配置」,但下
一次听写重读成功,所以是「概率性」且「实际可正常使用」。凭据 chunk 越多,单次
load 读取次数越多,命中瞬时失败的概率越高。
修法:仅在 Windows 上对非 NoEntry 的读错误做几次短退避重试(4 次 / 60·n ms)。
NoEntry 是确定的「未存储」,立即返回不付重试延迟。macOS/Linux 保持原单次行为
——它们的读错误是 ACL 拒绝,重试无益,且未缓存的错误路径下次调用本就会重读,
加 sleep 只会拖慢 macOS 首次 Keychain 授权流程。纯后端、cfg 隔离,零 PC-macOS 影响。
* fix(asr): 火山引擎连接增加超时与重试,修弱网下无法语音输入
connect_async 此前既无超时也无重试:弱网下 TLS/WebSocket 握手可能挂到 OS 级
TCP 超时(几十秒),期间用户卡在「Starting」;而协调器全局超时只覆盖
await_final_result,不覆盖 open_session,所以握手挂起完全不受约束。单次网络
抖动(连接被重置/瞬时 DNS 失败)也会直接让整次听写失败。
修法:每次握手包 5s 超时,最多 3 次尝试、250·n ms 退避。AuthRejected(凭据被拒)
短路不重试——重试不会变好只会拖慢报错。把请求构造抽成 build_connect_request
(connect_async 消费 request 且 http::Request 非 Clone,需每次重建)。
桌面与安卓共享此路径,改动对两端等效;最坏耗时从「无界(~75s)」降到有界(~15s)
并新增抖动可恢复,对 PC 端只增不减。
* feat(coding-agent): OpenCode CLI 适配器,语音 Agent 可选 OpenCode 后端 (issue #579 )
把 OpenCode 当作与 Claude Code 同类的 coding agent CLI 接入,照既有 coding_agent
适配模式(不另造架构),复用同一套 CodingAgentRequest / CodingAgentEvent /
CodingAgentError / 审批护栏链路。
后端:
- coding_agent/opencode.rs(新):detect_opencode(opencode --version)、
build_opencode_args(opencode run --format json --model --dir
[--dangerously-skip-permissions],prompt 作为 argv)、parse_opencode_json_line
(NDJSON:text/tool_use/error;text 块累计,EOF 合成 Completed)、
run_opencode_agent(取消/超时 kill,护栏经 OPENCODE_CONFIG_CONTENT 注入)。
- coding_agent/args.rs:CodingAgentProvider 枚举(claude-code-cli/opencode-cli,
未知回落 Claude)+ from_pref/default_exe。
- coding_agent/guard.rs:build_opencode_guard_config —— 把高风险 bash 前缀翻译成
OpenCode permission.bash deny glob + webfetch deny,审批放行的前缀显式 allow。
- coordinator/dictation_voice_agent: run_less_computer_once 按 coding_agent_provider
分派 Claude / OpenCode 运行器;两路都 fail-closed(护栏生成失败即中止,不裸跑)。
审批拦截探测/重跑放行链路 provider 无关,自动复用。
- commands: coding_agent_detect_opencode 命令(已注册 lib.rs)。
前端:
- CodingAgentSection: OpenCode 选项从「即将支持」改为可用 + 选中后探测安装状态并提示。
- ipc: codingAgentDetectOpencode + OpenCodeDetection。
- i18n: opencodeReady / opencodeMissing(5 语言,替换 providerOpenCodeSoon)。
验证:cargo check + cargo test(492 通过)+ npm run build 均通过。
Refs #579
(#579 还含「语音润色模型配置」:prefs 字段已存在但全链路未实现/未接 UI,
转写直接进 agent 未经语音润色模型整理 —— 故用 Refs 不用 Closes。)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
* fix(coding-agent): OpenCode 防参数注入 + 可配置 Agent 可执行文件路径 (#638 )
注入风险(@H-Chris233 评审):`opencode run` 的 prompt 作为最后位置参数,但之前缺
end-of-options 分隔。以 `-` / `--` 开头的 prompt(语音转写或被 prompt 注入诱导)会被
OpenCode 当作 flag 解析,可绕过护栏(混入 --dangerously-skip-permissions、--dir 改写
工作目录等)。修复:build_opencode_args 末尾追加 `--`,运行器把 prompt 接在其后;新增单测。
可配置路径(@PR-Agent 指出之前 hardcode "opencode"):新增 prefs.coding_agent_exe,
语音 Agent 路径据此取 exe(留空回退默认 claude / opencode),检测命令亦用配置路径;
设置「高级 → Less Computer」新增「可执行文件路径」输入;补 5 语言 i18n。
* fix(updater): 安装失败可见化 + 手动下载兜底 + 错误写日志 (#706 )
下载完成后若 install() 抛错,旧代码把 status 置成 'error',而 UpdateDialog 不渲染 error 态 → 弹框消失、错误只 console.error,用户表现为「下载后无反应、重启仍旧版」(#706 )。
- 新增独立状态 installError:仅下载/安装失败用它;'error' 仍表示「检查失败」,行为不变(CheckUpdateButton 按钮内轻提示、后台自动检查都不弹框,零回归)。
- 失败弹框留在原地显示真实错误 + 「手动下载」按钮直达 GitHub Releases 兜底。
- 新增 Rust IPC log_client_error,把前端更新错误写进 openless.log(webview console 不入文件日志),便于用户「导出日志」后定位真因。
- 5 个 i18n 文件补 updateDialog.installError / manualDownload。
注意:这是兜底(失败可见 + 可诊断),不解决 ad-hoc/quarantine 机器自动更新真正成功的问题——那需要 Apple Developer ID 签名 + 公证(本次暂缓)。
* 手动补:dictation/ipc 拆分后的 OpenCode + updater 改动迁移
* fix: AutoUpdate 兼容性修复(补回 CheckUpdateOptions + Android 参数类型)
* fix(audio-cue): 重建/唤醒退化的 AudioContext,修「用久了提示音消失」
长时间使用后「开始录音」提示音与设置页「试听」双双静音,且重启才恢复。
根因在 audioCue.ts 的 AudioContext 单例 sharedCtx 从不检查/恢复运行期状态:
- WKWebView/WebView2 在频繁录音抢占音频会话后,ctx 可能转入 WebKit 非标准的
`interrupted` 态。旧代码只判断 `suspended`,interrupted 被当作可直接排期 →
排到非 running 的 ctx 上,无声且不尝试 resume → 永久静默(macOS 最可能根因)。
- ctx 也可能被系统 `closed`。closed 无法复活(resume 必拒、createOscillator 必抛、
被 catch 静默吞掉),而 getContext 从不重建 → 永久静默。
- 胶囊窗口与设置窗口各持一份 ctx,都会这样退化 → 两处提示音同时失效。
修复:
- 新增纯函数 audioContextActionForState(state):closed→recreate / running→ready /
其余(suspended/interrupted/未知非运行态)→resume,单一真相、可单测。
- getContext 在 ctx 为 closed 时丢弃重建(并清空挂在旧 ctx 上的 activeVoices)。
- playRecordStartCue / primeAudioCue 改用该分类器,把 interrupted 一并按 resume 唤醒。
公共 API 签名不变,仅 AudioCue.tsx / RecordingInputSection.tsx 复用,行为向后兼容。
tsc --noEmit 通过;audioCue.test.ts 新增 5 条状态分类断言,全部通过。
* fix(macos): onboarding Accessibility authorization page stuck (#703 follow-up)
Root cause: permissions::request_accessibility() was called in setup(),
which runs BEFORE the AppKit event loop is live. On some macOS versions,
AXIsProcessTrustedWithOptions depends on the run loop for XPC to tccd.
When the event loop isn't ready, TCC may not show the dialog but still
consumes the one-time prompt. Later calls from the onboarding page's
'grant accessibility' button silently return Denied, trapping users on
the onboarding page. Recovery requires System Settings grant + app
restart, but users had no clear restart action — only a text hint.
Changes:
- lib.rs: Remove setup() TCC prompt. The prompt is now exclusively
triggered by user action on the onboarding page, aligning with
Apple HIG (explain why → then prompt).
- Onboarding.tsx:
* onGrantAccessibility now checks the TCC result: skip
openSystemSettings when already granted (previously always opened)
* New tccPromptShown state distinguishes 'never attempted' vs
'already denied' for correct button labels
* Denied state now shows a prominent 'Restart OpenLess' button
calling restartApp()
- PermissionsSection.tsx: Same fix for settings page accessibility
row — check TCC result, guide to System Settings when denied,
show 'Restart App' button
- i18n: Add onboarding.actionRestart + settings.permissions.restart
for zh-CN / zh-TW / en / ja / ko
Closes: macos-onboarding-accessibility-stuck
* chore(release): publish 1.3.13
* fix(audio-cue): recover when resume() is rejected or wakes non-running
Long sessions park the shared AudioContext in 'suspended' / WebKit
'interrupted' after the system audio session is repeatedly preempted by
ASR and recording. The earlier fix only recreated a 'closed' context: a
rejected resume() was swallowed and a resume() that resolved without
reaching 'running' scheduled voices on a frozen currentTime, both of
which leave the start cue permanently silent until the app restarts.
Treat both "won't wake" states as recoverable — discard the dead context
and retry once on a fresh one, bounded to avoid infinite recreation. The
decision is extracted into the pure, unit-tested cueActionAfterResume.
* chore(release): integrate 1.3.14
* fix(ipc): 去除 coding-agent.ts/index.ts 中 OpenCodeDetection 和 codingAgentDetectOpencode 的重复声明
integrate/cloud-sync-20260621 合并后 IPC barrel 出现重复 export(beta 已含 PR #638 的
OpenCode 适配器,integrate 分支又加了一份)。合并去重,npm build 通过。
* style(less-computer): 气泡/审批/发送按钮改用 accent 主题 token
把 LessComputerPanel 里三处硬编码渐变(#3d6bff→#7a55f2)替换为
--ol-accent-solid-bg / --ol-accent-solid-ink,跟随浅/深主题。
* feat(capsule/asr/ui): 胶囊即时显示与预测展开、Apple 语音修复、弹窗全局遮罩
胶囊入场(延迟出现 / 无入场动画 / 亮起→卡→展开):
- 按下热键即「乐观显示」胶囊并播入场动画,不等麦克风就绪;level_handler 首帧 PCM
到达后从预备态翻正式态、光条点亮(新增 warming 标志贯穿 emit_capsule payload)
- 修入场动画被吞:入场帧把发给前端的事件挪到 window.show 之后再 emit
- 预测式展开:光条按历史平均加载时长(EMA + localStorage 跨会话学习)从按下就平滑
展开,就绪早则加速补满、未就绪则慢爬至 90%,消除「亮起→卡→突然展开」
Apple 语音(说中文识别成英文 / 偶发不可用):
- initWithLocale 跟随用户工作语言主语言,修 init 无参落系统首选语言(英文)导致
中文被英文引擎误识别
- on-device 优先(requiresOnDeviceRecognition):离线可用 + 隐私 + 不受网络波动/限流
- isAvailable 就绪轮询等待,修刚 init 时瞬时不可用就报错的竞态
弹窗遮罩:Modal 用 createPortal 到 body,修被 WindowChrome/FloatingShell 常驻
will-change: transform 祖先困住 fixed 遮罩(登录弹窗浮在亮着的设置页上、无全局压暗)
服务页 Apple 语音文案优化(zh-CN/zh-TW)
---------
Co-authored-by: 吕柏青 <lubaiqing9@gmail.com >
Co-authored-by: sim <sim@local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com >
2026-07-04 23:41:41 +08:00
Duyi-Wang
28a52e949b
feat(llm): add custom provider extra headers
...
Add support for custom LLM provider extra HTTP headers stored in credentials, with validation that prevents overriding protocol-critical headers.
2026-06-27 17:06:13 +08:00
katanumahotori and Claude Opus 4.8
bafddd4a91
fix(history): fall back to raw transcript when polished text is empty + copy button on raw panel ( #752 )
...
When polishing returns an empty finalText (errorCode stays null), the History
"Copy" button copied an empty string, so the raw transcript that is still
visible in the UI could not be recovered. Re-transcribe does not apply here
(ASR succeeded; polish is what failed).
- onCopy: fall back to rawTranscript when finalText is blank
- raw panel: add a dedicated copy button (shown only when rawTranscript exists)
- reuse existing common.copy / common.copied, no new i18n; frontend-only
Complements #653 (polish identical to raw); independent of the in-progress
history re-polish work (#666/#694). No backend/IPC changes.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com >
2026-06-27 14:08:44 +08:00
jmr
1df2838604
NO AI SLOP PLEASE
...
AI SLOP 会导致项目产生大量垃圾内容 且在此workflow被跳过的情况下无法正常merge pr
2026-06-27 14:05:38 +08:00
sim
de8b6e3bd8
fix(release): skip beta Windows MSI
2026-06-25 15:32:28 +08:00
sim
8d74b3e0eb
chore(release): prepare 1.3.13-Beta.1
2026-06-25 14:59:31 +08:00
浩彬(^-^)
ee0f746324
feat(windows): add SendInput insertion and keyboard list controls
...
Merge PR #740 after review and full CI. This supersedes PR #734 by including its SendInput insertion mode work plus the keyboard-list visibility preference for #738 .
2026-06-25 13:51:11 +08:00
浩彬(^-^)
fa09eaf605
feat(hotkey): support side-specific modifier combos
...
Add side-aware combo detection for dictation on macOS/Windows, shortcut recording support for side-specific modifiers, overlap validation, and tests.
2026-06-25 13:41:28 +08:00
NarwhalChen
346942e1bb
style(ui): improve dark theme polish
...
Rework dark theme tokens, replace hardcoded dark-mode colors with theme variables, and remove the redundant overview metrics wrapper border.
2026-06-25 13:41:06 +08:00
Yu Peng Zheng
c10ef381cb
fix(ui): clean up late Tauri listener subscriptions
...
Immediately unsubscribe Tauri listeners if their async listen() call resolves after component unmount, preventing leaked handlers in AudioCue and Linux window chrome.
2026-06-25 13:39:58 +08:00
TRIP
b4636f9620
fix(audio-cue): recover degraded AudioContext
...
Recreate closed AudioContext instances and resume interrupted/suspended contexts before scheduling generated record-start cues. Includes state classification tests.
2026-06-25 13:39:10 +08:00
TRIP
124a49ca05
fix(macos): recover stuck Accessibility onboarding
...
Fix macOS Accessibility onboarding getting stuck after TCC prompt/identity drift. Request permission only from onboarding, add targeted Accessibility TCC reset + restart recovery, and mirror the flow in settings.
2026-06-25 13:38:52 +08:00
sim
8563e707ba
[cask] openless 1.3.12 (auto from release) [skip ci]
2026-06-24 13:56:50 +08:00
sim
a4df800d66
chore(release): publish 1.3.12
...
- add OpenCode CLI provider support for voice agent workflows
- improve updater fallback/error visibility and compatibility
- bump app, Tauri, and Cargo versions to 1.3.12
2026-06-24 12:42:25 +08:00
e1c1be2942
feat(coding-agent): OpenCode CLI 适配器,语音 Agent 可选 OpenCode 后端 (Refs #579 ) ( #638 )
...
* feat(coding-agent): OpenCode CLI 适配器,语音 Agent 可选 OpenCode 后端 (issue #579 )
把 OpenCode 当作与 Claude Code 同类的 coding agent CLI 接入,照既有 coding_agent
适配模式(不另造架构),复用同一套 CodingAgentRequest / CodingAgentEvent /
CodingAgentError / 审批护栏链路。
后端:
- coding_agent/opencode.rs(新):detect_opencode(opencode --version)、
build_opencode_args(opencode run --format json --model --dir
[--dangerously-skip-permissions],prompt 作为 argv)、parse_opencode_json_line
(NDJSON:text/tool_use/error;text 块累计,EOF 合成 Completed)、
run_opencode_agent(取消/超时 kill,护栏经 OPENCODE_CONFIG_CONTENT 注入)。
- coding_agent/args.rs:CodingAgentProvider 枚举(claude-code-cli/opencode-cli,
未知回落 Claude)+ from_pref/default_exe。
- coding_agent/guard.rs:build_opencode_guard_config —— 把高风险 bash 前缀翻译成
OpenCode permission.bash deny glob + webfetch deny,审批放行的前缀显式 allow。
- coordinator/dictation_voice_agent: run_less_computer_once 按 coding_agent_provider
分派 Claude / OpenCode 运行器;两路都 fail-closed(护栏生成失败即中止,不裸跑)。
审批拦截探测/重跑放行链路 provider 无关,自动复用。
- commands: coding_agent_detect_opencode 命令(已注册 lib.rs)。
前端:
- CodingAgentSection: OpenCode 选项从「即将支持」改为可用 + 选中后探测安装状态并提示。
- ipc: codingAgentDetectOpencode + OpenCodeDetection。
- i18n: opencodeReady / opencodeMissing(5 语言,替换 providerOpenCodeSoon)。
验证:cargo check + cargo test(492 通过)+ npm run build 均通过。
Refs #579
(#579 还含「语音润色模型配置」:prefs 字段已存在但全链路未实现/未接 UI,
转写直接进 agent 未经语音润色模型整理 —— 故用 Refs 不用 Closes。)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
* fix(coding-agent): OpenCode 防参数注入 + 可配置 Agent 可执行文件路径 (#638 )
注入风险(@H-Chris233 评审):`opencode run` 的 prompt 作为最后位置参数,但之前缺
end-of-options 分隔。以 `-` / `--` 开头的 prompt(语音转写或被 prompt 注入诱导)会被
OpenCode 当作 flag 解析,可绕过护栏(混入 --dangerously-skip-permissions、--dir 改写
工作目录等)。修复:build_opencode_args 末尾追加 `--`,运行器把 prompt 接在其后;新增单测。
可配置路径(@PR-Agent 指出之前 hardcode "opencode"):新增 prefs.coding_agent_exe,
语音 Agent 路径据此取 exe(留空回退默认 claude / opencode),检测命令亦用配置路径;
设置「高级 → Less Computer」新增「可执行文件路径」输入;补 5 语言 i18n。
---------
Co-authored-by: 吕柏青 <lubaiqing9@gmail.com >
Co-authored-by: Claude Fable 5 <noreply@anthropic.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-06-24 12:30:12 +08:00
Haoqian
0881338e2e
fix(asr): route Apple Speech dictation locally ( #741 )
2026-06-24 12:29:54 +08:00
jmr
95920a6b41
Merge pull request #729 from Open-Less/fix/issue-643-traditional-chinese-output
...
fix(ime): 繁中用户语音输入始终输出繁体 / enforce 简繁 script on output (#643 )
2026-06-21 20:57:47 +08:00
Andy Jiang
48e190be20
fix(ime): always enforce 简/繁 script preference on dictation output ( #643 )
...
Traditional-Chinese users got Simplified output. finalize_polished_text only ran
the deterministic OpenCC conversion for Raw mode / polish failures, leaving
successful polish modes to the LLM — which defaults to Simplified for Chinese.
The streaming-insert path bypassed the conversion entirely.
- finalize_polished_text: for non-translation dictation, always apply
apply_chinese_script_preference. It is a no-op for ChineseScriptPreference::Auto
(the default), so zero impact on users who didn't pick a script; for Simplified/
Traditional it now guarantees the output script instead of trusting the LLM.
- streaming_insert_eligible: gains the script preference and disables streaming
insert when it is non-Auto, so the one-shot path runs (streaming types live and
has no finished text to post-process).
Tests: polish_output_honors_chinese_script_preference (S2t actually converts;
Auto is a no-op) + streaming_disabled_for_non_auto_script_so_opencc_runs. 470 lib
tests pass.
Closes #643
2026-06-21 19:22:46 +08:00
github-actions[bot]
e55ac03fa2
[cask] openless 1.3.11 (auto from release) [skip ci]
2026-06-21 06:49:44 +00:00
Andy Jiang
950ad58006
chore(release): 1.3.11
2026-06-21 13:55:15 +08:00
Andy Jiang
65361606f7
feat(dictation): failure-resilience, record-next queue, manual re-transcribe
...
- preserve audio on ASR failure + auto silent retry: always-archive recordings
(delete on success unless debug), route all engine failure arms through a single
fail_dictation -> recoverable transcribeFailed history; auto-retry re-feeds the
archived WAV via retranscribe_pcm; fix empty-transcript id mismatch (#613 )
- hotkey: queue-chain -- a press buffered during processing auto-starts the next
recording (grace window distinguishes it from the #545 post-session cooldown)
- history: wire the manual re-transcribe button for transcribeFailed/emptyTranscript
entries with audio
Rebased onto beta 1.3.10; my capsule multi-monitor fix dropped (superseded by #714 ).
2026-06-21 13:53:56 +08:00
Chris233
b07f78bc1d
Merge pull request #723 from H-Chris233/fix/whisper-dynamic-timeout-721
...
fix(asr): Whisper/OpenRouter 动态超时 + 全局兜底 15→30s
2026-06-21 13:26:07 +08:00
Chris233
e1f24b61a4
test: 修复 local_qwen_timeout 测试 + 新增 whisper_transcribe_timeout 测试
...
- local_qwen_timeout_ceils_partial_seconds: 10.1s 音频原期望 17s,全局常量
提升到 30s 后改为期望 COORDINATOR_GLOBAL_TIMEOUT_SECS
- 更新相关注释中的 15→30
- 新增 3 个 whisper_transcribe_timeout 测试:短音频兜底、长音频缩放、ceil
2026-06-21 12:50:41 +08:00