Skip to content

release(stable): promote reviewed beta6 to 2.0.0+build.20261016 - #1201

Merged
appergb merged 162 commits into
mainfrom
release/2.0.0-main-20261016
Oct 15, 2026
Merged

appergb merged 162 commits into
mainfrom
release/2.0.0-main-20261016

Conversation

@appergb

@appergb appergb commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator

正式版晋级(维护者 beta → main 集成)

把已通过 Review/七项 CI 的 beta6 生产代码及 2.0.0+build.20261016 版本准备晋级至 main。此 PR 暂为 draft,必须先合并 #1200、核验并公开 beta6,且本 PR 自身 CI 全绿后才可合并/发 Stable。

main 长期停留于 1.3.18,与 beta 历史分叉。维护者集成分支记录 main 祖先,但保留已验收的 2.0 候选 tree;没有用 1.x settings/i18n/版本文件覆盖 Core 2.0。已经逐项审查 main 独有净差异:

  • 1.3.18 cask 版本/两个 SHA 已存在于 beta,新的日期 URL、macOS 14 与自动同步修复保留。
  • fix(settings): keep experimental state consistent #959 的 canonical settings 返回值、实验标题和偏好并发写保护已由当前 set_settings/Core field patch、PreferencesWriteGate、共享 ExperimentalSectionTitle 及其回归覆盖。
  • fix(llm): make custom provider temperature configurable #818 / GLM 井号过滤的历史 commit 差异没有形成 main 相对共同祖先的新生产代码差异,不丢弃共同代码中的能力。
  • 不复活已由 2.0 决策替代的旧 LocalModelSection/MultimodalPipelineSection 或历史 Sherpa 规划文件。

来源及状态记录:docs/releases/2.0.0-preparation-20261016.md 与 docs/releases/2.0.0-main-integration-20261016.md。本机修复版已由用户试用确认正常,当前不替换 App。

发布顺序

beta6 两条资产流水线核验并公开 → #1200 合入 beta → 本 PR 全绿后以线性 squash 维护 main → 最终 main CI 确认 → 管理员 v2.0.0-tauri → 资产核验并公开 latest → 自动同步 Homebrew / 本机升级。未执行设备场景不记为通过,Linux 安装包不随本次发布附加。

sim and others added 30 commits August 16, 2026 17:09
* 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>
Provider validation used the globally active ASR provider when deciding whether to derive Bailian protocol endpoints. Non-active Bailian channels therefore sent their WebSocket endpoint through HTTP-only validation for synchronous models.
…与工具展示 (#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>
* rename: 上游插件改名 dsh-jsonl -> dsh-events,同步 vendor 与常量

插件仓库改了名。`jsonl` 说的是输出格式,不是它给你什么——目标用户是想把 dsh 接进
GUI / 编辑器 / CI 的人,他们脑子里的词是「事件」,不是「JSON Lines」。而且别家都不这么
叫(Claude Code 是 --output-format stream-json,Codex 是 --json,OpenCode 是
--format json),有人来找这个能力时搜的是 "dsh json output"。

趁 npm 还没发布、还没对外宣传时改,代价只有改几个文件。旧 URL 有 GitHub 重定向兜底,
但留着迟早会成为断链。

跟着改的:vendor 文件名、同步脚本名、两个常量、环境变量名、模块文档与注释里的链接。
vendor 文件是用改名后的脚本重新生成的,不是手改——review 时加进来的来源与 MIT 许可头
原样保留。

* test(dsh): 删掉一条红绿取决于模型心情的联机验收

`tmp_is_writable_by_design_and_we_cannot_narrow_it` 想把「$TMPDIR 可写且收不掉」这个
dsh 既有行为钉成契约。但验证它必然要让模型去写文件,而 dsh 有**两道松紧不同的围栏**:

  bash(seatbelt 子进程沙箱)      工作目录 + /tmp + $TMPDIR
  write / edit(进程内 fs 围栏)    只有工作目录

prompt 里写了「用 bash 执行」,模型照做就绿,改用 write 就红。实测两种都出现过:一次
文件真落下去(bash),一次模型回 DONE 但文件根本没建(write)。这条测试的红绿反映的是
模型当次的选择,不是被测系统的行为——正是它上面那条注释批评过的毛病,我自己又犯了一遍。

那张「两道围栏」的表挪进模块文档,并写明为什么不做成测试。留下的
`sandbox_blocks_writes_outside_the_workspace` 打的是家目录,两道围栏都挡,不受工具选择
影响,那条才作数。
* fix(macos): Fn 键可被录制为听写触发键 (#979)

浏览器/WebView 不向网页层下发 Fn 的 keydown(系统修饰键被隐藏),
ShortcutRecorder 无法通过键盘事件捕获 Fn。运行时本可检测 Fn(CGEventTap 看
keycode 63 + kCGEventFlagMaskSecondaryFn),但仅能通过「设置」写入,录制流程录不进。

- ShortcutRecorder:加 allowFn 开关,菜单提供「Fn」一键设置(绕过录制限制)
- macOS CGEventTap:录制态检测 Fn 边沿 → 上报 FnRecordingPressed → coordinator
  emit fn-shortcut-pressed → 前端提交 {primary:'Fn'}
- 关键修复:MacHotkeyAdapter 缺 set_recording_active override,录制态从未传到监听器,
  Fn 检测永不触发
- i18n: 补 comboFnLabel / comboFnHint 五语言文案

refs #979

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(android): gate desktop Fn recording bridge

* refactor(macos): record Fn through backend event

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
Update .gitignore to exclude local Reasonix metadata and the .codex directory so editor-generated or local inference files stay out of the repository.
* 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>
* feat(translation): inherit active style pack

* fix(translation): resolve style prompt conflicts
* feat(macos): add line feed newline option

* feat(macos): auto-select newline mode by target app

* style(macos): localize newline fallback comment
* 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
* feat(selection-voice): Windows 选区语音编辑 MVP(issue #987)

选区 + 专用快捷键 + 语音指令:指令润色后按 auto/manual/heuristic 分流到 QA 或 EditPlan 确定性编辑,含设置页、预览窗与热键集成。

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-voice): 修复 Windows 编译(展平 session 模块结构)

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-voice): 用 polish_text 替代 ActiveLLMProvider::complete

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(ci): 补全 mock trait 与 SessionId 单元测试类型

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(release): feature 分支跳过 MSI 并上传 NSIS 安装包

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-voice): post-utterance intent picker and merged settings

