Chris233
c8bd7aa295
fix(foundry): keep local ASR warm and stream transcripts ( #1052 )
...
* fix(foundry): keep local ASR warm and stream transcripts
* fix(foundry): cancel stale release schedules
2026-09-13 12:28:41 +08:00
82357e8df3
fix(android): 对齐应用内更新 minisign 并修复凭据 vault ( #1061 )
...
* fix(android): parse Tauri-wrapped minisign keys so in-app APK install can open
Android updater called PublicKey::from_base64 on the wrapped tauri.conf pubkey, so install died before installApk. Also keep vault envelope failures from looking like an unconfigured Volcengine ASR provider.
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(linux-egui): 补齐根证书指纹字段并让 fcitx5 门禁匹配实际安装调用
Release Linux egui 在 beta 上因 RemoteInputStatus 缺字段、match 臂类型不一致,以及门禁要求 ensure_fcitx5_ready(?) 而失败;安装调用本身已在监听器之前,错误会展示在 UI 里。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): Keystore 暂时不可用时不要让 Tauri setup abort
Core.start() 会走 configuration_snapshot → load_credentials_for_update;信封读失败若返回 Err,setup hook 直接 SIGABRT。改为记录 last_read_error 并返回未缓存默认值,应用可以启动。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 凭据信封暂时读失败时不要挡住 2.0 启动握手
Core.start() 在 setup 成功后还会被 event bridge 和 get_startup_snapshot 再调一次;此时 last_read_error 已记下,require_readable_vault 把 Persistence 抛成「暂时无法启动」。握手改为降级空凭据状态继续运行。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 创建渠道时重试 Keystore,失败不覆盖空信封
启动时信封暂时读失败后,require_readable_vault 会在真正 load 之前短路,导致添加提供商一直操作失败。改为每次读写都重试 Keystore;读失败返回 Persistence 且不缓存/不写入默认空根;前端展示后端具体错误。
Co-authored-by: Cursor <cursoragent@cursor.com >
* debug(android): 把 Keystore 暂时不可用的具体异常名带回日志
添加提供商已会重试信封,但 Keystore 仍返回 temporarily unavailable。JNI 原先丢掉 Kotlin 异常与 JNI 失败路径,无法区分 class load、status 3 还是 BackendBusy。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 无法用于 Cipher 的 Keystore 密钥按失效信封恢复
真机 open 稳定抛出 InvalidKeyException(非 UserNotAuthenticated)。继续当成 temporarily unavailable 会让已保存凭据永远读不出来。改为走密钥缺失路径,删除无法解密的信封后可以重新配置提供商。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 凭据 Keystore 写入改走主线程并换用 v3 别名
清掉失效信封后,增加提供商仍在 seal 上失败(ProviderException/KeyStoreException)。HyperOS 上 Keystore2 从 JNI 后台线程调用常失败;改为主线程执行,并换用未损坏的 v3 别名,失败时删除别名再生成一次。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): KeyMint AES-GCM 失败时回退到应用私有软件密钥
HyperOS 上 seal 稳定返回 KeyStoreException 10,主线程与 v3 别名仍无法写信封。Keystore 不可用时改用 UID 私有软件 AES-GCM,避免增加提供商失败。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): preserve credentials across key fallback
---------
Co-authored-by: Cursor <cursoragent@cursor.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-09-13 01:58:26 +08:00
sim
4ec44b2b0b
merge: 汇入 origin/beta 第二轮(#1048 根证书指纹核验、#1049 录音保亮屏)
...
- 五语 PC/手机页文案取云端指纹核验版;de/es/fr 全套补译(指纹 6 键、保亮屏 4 键、恢复 4 键、中断/离线 2 键)
- index.html:帮助块改为指纹核验流程 + 录音屏新增保亮屏开关(默认开)
- RemoteInputStatus 补 caFingerprintSha256;Linux egui 面板移植指纹显示与复制
- remote-input-audio-queue 测试取云端(#1049 音频队列改造),我方仅格式差异
2026-09-10 17:16:58 +08:00
sim
3ff3df1626
fix(merge): 落实合并后的契约与目录对齐
...
- build-mac.sh 移除 hdiutil DMG 兜底:bundle contract 测试显式禁止手搓 DMG
绕过签名/公证链路;DMG 缺失即失败(保留 qwen3-asr-rs 剪枝与 BUILD_START_TS
新鲜度校验)
- 红绿灯 y=26 契约:tao 几何下视觉顶距≈y-14,x==y 并不相等(实测左 21.5px)
- 胶囊几何契约同步 typeless 206×57(原 460×128 的 1/5 面积)
- LLM_LABELS 补 tencentTokenHub 静态目录项(ASR_LABELS 已含 tencent-cloud)
2026-09-10 16:54:34 +08:00
zhou zhichao
f39a68a795
修复远程录音息屏丢失并默认保持亮屏 ( #1049 )
2026-09-10 16:01:55 +08:00
sim
bd5656b5fc
build(macos): 构建前清理重复的 qwen3-asr-rs 目录;新鲜度基准改为构建开始时间
...
- 本地混跑 cargo check/test/build 会按 feature 上下文生成多份 qwen3-asr-rs
构建目录,多份 metallib 会让暂存脚本拒绝猜测
- 打包后原始二进制还会被签名触碰,bundle 新鲜度不能与它比,改与本构建
开始时间比
2026-09-10 13:46:19 +08:00
sim
e3f63e97fc
build(macos): 兜底校验加新鲜度——打包失败时旧 bundle 不允许再通过校验
2026-09-10 12:15:03 +08:00
sim
ce43e1b11b
build(macos): DMG 兜底(hdiutil + Applications 替身)并按第一性原则收紧注释
...
- tauri build 退出码非零不再夭折脚本:.app 已生成时用 hdiutil 兜底打包 DMG,
内容含 /Applications 替身,保留拖拽安装
- Cargo.toml Xcode 27 beta 构建注释压缩为一行事实 + 对策
2026-09-10 00:27:19 +08:00
sim
9a88bee5c6
feat(app): polish desktop UI, expand languages and prepare cloud sync
2026-09-09 01:13:16 +08:00
sim
4519f19c92
style(app): 统一前端与平台源码格式
2026-09-08 14:35:28 +08:00
sim
d686406a70
refactor(app): 清理废弃代码并明确模块注释
2026-09-08 14:27:29 +08:00
sim
a6ed77c0d0
feat(ui): 完善设置子页与自定义风格图标
2026-09-08 14:16:24 +08:00
sim
69f454bd68
feat(ui): integrate 2.0 interface and agent work
...
Consolidate the current 2.0 sidebar, overview, settings, vocabulary editing, correction rules page, and first-launch splash with their Core and Tauri adapters. Include the accompanying source and architecture documentation updates.
Validation: npm test (build and 73 discovered test files); cargo test -p openless-core --locked; Core/Linux and Tauri rustfmt checks.
2026-09-08 11:12:05 +08:00
Tearice and tonyzaca7755963
82aa33ffd6
fix(windows-ime): 避免 TSF 预检导致文本重复插入 ( #1021 )
...
Co-authored-by: tonyzaca7755963 <tonyzaca7755963@users.noreply.github.com >
2026-09-07 08:29:07 +08:00
fd632c2fc7
fix(windows): 粘贴模式下也可隐藏键盘列表中的 OpenLess ( #1015 ) ( #1017 )
...
* fix(windows): allow hiding OpenLess from keyboard list in paste mode
Extend the keyboard-list visibility toggle and desired-profile logic from
SendInput-only to all non-TSF insertion modes so clipboard paste can hide
OpenLess without blocking TSF when switched back.
Refs: #1015
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(macos): 把 mlx.metallib 放到 Resources,避免 ad-hoc codesign 失败
Contents/MacOS 里的非 Mach-O 会被当成 nested code;克隆仓没有 Developer ID 时 identity '-' 会直接 bundle 失败。metallib 改为 Contents/Resources,worker 启动时调用 MLX set_metallib_path。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(ci): dispatch 时按版本号跳过 Windows MSI,避免 Beta.N 被 WiX 拒绝
workflow_dispatch 的 ref 不是 tag,OPENLESS_RELEASE_CHANNEL 会落成 stable,但 app 版本仍是 1.3.18-Beta.7。WiX 要求 prerelease 只能是数字,MSI 直接失败。版本带 Beta/Alpha/RC 时与 beta 渠道一样跳过 MSI。
Co-authored-by: Cursor <cursoragent@cursor.com >
* ci(linux): test core without egui host
---------
Co-authored-by: Cursor <cursoragent@cursor.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-09-06 23:37:56 +08:00
Chris233
fc38edd1a3
refactor: consolidate Core 2.0 and restore cross-platform behavior ( #1019 )
...
* refactor: split Linux egui host from shared backend
* fix: keep CI contracts portable across runners
* fix(ci): preserve CRLF while removing qwen dependency
* fix(ci): regenerate target lockfile and install ripgrep
* fix(ci): gate desktop-only selection voice module
* ci: limit native build parallelism on cross-platform runners
* fix(host): expose blocking task seam to coordinator
* fix(settings): avoid macOS default hotkey collision
* docs: record cross-platform CI evidence
* ci: expose Linux validation package artifact
* ci: grant reusable Linux package permissions
* refactor: remove legacy coordinator dictation facade
* ci: skip unsupported MSI prerelease builds
* ci: install minisign only for signed Linux releases
* fix: keep test-only coordinator session helper
* refactor: move style preview diagnostics into core
* fix: import shared preferences type from core
* refactor: centralize enabled vocabulary projection
* ci: install ripgrep for Linux package gates
* test: make source contract line-ending agnostic
* fix: keep Linux desktop entry standards compliant
* docs: expose core style diagnostics contract
* ci: resolve Linux package version in app directory
* refactor: centralize ASR vocabulary priority
* fix: use shared vocabulary note constant
* refactor: keep vocabulary priority inside core
* test: retain starting-stop queue coverage
* ci: scope Linux updater URL to the current repository
* docs: close implementation and artifact evidence
* docs: record final CI artifact evidence
* fix(android): align updater plugin versions
* fix(android): pin updater crate exactly
* refactor(core): remove unused type anchor
* docs: record final artifact runs
* fix(remote-input): preserve beta status fields
* fix(tauri): finish beta host merge
* fix(asr): pass scoped operation to native qwen adapter
* fix(macos): bundle mlx metallib as a resource
* test(remote-input): update status wire contract
* feat: share Less Computer voice flow with Linux
* refactor(core): centralize host-independent runtime policy
* refactor(core): complete 2.0 backend consolidation
* fix(ci): prepare Sherpa after cache restore
* fix(macos): route native model paths through Core store
* fix(macos): use ModelStore catalog API
* fix(ci): serialize macOS native test build
* test(ci): preserve macOS cargo diagnostics
* fix(macos): release input source lock before await
* test(core): replace legacy hotkey injection gate
* test(core): move Codex sandbox contract into Core
* fix(core): close final runtime policy gaps
* fix(windows): terminate coding agent process trees
* fix(core): complete local model migration
* fix(credentials): align Core LLM model account
* fix(core): restore 1.x parity across shared backend
* fix(android): complete shared backend stubs
* fix: close cross-platform migration review gaps
* fix: complete migration lifecycles and platform compatibility
* docs: define desktop 2.0 acceptance and Linux handoff
* fix: close desktop parity and session lifecycle gaps
* fix: finish voice lifecycle and desktop feedback parity
* fix: close desktop cancellation and feedback race gaps
* fix: honor proxy settings and reject stale session effects
* fix: dispatch native cleanup on host runtimes and order events
* fix: keep optional recording effects best effort
* fix: close desktop agent model and QA lifecycle gaps
* fix: preserve desktop raw voice and QA turn ownership
* fix: finalize desktop dictation and QA feedback
2026-09-06 18:39:46 +08:00
Jimmy Lee and Chris233
2cf5069846
fix(asr): 修复 macOS MLX 后端闪退与发布资源缺失 ( #999 )
...
* fix/local-qwen-asr-exit: 修复使用本地的qwen3-asr识别闪退的问题 #986
* add mlx error
* 修复github action打包出来的dmg运行本地qwen3-asr-rs时崩溃的问题
* fix(asr): 隔离 macOS MLX worker 并修复发布资源
* fix(asr): 修复 macOS worker 超时与 socket 测试
* fix(asr): scope MLX cancellation to owning operation
* fix(asr): preserve abort semantics on target switch
---------
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-08-26 13:25:11 +08:00
Chris233
58c0ade3ab
fix(windows-ime): make TSF shutdown fully cancelable ( #991 )
...
* fix(windows-ime): make TSF shutdown fully cancelable
Remove the uncancelable named-pipe flush, post owned submit requests to the TSF owner thread, cancel pending edit sessions during shutdown, and keep the DLL loaded while asynchronous edit sessions remain alive.\n\nRelated to #954 .
* fix(windows-ime): handle uncertain submits and startup failures
* fix(windows-ime): keep untrusted responses outcome-unknown
2026-08-25 22:29:50 +08:00
浩彬(^-^) and Cursor
ec33bd5dd2
fix(android): 修复小屏大字号下的设置与风格页面排版 ( #960 ) ( #983 )
...
* fix(android): 修复移动端设置与润色页排版及底栏遮挡 (#960 )
设置弹窗 z-index 低于底栏导致底部控件无法点击;润色风格/市场页与 Android 权限区补齐 mobile 布局。
Co-authored-by: Cursor <cursoragent@cursor.com >
* feat(ui): 通用设置新增易读布局,大字号小屏防溢出换行
新增 stackedRowLayout 偏好与 useLayoutStack;设置外观区可手动开启同行控件换行,覆盖老人机等极限场景。关联 #960。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 安全查询悬浮窗权限,修复 HyperOS canDrawOverlays 闪退
WebView IPC 线程不再直接 JNI 调用 Settings.canDrawOverlays,改走 Kotlin 主线程桥接并捕获异常,避免 Redmi/HyperOS 在权限轮询时崩溃。
Co-authored-by: Cursor <cursoragent@cursor.com >
* feat(ui): 保守排版开关与易读布局 min-width 增强
新增 conservativeLayout 偏好与 ol-conservative-scope 单列满宽规则;易读布局补充 min-width 换行;设置与主要页面支持双开关独立并存。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): can_draw_overlays JNI 生命周期以通过 Android CI 编译
为 env 与 context 绑定同一 lifetime,满足 call_static_bool_with_context_class 的借用约束。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 恢复 AccessibilityService 对 Settings.Secure 的 import
isEnabled 仍使用 Settings.Secure 查询无障碍状态,与 canDrawOverlays 移除的 import 无关。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(ui): 将易读/保守排版开关独立为「布局」区块并置顶
原开关藏在「外观」卡片深处不易发现;现于设置→通用页录音输入下方展示独立「布局」卡片。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(ui): 统一易读与保守排版布局规则
---------
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-08-23 00:22:21 +08:00
b7ac91f0e6
feat(coding-agent): Less Computer 接入 dsh(DeepSeek Harness),自带事件插件补齐流式与工具展示 ( #975 )
...
* fix(coding-agent): 版本号解析认预发布号
dsh 的真实输出是 `0.1.0-rc.6`,而解析器要求严格的三段全数字:它被切成
["0","1","0-rc","6"] 四段,判定失败。用这个判「装没装」的地方就会说它没装。
改成认 `-rc.6` / `+build.7` 这类预发布与构建后缀,并原样保留(用户看到的版本号才是
真的)。同时把排版噪声挡在外面:`(1.2.3)` 取到的是 1.2.3,不是 `1.2.3)`。
单测里的样例串是手抄的,抄错了测试照样绿。所以另加一条 #[ignore] 的 live 测试,直接问
本机四个 CLI 要 --version 输出再喂给解析器——那才是「设置页会不会误报没装」的可信证据。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* fix(coding-agent): 「装没装」改看命令能否跑通,不再依赖版本号解析
上一条修的是解析器,那只是补了一个洞。根子在于判据选错了:
installed: version.is_some() // 解析不出版本号 = 判定没装
版本字符串是这些 CLI 里最容易变的东西——改排版、加后缀、换前缀,对它们都不算 breaking
change,但对「拿版本号当判据」的我们就是。
改成:命令跑通(进程起得来且 exit 0)= 装了;版本号只用来显示,解析不出来最多让界面少
显示一个号码,不会把能用的后端说成没装。三个后端共用一个 probe_cli,顺手删掉了三份
几乎一样的 detect_* 。
单测拿 `echo` 当替身——`echo --version` 会原样打印并 exit 0,正是「跑得通但读不出版本号」
这个形状,且不依赖本机装了哪些 agent CLI。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* feat(dsh): 无头 dsh 后端,自带事件 tap 插件
dsh(DeepSeek Harness)的 headless 只在结束时往 stdout 打一行最终文本——没有 JSON、
没有逐字流、没有工具事件。但这不是它缺数据:它内部的会话事件总线上 assistant/chunk、
tool/call、turn/end 一应俱全,只是 headless 汇总完就丢了。
dsh 是插件栈架构,`--patch` 是官方留给外部叠自己那层的入口。这里挂上一个订阅
session/event 的小插件,把需要的事件规范化成 NDJSON 打到 stderr,stdout 的「只打最终
文本」契约原样不动。挂载不侵入用户的 profile,插件随运行落到临时目录、跑完删掉。
上游耦合被刻意压缩在那个 30 行的 JS 里:它把 dsh 的内部事件翻译成我们自己定义的稳定
形状,上游改字段只需要改 JS,Rust 的解析和单测都不用动。tap 是纯增益——挂不上也只是
少了逐字流和工具展示,最终结果照样从 stdout 拿得到。
prompt 不进 argv:dsh 的启动器不认 `--` 作为选项终止符(实测 `dsh --profile headless
"--version"` 会真的去执行 --version),所以以 `-` 开头的转写会被劫持成 flag。既然本来
就要写 patch 文件,索性用它直接覆盖 runner 的 task 配置,prompt 连进程列表都不会出现
——这点比另外三家都严。
护栏走 DSH_PERMISSION_MODE 三档沙箱,沙箱根 = 子进程工作目录。和 Codex 一样没有逐命令
deny 清单,所以审批卡对它同样不生效,撞墙时如实报错。
模型解析永远返回 None:headless profile 没有 --model,模型由 dsh 自己的 profile 决定,
返回 Some 只会让调用方以为选得动。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* feat(settings): Less Computer 后端下拉加入 dsh
第四项。它的能力面和另外三家不一样,设置页如实反映,不给假开关:
- 模型那一行**整行不显示**,换成一句说明:dsh 的 headless 没有模型开关,模型由它自己的
profile 决定,在这里改不了。给个选不动的下拉比不给更糟。
- 复用 Codex 那条沙箱护栏说明(两家都只有粗粒度档位、都不弹审批卡)。
- 装没装当场检测;可执行文件 placeholder 跟着后端走。
文案 5 语言齐全。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* refactor(dsh): tap 插件抽成独立项目 dsh-jsonl,OpenLess 改消费它的公开 schema
原来这个插件是内嵌在 dsh.rs 里的一段 Rust 字符串,只发我们自己要的 4 类事件、用我们
自己的私有形状。它要开源出去(dsh 缺结构化输出,而上游不收 PR,第三方插件是这个能力
唯一可能存在的形式),于是有了「两份会各自跑偏的代码」这个问题。
解法是保证世界上只有一份这个 JS:
- 源头在 github.com/bigsongeth/dsh-jsonl,发完整的、有文档、有版本的事件词表。
- OpenLess 用 include_str! 内嵌一份逐字副本(vendor/dsh-jsonl.js),带版本标记。
内嵌而不是依赖 npm 包:用户装机即用,不需要网络、不需要 npm i,也不碰用户自己的
dsh profile 配置。
- Rust 侧改成解析那个公开 schema(text.delta / tool.call / turn.end),不再有私有形状。
用不上的事件按 schema 的兼容性约定忽略——上游加新事件不会把我们打挂。
**跨仓库没有任何自动同步**,这点没被消除,只是变便宜了:
- scripts/vendor-dsh-jsonl.sh 把同步变成一条命令
- 单测盯着 vendor 文件的版本标记与 VENDORED_DSH_JSONL_VERSION 一致,防止有人直接手改副本
- 插件报的 schema 大版本与我们支持的不一致时留警告日志(不中止:最终结果始终从 stdout
拿得到,流式展示只是锦上添花)
- 真的对不上时,live::tap_plugin_delivers_streaming_and_tool_events 会红
顺带把「禁止任何 import」的断言放宽成「只准 node: 内置」——公开插件要写文件,用了
node:fs,而 node: 内置不需要 node_modules,不影响从临时目录绝对路径加载。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* test(dsh): 沙箱验收的靶子选错了,它一直是靠运气过的
那条「沙箱挡得住工作目录之外的写入」把靶子放在 $TMPDIR。但 dsh 的 workspace-write 把
可写根写死成 [工作目录, "/tmp", $TMPDIR](见 @deepseek-ai/dsh-sandbox 的 writableRoots)
——往 $TMPDIR 写**本来就是允许的**。
它之前能过,只是因为模型碰巧挑了受限更严的 `write` 工具;这次挑了 `bash`,文件就真的
落下去了。也就是说这条测试的成败取决于模型当次的选择,不取决于沙箱是否失效。
改成打真正的边界(家目录),实测会被拒:
bash: /Users/…: Operation not permitted [sandbox: file access denied under workspace-write mode]
另加一条把 dsh 的既有行为钉成契约:$TMPDIR 可写,且**没有配置项能收掉**——Codex 那边
有 -c sandbox_workspace_write.exclude_* 可以收紧,dsh 没有对应物。哪天 dsh 收紧了这条
会红,那是好消息,届时删掉它并更新文档。
所以对用户的措辞只能是「撞到限制会如实报错」,不能说成「写入限制在工作目录内」。
模块文档里把这个边界写清楚了。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* fix(dsh): 收紧运行协议与权限边界
* fix(dsh): 修复权限与连续对话审查项
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-08-22 00:14:17 +08:00
5ba0fa725c
feat(coding-agent): Less Computer 接入 Codex,语音使唤电脑不再只能用 Claude ( #974 )
...
* fix(coding-agent): 从用户 shell 取真实 PATH,打包后也找得到 CLI
macOS 从 Finder 启动的 GUI 进程拿到的是一份极简 PATH,不经过用户的 shell 配置。
后果是:凡是版本管理器装的 agent CLI 在打包版里一个都找不到——`opencode` 官方脚本
装在 `~/.opencode/bin`,全局 npm 前缀和 nvm 的路径更是带版本号、根本没法硬编码。
用户只能手动去高级设置里填绝对路径。
改成先问用户的 shell 要一份真实 PATH。三个细节是踩出来的,都写进注释了:
- 用 `-lic` 而不是 `-lc`。nvm 这类版本管理器通常在 .zshrc 里初始化,而 .zshrc 只有
交互式 shell 才读;`-lc` 拿到的 PATH 里 nvm 排在 /usr/local/bin 之后,
`#!/usr/bin/env node` 会命中错版本的 node,子进程直接崩。
- 拼接必须保序。逐项前插等于把整个 PATH 倒过来,同样会选错解释器。
- 分隔符交给 std::env::split_paths / join_paths,不能手写 `:`。Windows 用 `;`,
而且盘符自带冒号,手写会把 `C:\Windows` 切成两半、整条 PATH 报废。
shell 卡住有 5 秒硬上限,超时回落到静态目录列表。整段探测限定 unix:Windows 没有
「登录 shell 的 PATH」这个概念,装了 Git Bash 的机器 SHELL 有值,真去跑只会莫名其妙
拉起一个 bash。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* feat(codex): 无头 Codex 适配器
Less Computer 现在只认 Claude Code 和 OpenCode,因为每个后端都得手写一套适配器。
这个是 Codex 的那套,形状和前两家一致,共用同一套请求/事件/错误类型。
- 运行:`codex exec --json`,逐行解析 JSONL。
- prompt 走 stdin(末尾的 `-`),不进 argv,也不会出现在进程列表里。
- 续接用 `resume --last`。参数顺序有坑:`-s` / `--json` 这些必须排在 `resume` 之前,
写反了 CLI 直接报 unexpected argument,已对 0.146.0 核实并写进注释。
- 工具展示会剥掉 `/bin/zsh -lc '…'` 这层 shell 包装,胶囊里显示的是真正执行的命令名。
- 护栏:Codex 给不了逐命令 deny 清单(`.rules` 只从 $CODEX_HOME / 项目目录读,实测
`-c rules=[…]` 会被静默忽略)。它的护栏是自带的 seatbelt 沙箱,走 `-s <mode>`。
额外关掉 workspace-write 对 /tmp 与 $TMPDIR 的默认放行——不关的话「写入限制在工作
目录内」就是句假话,实测任务真的能在 $TMPDIR 里落文件。
有一处刻意不做:Codex 会把「模型元数据没找到」这类警告也塞成 error 事件,本机每次运行
都会发一条。把它当终局失败会让所有运行都被误判,所以只认 turn.failed。
联机验收默认 #[ignore],其中一条不调模型不花钱:它比对加固前后实际生效的可写根,
盯住护栏别被上游无声改宽(codex 对未知 -c 键是静默接受的,改名了不会报错)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* feat(coding-agent): Less Computer 可选 Codex 后端,审批卡按能力启用
把 Codex 接进语音链路,后端从两家变三家。
护栏这块两类后端不一样,代码里如实分开:Claude / OpenCode 有逐命令 deny 清单,撞了能
弹审批卡、批准后放行那一条重跑;Codex 只有粗粒度沙箱档位,唯一的「放行」办法是整体
降档,那等于把护栏关掉,不是放行这一条。
所以给 provider 加了一个能力位,只有支持逐命令放行的后端才弹审批卡。否则用户点了批准、
重跑还是同样被拦,那是个假承诺。撞墙时直接把失败如实报出去。
模型解析也按后端分开:Codex 收裸模型名(gpt-5 / o3 这种),留空交给它自己的
~/.codex/config.toml,不替用户瞎猜一个默认。
另加一个通用的安装检测命令:选了后端却没装 CLI 时,在设置页当场看到,而不是等说完
一句话才发现跑不起来。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* feat(settings): Less Computer 后端下拉加入 Codex
设置页的后端下拉从两项变三项,并且如实反映能力差异,不给假开关:
- 模型:Claude 用别名下拉,OpenCode 拉账号可用列表,Codex 改成自由文本——它的模型名
是裸名(gpt-5 / 自建网关的任意名字),枚举不过来;留空 = 用 Codex 自己的默认。
- 护栏:选了 Codex 会挂一条说明,讲清楚它只有粗粒度沙箱、撞到限制会直接报错而不是弹
「批准这条命令」的卡片。免得用户按 Claude 的心智去用。
- 装没装:当场检测并提示,没装时按警示色显示。
- 可执行文件的 placeholder 跟着后端走。
文案 5 语言齐全。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* fix(coding-agent): harden Codex execution
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-08-21 22:07:10 +08:00
Chris233
cb3d3f8a3a
fix(local-asr): preserve child state across refreshes
2026-08-21 20:07:30 +08:00
sim
3d2811dcae
fix(release): link Apple compiler runtime for MLX
2026-08-21 14:49:55 +08:00
sim
1933a283c6
chore(release): prepare 1.3.18-Beta.5
2026-08-21 14:24:56 +08:00
Jimmy Lee and Chris233
42c1b31754
本地模型增加whisper相关模型的支持; 增加qwen3-asr的rust版本, 相比C版本速度更快 ( #940 )
...
* feat: add selectable local ASR backends
* fix(build): 修复本地 ASR 多平台构建与旧渠道兼容
* fix(asr): 修复 MLX 权重跨线程 stream 错误
* fix(ci): exclude MLX Qwen3 from non-macOS jobs
* fix(ci): use app-relative ASR submodule path
* fix(android): skip qwen-asr C backend
* fix(android): guard qwen-asr by target triple
* fix(ci): 修正语法错误
* fix(ci): remove invalid checkout step options
* fix(asr): harden local backend integration
* fix(asr): 处理 PR #940 审查发现(9 项)
- strip: 全局保留 symbols,macOS release profile 单独退回 debuginfo(Homebrew rustc 的 LINKEDIT 问题仅限 macOS)
- 转录超时改为驱逐引擎而非无效 cancel():spawn_blocking 解码任务无法被中止,驱逐后下次会话加载新引擎而非排队
- Turbo/Q5 共享目录模型在 is_downloaded/downloaded_bytes/delete_model 上互相认账
- MLX 临时 WAV 用 RAII guard 兜底清理;HF tree API 改 Link rel=next 游标分页(offset 被服务器静默忽略),带防御上限与 5 个单测
- Intel Mac 渠道下拉不再闪现 MLX 预设;MetalToolchainGuide 默认折叠并标注仅源码构建期要求
- qwen3-asr-rs 子模块 URL 与 gitlink 指向 Open-Less org 镜像,嵌套 mlx-c 同步改指 org(供应链 N-6)
- README/注释补充:所有平台源码构建均需递归初始化子模块(path 依赖跨 target 解析)
* fix: harden local whisper model lifecycle and downloads
* fix(asr): address PR 940 review findings
* fix(ci): add local ASR model stub to backend tests
* fix(linux): bundle and sync fcitx5 selection plugin
* fix(macos): avoid duplicate whisper test module
* fix(history): make detail sibling keys unique
* fix(ci): stub macos whisper model constant
* test(ci): avoid macOS streaming timeout race
---------
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-08-20 20:22:02 +08:00
Chris233
fac8ddc685
fix(ui): 修复模型选择刷新闪烁 ( #970 )
...
* fix(ui): 修复模型选择刷新闪烁 (#958 )
* test(polish): 放宽流式首字测试时序裕量
* fix(ui): ignore stale LocalAsr refresh results
2026-08-20 19:03:01 +08:00
bigsong and Claude Opus 5
ec5ea4b07a
fix(vocab-card): 收起添加词卡片后,胶囊要回到屏幕中间 ( #969 )
...
* fix(vocab-card): 收起卡片时把胶囊的位置也还回去
卡片和录音胶囊是同一个窗口。弹卡片要把窗口挪到右下角,收卡片时
`hide_vocab_suggestion_card` 还了尺寸、还了鼠标穿透,唯独没还位置 ——
于是下一次录音,胶囊出现在右下角。
漏这一步之所以致命,是因为 `maybe_position_capsule_bottom_center` 有个
去重缓存,而那个缓存只记「显示器 + 翻译态」。卡片这一挪它一无所知,
下次录音时拿到相同的显示器快照就判定「没变化」,直接跳过重新定位。
换句话说:窗口被挪走了,而唯一会把它挪回来的那段代码以为自己不用动。
所以复位和清缓存两件事都做,各堵一个方向:清缓存保证「就算这次复位
失败,下一次 emit_capsule 也一定会重算」;复位保证「就算有哪条路径
绕过 emit_capsule 直接 show,窗口也已经在对的地方」。
顺带把同一形状的另一处堵上:卡片直接调 set_ignore_cursor_events,却没
同步 `capsule_cursor_passthrough` 那个缓存。目前触发不了,但一旦缓存和
窗口真实状态分家,emit_capsule 就会跳过它该调的那一次 —— 表现是经典
胶囊上的 ✓/✕ 点不动。
复位顺序改成先 hide 再改几何:尺寸和位置要一起动,窗口还亮着时改就有
概率被合成出一帧「卡片被拉宽、还横着飞过半个屏幕」。
真机量过(临时脚手架 + CGWindowList 取窗口 frame,外接屏 1920x1080):
修复前 录音 → x=453(居中)→ 卡片 x=1299(右下)→ 收卡片后窗口
仍在 x=1299 → 下一次录音胶囊 x=1299 ← bug
修复后 录音 → x=526(居中)→ 卡片 x=1168(右下)→ 收卡片当场回到
x=453(居中)→ 下一次录音胶囊 x=453 ← 对
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
(cherry picked from commit d3fedcd13da0a3ba002a6f29dda330eeabee62f1)
* test(capsule): 把「卡片借走胶囊窗口必须完整归还」钉成契约
上一条修复(收起卡片时把胶囊位置也还回去)在 8 月丢过一次 —— 它只活在
一个没合并的本地分支上,主线从 PR #917 重新长出了漏还位置的版本,于是
真机 bug 原样复发:用过一次带添加词的卡片,下一次录音的胶囊就出现在
右下角,再也回不到底部居中。
这类不变量单测抓不到:整段是 Tauri 窗口调用,跑在 run_on_main_thread 的
闭包里,没有窗口就没有断言对象。所以按 repo 既有的做法收进
macos-capsule-spaces-contract —— 那个文件已经是「胶囊窗口几何」这类
源码级不变量的归属地(多屏定位缓存那条就在里面)。
守两侧四个函数(词条卡片 + 落字回退卡片):
弹卡片:挪走了共享窗口,就必须让 capsule_layout 去重缓存当场作废,
并同步 capsule_cursor_passthrough
收卡片:穿透、尺寸、位置、两个缓存,一样都不能少;且必须先 hide
再改几何(否则复原会被合成出一帧横飞过半个屏幕的动画)
「还位置」和「清缓存」分开断言是有意的:这两件事各堵一个方向,漏任何
一个 bug 都会回来,所以要能各自报出自己的名字。
验证(三态):
未修复的 coordinator.rs(HEAD~1) → 红,报 show_vocab_suggestion_card
缺 capsule_layout 失效
变异:只删掉 hide_vocab 里那一行
position_capsule_bottom_center → 红,且精确报出「restoring size
alone leaves it in the card's
bottom-right corner」
修复后 → 绿;npm test 全量退出码 0
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com >
2026-08-19 23:30:48 +08:00
789c82051e
fix(history): 详情面板同层 key 去重,切换条目不再残留「播放录音」按钮 ( #964 )
...
* fix(history): 详情面板同层 key 去重,切换条目不再残留「播放录音」按钮
详情面板里 AudioRecordingPlayer 和 RepolishPanel 是同一层的兄弟节点,两个都用
裸 `item.id` 当 key。同层重复 key 下 React 只打警告(Encountered two children
with the same key)不报错,但 reconcile 匹配不上旧 fiber,旧的播放器节点删不掉:
每切换一次历史条目就在 DOM 里多留一个「播放录音」按钮,一直开着不关的窗口能叠出
一整列,把下面的流水线信息挤走。
改成 `audio-${item.id}` / `repolish-${item.id}`,key 仍随条目 id 变化(切换条目
时照旧重挂载、重置播放与润色状态),但同层不再撞车。
另加契约测试 scripts/history-detail-sibling-keys.test.mjs:扫详情面板里所有
key 表达式,断言互不相同且都带 item.id,后续再往这层加带 key 的兄弟组件会被拦下。
复现与验证(浏览器 dev,mock 条目打开 hasAudioRecording):
- 修复前:连续切换 12 次条目 → 播放按钮 1→12,控制台每次都刷重复 key 警告
- 修复后:同样切换 12 次 → 播放按钮恒为 1,重复 key 警告 0 条
- npm test(tsc + vite build + 全部前端测试)exit=0
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
* test(history): validate sibling keys at runtime
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-08-19 01:08:15 +08:00
Chris233
f008cc6f05
fix(windows): allow synthetic hotkeys to trigger OpenLess ( #948 )
2026-08-14 22:04:47 +08:00
King and Chris233
c84bfb98f3
chore(ci): optimize CI caching, concurrency, and Tauri security ( #937 )
...
* ci: optimize CI caching, concurrency, and Tauri security
Address multiple CI/CD efficiency and security gaps identified during
project optimization analysis. The changes reduce PR build times,
prevent wasteful concurrent runs, tighten the Tauri security boundary,
and eliminate unnecessary submodule fetches on non-macOS jobs.
CI workflow improvements:
- Add swatinem/rust-cache@v2 to both ci.yml jobs (android-check and
cross-platform), matching the caching already present in
release-tauri.yml. This converts PR Rust compilation from full
rebuilds to incremental builds, saving an estimated 60-80% of
compile time per run.
- Add concurrency groups to all three workflows. PR pushes cancel
superseded runs to free concurrency slots; tag pushes and manual
dispatches are isolated by run_id to avoid mutually canceling
release builds. Previously, rapid PR pushes triggered redundant
parallel CI runs with no cancellation.
- Unify Node version to 22 across release-tauri.yml and
android-apk.yml, which were previously pinned to 20. This ensures
consistent build environments across all workflows.
Submodule and security hardening:
- Conditionally fetch the vendor/qwen-asr submodule only on macOS
jobs across all three workflows. The submodule is compiled
exclusively by build.rs on macOS (build_qwen_asr_macos); Linux,
Windows, and Android builds never reference it. Removing the
unconditional recursive checkout eliminates a network fetch and
a submodule-availability failure point on every non-macOS job.
- Set withGlobalTauri to false in tauri.conf.json. The frontend
exclusively uses @tauri-apps/api imports and never references the
window.__TAURI__ global, so disabling it removes an unnecessary
XSS attack surface without functional impact.
Dependency hygiene:
- Move @types/dompurify from dependencies to devDependencies in
package.json. Type declaration packages are build-time only and
should not ship in the production bundle.
* fix(ci): address review findings
* fix(ci): isolate manual CI workflow runs
---------
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-08-10 23:06:12 +08:00
Chris233
4496eba30b
feat(marketplace): 支持风格包 ZIP 下载与跨设备导入 ( #942 )
...
* feat(marketplace): add style pack ZIP downloads
* fix(marketplace): reject file URI download targets
2026-08-10 21:59:10 +08:00
浩彬(^-^) and Cursor
ead09481bd
feat(android): 可选 Shizuku 与三层跨应用粘贴回退 ( #932 )
...
* feat(android): add optional Shizuku accessibility recovery path
Integrate best-effort OpenLessAccessibilityService recovery via Shizuku UserService with safe rollback, manifest/Gradle scaffolding, JNI bridge, settings UI, and contract tests.
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): add primary constructor for Shizuku UserService Stub
Kotlin requires an explicit supertype initializer when extending AIDL Stub; fixes Gradle compile error on CI.
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): replace accessibility heartbeat with IPC paste results
Remove SharedPreferences cross-process heartbeat gating, use structured PASTE/PING IPC with safe retry rules, tighten editable target validation, and fix Shizuku manifest attribute merging for mixed-quote providers.
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): use literal const values in accessibility command receiver
Kotlin const val cannot reference enum codes; fixes release APK compile.
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 修复无障碍组件短名与全名匹配误判
Settings.Secure 常以 pkg/.Class 存储服务列表,主检测路径改用 ComponentName 规范化比较,避免 enabled=false 误报未授权;同步 Rust JNI 路径并补齐测试。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 为 JNI 调用的无障碍检测方法添加 @Keep
Release 构建中 R8 会剥离仅由 JNI 反射调用的 pingAccessibilityProcess,导致 NoSuchMethodError 与 operational=false 误报;同步保护 isEnabled 并补充契约测试。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 恢复无障碍粘贴的可编辑目标回退查找
粘贴失败日志为 NO_FOCUSED_EDITOR:过严的 isFocused 校验与移除树遍历导致找不到输入框。恢复 FOCUS_ACCESSIBILITY、宽松焦点匹配与 findEditableInTree 回退,并保留严格缓存校验。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 跨窗口扫描与缓存优先修复粘贴目标查找
微信等场景下 rootInActiveWindow 非输入窗口导致 NO_FOCUSED_EDITOR;改为缓存优先、遍历全部无障碍窗口,并加深树搜索。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 识别非 isEditable 的粘贴目标节点
微信等 App 不向无障碍暴露 isEditable;扩展为 EditText/ACTION_PASTE/ACTION_SET_TEXT 目标,并订阅文本变更事件以预热缓存。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 三层粘贴回退(无障碍 → Shizuku → 剪贴板)
无障碍失败后尝试 Shizuku 注入 KEYCODE_PASTE,再回退剪贴板;精简 Tier1 为 findFocus + ACTION_PASTE。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 粘贴结果校验与 Shizuku processNameSuffix
ACTION_PASTE 返回 true 但文本未写入时降级为 PASTE_REJECTED 并走 Tier2;修复 UserService 绑定 NPE;Tier1 成功后跳过 Shizuku。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 恢复无障碍可编辑目标查找以修复微信等应用粘贴
aaa3fbf2 将 Tier1 简化为 findFocus 导致微信等应用 PASTE_REJECTED;恢复跨窗口/树扫描与焦点缓存,保留粘贴结果校验与 Promise.allSettled 容错。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 通过 IPC 传递粘贴文本修复后台剪贴板读取被拒绝
无障碍子进程在应用未聚焦时无法读剪贴板,导致 Tier1 直接 PASTE_REJECTED;主进程将听写文本经 EXTRA_PASTE_TEXT 传入粘贴流程。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): Tier2 粘贴改用 Shizuku.newProcess 绕过 MTK UserService 崩溃
联发科/小米 ROM 上 UserService 进程在 LoadedApk.makeApplicationInner 因 procName 为 null 而 NPE;粘贴键注入优先走 Shizuku.newProcess,失败再回退 UserService。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): Tier2 粘贴改用 Shizuku daemon UserService
newProcess 为私有 API;粘贴键注入改走 daemon(true) 绑定,避免 MTK 上 :shizuku 子进程 Application NPE。
Co-authored-by: Cursor <cursoragent@cursor.com >
* test(android): 修正 daemon 粘贴契约断言
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): daemon 粘贴绑定补全 processNameSuffix
Shizuku UserServiceArgs 要求 suffix 非空;daemon(true)+suffix=paste 避免此前 null NPE 与 MTK :shizuku 子进程崩溃。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): Tier2 粘贴经反射调用 Shizuku.newProcess
MTK 上 UserService 子进程仍触发 LoadedApk NPE;粘贴键注入优先反射 newProcess 执行 input keyevent 279,UserService 作回退。
Co-authored-by: Cursor <cursoragent@cursor.com >
* chore(android): 移除粘贴调试日志
微信等应用三层粘贴回退已在真机验证通过,清理 DBG-21a66f/DBG-53a00d 临时 instrumentation。
Co-authored-by: Cursor <cursoragent@cursor.com >
* fix(android): 修复 CI 单元测试在无 Robolectric 下失败
ComponentIds 改为纯 Kotlin 规范化(对齐 Rust);isValidServiceComponent 拒绝首尾空白;Target 测试改用 action id 常量。
Co-authored-by: Cursor <cursoragent@cursor.com >
---------
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-08-07 21:50:09 +08:00
cd48a037a4
fix(less-computer): restore OpenCode model discovery and execution ( #840 )
...
* fix(less-computer): restore OpenCode model execution
* fix(capsule): gate set_ignore_cursor_events behind #[cfg(not(mobile))]
#887 introduced desktop-only capsule cursor-passthrough logic into the
unconditionally-compiled capsule_focus module, breaking Android cargo check
(E0599: no method set_ignore_cursor_events on tauri::WebviewWindow). Gate the
block to desktop; variables it consumes (classic_style, selection_polish,
visible) are still used on mobile outside the block.
---------
Co-authored-by: sim <sim@local>
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-08-03 16:03:41 +08:00
浩彬(^-^)
2409036ca9
fix(android): use app cache for Marketplace installs ( #879 )
2026-08-02 20:22:22 +08:00
浩彬(^-^) and Cursor
7ad24d3e94
fix(android): persist prefs/logs under app filesDir ( #877 )
...
* fix(android): use app filesDir for persistence and SAF log export
Honor devices reject writes under /data/local/tmp, which caused PreferencesStore to fall back to openless_prefs_fallback.json and settings saves to fail. Initialize JNI storage roots before Coordinator and file logging, route logs to files/logs/openless.log, and export via ContentResolver for SAF content:// URIs.
* fix(android): guard StylePack empty asset_root and Android-only coord logs
Reject persisting style pack icons when asset_root is empty to avoid writing under cwd; no-op cleanup on empty root. Limit Coordinator persistence degrade log suffix to Android only. Add unit test.
Co-authored-by: Cursor <cursoragent@cursor.com >
---------
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-08-02 20:04:18 +08:00
TRIP
857ea6dc21
Merge pull request #839 from Open-Less/release/1.3.15
...
fix(updater): prepare 1.3.15-Beta.2 after repository transfer
2026-07-21 18:43:09 +08:00
sim
6b33ba21e0
fix(updater): prepare 1.3.15-Beta.2 after repository transfer
2026-07-19 00:11:34 +08:00
75918e0338
fix(android): protect credentials with Android Keystore ( #838 )
...
* fix(android): protect credentials with Keystore
* fix(android): harden credential migration
* fix(android): recover sanitized credential migration
* fix(ci): target Android x86_64 test variant
* fix(ci): prepare Tauri Android test project
* fix(ci): set Tauri Android build metadata
* fix(ci): isolate Android Keystore test build
* fix(ci): generate Tauri Android Kotlin bridge
* fix(android): harden credential persistence
* fix(android): preserve credential migration roots
* fix(android): recover verified credential writes
* fix(android): clear unrecoverable credential recovery
* fix(ci): accept CRLF in Android credential contract
---------
Co-authored-by: Codex <codex@openai.com >
Co-authored-by: baiqing <lbx12309@icloud.com >
Co-authored-by: Chris233 <h-chris233@outlook.com >
2026-07-18 18:13:34 +08:00
TRIP and sim
4bdef5d7a3
ci: run all frontend and contract tests ( #832 )
...
Co-authored-by: sim <sim@local>
2026-07-15 15:55:37 +08:00
eb099c4f41
build(macos): 校验打包产物声明语音识别用途 ( #825 )
...
* build(macos): 校验打包产物声明语音识别用途
build-mac.sh 已在校验 NSMicrophoneUsageDescription 与 audio-input
entitlement,但 Apple Speech provider 引入的 NSSpeechRecognitionUsage-
Description 没有对应护栏。该 key 一旦缺失,构建静默成功,而选择
apple-speech 的用户会在调用 Speech.framework 时被 macOS TCC 以 SIGABRT
直接杀掉进程(崩溃报告 termination namespace = TCC)。
对打包产物 .app/Contents/Info.plist(而非源码 Info.plist)新增一行
PlistBuddy 校验:脚本开头的 set -euo pipefail 会让 key 缺失时非零退出、
当场中止构建。key 存在时输出被丢弃,行为与现在完全一致,产物逐字节不变。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
* fix(macos): enforce speech usage description contract
* fix(macos): reject Unicode-only speech descriptions
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com >
Co-authored-by: sim <sim@local>
2026-07-15 15:26:48 +08:00
TRIP and sim
e3e63cad04
fix(security): harden remote pairing PIN persistence ( #821 )
...
* fix(security): harden remote pairing PIN persistence
* fix(security): harden pairing PIN persistence
* test(ci): accept Windows line endings in PIN contract
* fix(linux): declare libc for secure PIN opens
---------
Co-authored-by: sim <sim@local>
2026-07-15 14:46:06 +08:00
TRIP and sim
9991b325b8
test(windows): repair UI config contract ( #829 )
...
Co-authored-by: sim <sim@local>
2026-07-15 13:53:09 +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
cfb09b14f8
fix(capsule): 胶囊跟随鼠标光标所在屏,修复多屏/多 Space 只在第一块屏显示 ( #714 )
...
新增 CGEventGetLocation 取鼠标光标位置(零权限),focused_input_target_monitor → capsule_target_monitor,定位与去重快照统一走光标优先选屏,消除「定位用 AX caret、去重用 current_monitor」两套选屏不一致导致的锁屏。
Claude 审核:5 个核心确认点(坐标系一致/选屏逻辑/快照统一/零权限/平台隔离)全部通过,可合并。
2026-06-21 00:05:45 +08:00
TRIP
fbe40ab583
feat(android): 集成 #704 安卓自动更新 + 同步 PC updater 修复(#705/#708)到安卓 ( #712 )
...
合并 #704(安卓应用内自动更新 + JNI 修复)并把 PC updater 修复同步到安卓:①安卓公钥回退 6F4B5994→1DEAA803(同步#705)②installError 安装失败兜底+去 throw(同步#708)③还原被自动合并误删的桌面 logClientError。桌面机制零变更。CI 全绿 + @claude 审核通过。取代 #704 及 #694 安卓部分。
2026-06-19 13:55:53 +08:00
TRIP
121bb11447
fix: audit batch 1 — critical Android updater + security hardening + bug fixes ( #695 )
...
14 confirmed audit findings: critical Android auto-update fix (SUPPORTED_ABIS), security hardening (exe allowlist, window-scoped approval, update-URL validation, remote PIN rate-limit/entropy, mirror order, prompt sanitization), correctness bugs (prefs race, hotkey spawn race, voice-agent focus clear), build-hygiene, and Android robustness. All-platform CI green; 446 tests pass.
2026-06-17 11:13:27 +08:00
TRIP
0eb69fc0f4
chore: codebase cleanup + behavior-preserving refactor ( #693 )
...
Audit-driven cleanup: 6 issue fixes (#689/#686/#680/#691/#678/#612), Aura skin removal (visually-neutral), dead-code cleanup (98→87 warnings), behavior-preserving modularization (coordinator.rs 6961→3083 + LocalAsr/ + polish/ submodules), and RELEASING.md (admin-only release policy). Gates: cargo test --lib 446 passed, tsc, all-platform build + contract checks green. Supersedes #685/#687/#690/#692/#682/#681.
2026-06-16 23:22:21 +08:00
HKLHaoBin and Cursor
63040b2028
feat(ui): 深色模式与主题 token 及选中态修复
...
Co-authored-by: Cursor <cursoragent@cursor.com >
2026-06-14 19:03:02 +08:00
Chris233
8e8f5fdeb5
Merge pull request #658 from HKLHaoBin/feat/android-release-pipeline
...
feat(android): 对齐移动端构建与发布流水线
2026-06-14 14:12:03 +08:00