Let users choose question vs edit after speaking (default prompt mode), merge polish and voice into one settings card, keep hotkey supervisor polling, and show capsule errors when trigger preconditions fail.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(i18n): add selectionWorkspace keys for ja, ko, zh-TW

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-voice): compare hotkey supervisor signatures as Option<&str>

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(coordinator): gate selection_voice_intent_prompt init to Windows

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-workspace): unify voice and polish hotkey with edge prefetch

Reuse the selection polish shortcut for voice edit and prefetch selection at hotkey press to avoid Alt clearing the selection before capture.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-voice): align auto/toggle hotkey modes and intent UX

Match dictation auto short/long-press semantics, fix toggle stop blocked by busy flag, block overlapping dictation, and invert intent toggle to heuristic-off / AI-on.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(ci): gate selection-voice dictation block to Windows only

selection_voice_session is Windows-gated; non-Windows builds failed with E0433 when dictation referenced it unconditionally.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-voice): surface end-workflow errors instead of stuck loading

When stopping a voice session, failures during ASR, intent, or edit-plan steps now reset state and show a user-facing capsule error with stage hints.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-voice): annotate end-workflow async block error type as String

Windows CI failed because the async block inferred Result<_, str> instead of Result<_, String>.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-voice): route translation edits through translate pipeline

Infer target language from voice instructions like translate-to-English and build a full_rewrite plan via translate_text instead of fragile EditPlan JSON. Also normalize common LLM JSON aliases and improve parse fallbacks.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(selection-voice): use XML EditPlan format for LLM edit responses

Switch voice-edit system prompt to XML envelopes with child elements for multiline text. Add parse_edit_plan with XML-first parsing and JSON fallback for legacy outputs.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(edit-plan): correct XML entity match string literals

Fix E0762 unterminated character literal in decode_xml_text that broke all platform builds.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(edit-plan): resolve XML parser type errors for CI

Use Option for find_open_tag, fix unwrap_or types, bool attr matching, and promote_alias_field slice arity.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(edit-plan): fix remaining XML parser compile errors

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(edit-plan): fix tuple arity, map remove keys, and borrow in normalize

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-voice): unify voice edit with QA panel and improve intent

Route voice edits through QaPanel for shared preview/confirm UX, hide capsule when the session ends, prioritize heuristic edit cues for auto intent, and fix translation identity checks.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(selection-voice): 统一语音编辑为 QA 面板预览模式并支持回退

将选区语音编辑流程统一到 QA 面板,新增预览与回退功能。

- 新增 `revert_selection_voice_preview` Tauri 命令及 IPC 调用,支持回退到上一轮编辑预览
- 在 QA 面板中新增 `editRevertAvailable` 状态,处理预览模式下的错误与空闲状态
- 优化 `emit_selection_voice_end_error` 逻辑:预览模式下错误回退到 Idle 状态并关闭面板,其他模式下显示错误胶囊
- 新增翻译结果与原文相同时的错误提示
- 跟踪 `previous_preview_text` 以支持回退操作
- 同步更新多语言(zh-CN、zh-TW、en、ja、ko)编辑按钮文案及新增回退文案

* fix(ci): gate selection-voice QA follow-up to Windows and fix compile errors

Add missing selection_voice_preview_mode helper, cfg-gate revert command registration, and release QA mutex before async follow-up edit to satisfy Send.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(ci): stub selection module in backend-tests harness

hotkey.rs now prefetches workspace selection on polish shortcut; provide no-op stub for Rust-only test crate.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(qa): route intent by interrogative and add edit-instruction mode

Detect question vs non-question for selection-voice Auto intent, polish QA mic ASR, and gate ask/edit on the panel checkbox so text and voice stay consistent.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(selection-voice): 增强语音编辑功能,优化 QA 面板状态同步

* fix(selection-voice): stop legacy edit keywords from misrouting to QA

Filter pre-#987 default keywords like 「改成」 so edit imperatives no longer match question heuristics, and reset qa_stream_cancelled before streaming so prior QA cancellations do not yield empty-stream failures.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection-voice): address review blockers

* fix(selection-voice): gate QA preview cleanup to Windows

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
* 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>
* fix(polish): 润色流式请求让取消检测和网络等待赛跑,不再悬挂到 budget 结束

配置为 qwen-audio-3.0-asr-flash + deepseek-v4-flash 时,若润色阶段对话模型
接口迟迟不返回,取消操作(点击胶囊关闭按钮 / 按快捷键重新发起)会晚至
32~53 秒才生效,期间胶囊卡死在屏幕上、快捷键无响应,只能强制重启 App
才能恢复(本机日志复现,见 issue)。

根因:chat_completion_messages_streaming 的取消检测只在 SSE 循环顶部轮询
一次,真正等待网络数据的两处 await(建连/发送请求、逐帧读取)都不会被
取消打断,只能等到数据到达或 budget(首字 30s+ / 空闲 20s / 硬顶 900s)
自然超时。同一类问题在转写(ASR)阶段已在 #798 修过,但没有推广到润色
阶段——这是一处遗留的修复范围缺口。

用同款 tokio::select! 赛跑模式补齐:新增 wait_until_cancelled helper
(75ms 轮询,与 wait_for_processing_cancel 同款间隔),分别和
send_with_transient_retry、response.chunk() 赛跑,命中取消就复用既有的
"空流 → InvalidResponse" 错误路径。不改变任何超时预算数值,不改变
already_streamed 语义,不改变 dictation.rs 状态机。

Fixes #1000

* test(polish): 补上 SSE 循环内取消的回归测试,并修正建连阶段取消的状态码

上一版新增的 cancellation_before_response_arrives_* 只覆盖了「服务端连状态行
都不回」的建连阶段,走的是 send_with_transient_retry 之前那个 select!。而
issue #1000 日志里打出的是 "cancelled by caller after 0 deltas ... breaking
SSE loop",说明 response 头已到达、代码已进入 SSE 循环,真正卡住的是
response.chunk() 那一次 await——也就是本次修复的核心那处 select!,此前没有
任何回归测试覆盖:把它还原成旧写法,原用例照样通过。

补 cancellation_mid_stream_does_not_wait_out_the_budget:服务端立刻回 200
header 让客户端进入 SSE 循环,随后长时间不发 delta,取消后必须在一个轮询
周期内返回,而不是等满 30s 首字预算。

顺带把建连阶段取消返回的 status 从编造的 200 改成 0:那条路径上一个 HTTP
响应字节都没收到,日志打成 "status 200" 会让人误以为服务端回了 200 空body。
两个用例的断言因此分别锁 status 0 / 200,互相不会冒充。

* fix(polish): 读取非 2xx 错误 body 时也让取消赛跑,并给 select! 加 biased

外部 review(codex)指出前两版仍漏了一处不可取消的网络等待:收到非 2xx
响应头后的 response.text()。polish_client 走的是 POLISH_CLIENT_HARD_CAP_SECS
(900s)总超时,服务端只要回一个 500 头就挂住不发 body,取消完全不生效,
最坏卡死 15 分钟——症状与 issue #1000 一致,且比原路径的 30s 首字预算严重
一个数量级。

补 cancellation_while_reading_error_body_does_not_hang:服务端回 500 头并
声明 1KB body 却一字节不发。去掉这次赛跑后该用例实测耗时 5.01s(真实场景
连接不关就是等满 900s)。

三处 select! 统一加 biased,让取消分支先于网络分支被 poll,消掉「budget 归
零与取消同时就绪时随机选分支」的竞态。

按 review 意见收紧措辞与注释:原注释称 Response 被 drop 会中断底层 TCP,
在 HTTP/2 多路复用与连接池下未必成立,改为只声明放弃这次请求的等待;
wait_until_cancelled 与两个既有用例的说明各压掉约一半。
* fix(remote-input): start the LAN server on launch when already enabled

Toggling the setting only refreshed the server on a prefs change. After restart the switch stayed on but port 8443 never bound, so the phone page could not open.

* fix(remote-input): unstick Windows startup and settings

On Windows, NIC enumeration and Tauri path APIs from the async runtime can stall the LAN server, and set_remote_locale's main-thread tray refresh deadlocks the settings page. Start the server on Ready and keep those calls off the UI thread.

* fix(remote-input): harden LAN discovery and startup lifecycle

* fix(remote-input): feed phone PCM into ASR instead of the PC mic

Remote dictation still opened the computer microphone and never assigned
the phone sink, so Safari audio was dropped. Arm a deferred bridge on
start and skip the local capture device for remote sessions.

* fix(remote-input): scope PCM cleanup to active session

* test(remote-input): import RMS helper

* fix(remote-input): clear idle PCM sink on cancel

---------

Co-authored-by: Chris233 <h-chris233@outlook.com>
…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
* 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>
* fix(floating-windows): 浮窗跟随鼠标所在的屏,多显示器下不再被钉死在主屏

接了外接屏时,Less Computer 的全屏彩虹描边(跑马灯)、Less Computer 聊天浮窗和
QA 浮窗都只出现在主屏上,胶囊却在你正在用的那块屏 —— 两边分家。

原因是这三个浮窗选屏时问的是「我自己现在在哪块屏」(window.current_monitor)。
它们都是懒创建 + 常驻隐藏的窗口:隐藏时停在上一次出现的屏,而这辈子第一次出现
就在系统默认(主)屏,于是每次 show 都算出主屏、又铺回主屏,永久钉死。

胶囊自己踩过并修好过同一个坑 —— 改成跟随鼠标光标所在的屏(capsule_target_monitor
的注释写着「不能用窗口自己的 current_monitor」),这三个浮窗漏掉了。这里抽出共用的
floating_window_monitor_frame,让浮窗和胶囊看同一块屏;非 macOS 没有这条
CGEvent/AX 通路,仍走 current_monitor,行为不变。

顺带把选屏的纯逻辑抽成 pick_monitor_for_anchor_point 并补单测:光标在哪块屏就选
哪块、落在所有屏之外时退到最近的屏。

注:QA 浮窗只在首次 show 时定位(之后有意保留用户拖动后的位置),所以这条对它只
影响第一次出现的位置。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* test(macos): fix mixed-DPI monitor fixture

* ci: rerun with updated Linux gate

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
* fix(selection-voice): auto-hide capsule when begin fails without selection

Schedule the standard 2s capsule idle timer after no-selection begin errors so the Siri-style prompt does not stay on screen indefinitely.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection): log why selection capture missed for voice/polish

Distinguish clipboard sentinel unchanged, empty copy, shortcut failure, and prefetch vs live capture so user-exported logs can diagnose false no-selection reports.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection): fix capture diag logging compile errors

Format optional front_app in prefetch miss logs and gate the NoCapturePath fallback to non-desktop targets so macOS/Windows/Linux builds compile cleanly.

Co-authored-by: Cursor <cursoragent@cursor.com>

* debug(selection): add sentinel/post_copy DEBUG logs to diagnose Chrome capture

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection): Windows content-change check instead of sentinel for Ctrl+C validation

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection): settle clipboard after sentinel for Windows history race

Clipboard History async listeners can hold the clipboard after we write the
sentinel, so target-app Ctrl+C silently fails. Wait for settle, poll, and
optionally resend Ctrl+C. Bump to 1.3.18-Beta.10.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection): parenthesize duration cast comparisons for Rust parse

Bare `as u64 <` is parsed as a generic; cfg(windows) code still must parse on Linux CI.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(selection): handle GetOpenClipboardWindow Result and type key_down

windows 0.58 returns Result<HWND>; annotate VIRTUAL_KEY for GetAsyncKeyState.

Co-authored-by: Cursor <cursoragent@cursor.com>

* chore(selection): 从 PR 中移除 fork 专用版本号与 release workflow

上游 PR 只保留选区捕获 / 剪贴板 sentinel 修复。版本号仍由上游发布流程管理。

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
Co-authored-by: tonyzaca7755963 <tonyzaca7755963@users.noreply.github.com>
- 主页前置下一步与真实服务状态,服务卡直达对应设置;概览与热力图排布调整
- 设置按任务分类并支持搜索、焦点返回与 Escape 语义;旧 section ID 保持稳定
- AI 分区拆分语言模型/语音识别/本地模型/连接;渠道列表与表单重构,设置实底
- 本地模型管理与下载目录重排,补空态、主操作与窄屏布局
- Core 生成 provider descriptor 公开目录供浏览器预览懒加载,原生 IPC 合同不变
- Linux egui 按开始/听写/AI 服务/模型/工具/手机输入/历史/设置组织页面并加环境引导
- 五语言文案与文档(体验梳理、架构、计划收口)同步
删除已完成/已收口任务的规划与过程记录(2.0 UX 收口、Core 2.0 计划、
PR#1019 复核与桌面复审、平台边界审计、Linux 引导知识快照、
Linux 共享后端阶段计划、供应商渠道计划、Windows sherpa 规划、
PR#711 评审截图、应用内测试计划),保留规范性文档、验收清单、
Linux 交接目录与运营指南,并修复全部引用链接。
修正 92da4fb 中误随 git add -A 提交的 Mimosa 安全钩子运行状态文件;
该目录为插件会话状态,不属于版本库,已忽略以防再次混入。
HKLHaoBin and others added 28 commits October 12, 2026 17:51
* fix(android): make pinyin label toggle input mode

Route taps on the visible Pinyin/English hint to the existing mode switch instead of allowing them to fall through to the space key, while preserving ordinary space and long-press behavior.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* test(sync): tolerate CI scheduling latency in pause check

Keep the runtime-release assertion while allowing asynchronous state persistence to complete on loaded Linux runners.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* fix(qa): expand selection polish preview

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(qa): preserve polish preview mock after upstream merge

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(qa): allow editing selection polish preview before insert

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
…1138)

* fix(sync): stop treating list position and hit counts as conflicts

Encrypted sync compared whole records, and every history, dictionary and
correction record carried sortIndex: its position in the exporting
device's list. History and corrections insert at the front, so each new
dictation renumbered every older row on that device. Two devices that had
both been used since the last sync, an unequal number of times, therefore
disagreed with each other and with the baseline on every shared history
row, and the user was asked to pick a side for each one even though the
text was identical. Dictionary hit counters did the same per word.

The merge now compares what a record says. sortIndex (history, dictionary,
corrections) and dictionary hits are left out of the comparison; when both
sides hold a dictionary entry the higher hit count is kept, including when
a conflict is resolved by choice.

Collection order is derived from the records instead of from a device's
list: history and corrections newest first, dictionary manual entries
newest first ahead of learned entries oldest first, which is how the
stores insert. sortIndex stays on the wire as a dense index so older
clients keep restoring in order; the incoming value only breaks ties, so
rows without a usable createdAt keep their relative order.

Real conflicts are unchanged: the same record edited on both sides, and
delete against modify, still ask the user.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(sync): canonicalize merged collection ties

Prevent equivalent records with equal or undated timestamps from retaining device-local sortIndex during merge while preserving legacy direct restore ordering. Add convergence and timezone-order regression coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(sync): preserve agreed collection order

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(sync): preserve one-sided inserts in tied collections

---------

Co-authored-by: DepengWang <2818245+DepengWang@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: HKLHaoBin <we3q@qq.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
* fix(windows): show recording capsule on every monitor (issue #1057)

Mirror the capsule and transcript rail onto non-primary displays so reconnecting an external monitor no longer hides the UI on the secondary screen.

* fix(capsule): protect replay from live events

* test(capsule): cover wrapped fallback events

---------

Co-authored-by: Chris233 <h-chris233@outlook.com>
…#1185)

* fix(dictation): skip polish when LLM is unset or transcript is short (#1032)

Unconfigured LLM channels now run as Raw without polishFailed toasts, and a user-set polishSkipMaxChars threshold skips polish for short dictations.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(dictation): preserve no-LLM fallback across target changes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(dictation): update translation context expectation

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(linux): configure fixture LLM channel

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(dictation): correct short-input history and settings

* fix(linux): update egui settings test input

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
* fix(android): 听写撤销前确认原文仍在光标处

按长度删除会在用户退格或移动光标后擦掉相邻文字。撤销和整段替换只在原文完整位于光标前时执行。

Co-authored-by: lubaiqing9 <lubaiqing9@gmail.com>

* fix(android): guard dictation edits and read cursor text once

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: lubaiqing9 <lubaiqing9@gmail.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
* fix(selection): 拒绝用截断提示替换超长选区

选区润色和语音编辑的提示最多只放入 16000 字,但默认直接替换会把模型结果写回整段原文。超长选区在调用模型前直接失败,避免删掉模型没看到的后半段。

Co-authored-by: lubaiqing9 <lubaiqing9@gmail.com>

* test(selection): cover envelope boundaries across edit entrypoints

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: lubaiqing9 <lubaiqing9@gmail.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
编辑面板关闭后若识别失败,awaitingEditReplacement 仍会把下一次普通听写送进按长度删除的整段替换。失败和主麦克风上的新录音都会释放这个状态。

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: lubaiqing9 <lubaiqing9@gmail.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
* feat(audio): add configurable microphone enhancement

Add shared audio processing with bounded native capture workers, frozen recording configuration, and desktop settings integration across Tauri and Linux.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(linux): keep recording settings rows visible

Render the existing audio cue row before the new enhancement toggle so the fixed-size Linux settings regression test and compact layout retain the established controls.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(linux): satisfy capture worker clippy checks

Group Linux recorder startup and worker arguments into typed options so the audio enhancement path passes the Linux warning-as-error build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(audio): add lightweight noise suppression

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(linux): satisfy audio clippy gate

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(audio): use fresh frames for sustained speech

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
* fix(polish): diagnose adjacent near-duplicate output

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(polish): complete duplicate diagnostics across dictation stages

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
…ion/desktop-beta-a.beta.5-20261015-bd

# Conflicts:
#	openless-all/app/src/components/SettingsModal.tsx
#	openless-all/app/src/i18n/de.ts
#	openless-all/app/src/i18n/en.ts
#	openless-all/app/src/i18n/es.ts
#	openless-all/app/src/i18n/fr.ts
#	openless-all/app/src/i18n/ja.ts
#	openless-all/app/src/i18n/ko.ts
#	openless-all/app/src/i18n/zh-CN.ts
#	openless-all/app/src/i18n/zh-TW.ts
#	openless-all/app/src/pages/settings/ChannelList.tsx
#	openless-all/app/src/pages/settings/models/LocalModelPicker.tsx
#	openless-all/app/src/pages/settings/navigation.ts
#	openless-all/app/src/pages/settings/tabs.tsx
…to integration/desktop-beta-a.beta.5-20261015-bd
…ion/desktop-beta-a.beta.5-20261015-bd

# Conflicts:
#	docs/architecture.md
…nto integration/desktop-beta-a.beta.5-20261015-bd

# Conflicts:
#	docs/architecture.md
#	openless-all/app/src-tauri/src/commands/qa.rs
#	openless-all/app/src-tauri/src/lib.rs
#	openless-all/app/src/i18n/de.ts
#	openless-all/app/src/i18n/en.ts
#	openless-all/app/src/i18n/es.ts
#	openless-all/app/src/i18n/fr.ts
#	openless-all/app/src/i18n/ja.ts
#	openless-all/app/src/i18n/ko.ts
#	openless-all/app/src/i18n/zh-CN.ts
#	openless-all/app/src/i18n/zh-TW.ts
#	openless-all/app/src/pages/settings/ShortcutsSection.tsx
#	openless-all/app/src/pages/settings/navigation.ts
#	openless-all/app/src/pages/settings/tabs.tsx
Align npm, Tauri and Cargo versions; preserve per-model lifecycle and Beta opt-in boundaries during UI integration. Verify three compact model switches, async window error propagation and updated opt-out visual baselines.
Gate Foundry command modules off mobile, use standard Core test module layout for TaskSpawner checks, normalize CRLF version fixtures, and add reviewed Ubuntu visual baselines with deterministic motion/scroll probes.
@appergb
appergb marked this pull request as ready for review October 15, 2026 19:35
@appergb
appergb merged commit b5e60db into main Oct 15, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.