16 Commits
Author SHA1 Message Date
TRIPandHKLHaoBin 6f9af89583 release: OpenLess 2.0.0-Beta.4+build.20260930 (#1126)
Integrate ASR/Omni fixes, API Route, Android IME and confirmation-based vocabulary learning. Complete settings transitions and macOS single-item credential storage. Synchronize all application versions to 2.0.0-Beta.4+build.20260930.

Integrated PRs: #1116, #1120, #1121, #1123, #1124, #1067 and #1128. Linux #1117 remains independent and is excluded from automatic release.

Validated: full cross-platform CI, 18 UI motion cases, 112 frontend test files, 1245 Core tests (1 ignored) and 572 macOS native tests.

Co-authored-by: HKLHaoBin <we3q@qq.com>
2026-09-30 20:32:53 +08:00
16c3f841b5 chore(release): prepare 2.0.0-Beta.2 build 20260924
Integrate the reviewed 2.0 PRs and local fixes from 03136853.
Preserve the verified subtitle behavior and model/runtime corrections.
Keep the numeric Beta tag compatible with released clients while exposing
the date as application build metadata.

Co-authored-by: DepengWang <2818245+DepengWang@users.noreply.github.com>
Co-authored-by: HKLHaoBin <we3q@qq.com>
Co-authored-by: Nahida <1139500183@qq.com>
Co-authored-by: TRIP <1933142963@qq.com>
Co-authored-by: chyuwei <weichangyuwcy@gmail.com>
Co-authored-by: leonoxo <leonoxo@gmail.com>
Co-authored-by: tayir <arnoldincredible@126.com>
2026-09-24 17:28:24 +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 4519f19c92 style(app): 统一前端与平台源码格式 2026-09-08 14:35:28 +08:00
sim d686406a70 refactor(app): 清理废弃代码并明确模块注释 2026-09-08 14:27:29 +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
浩彬(^-^)andCursor 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
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
浩彬(^-^)andCursor 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
浩彬(^-^)andCursor 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
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
TRIPandsim d6ca07a6b2 fix(android): break IPC settings barrel cycle (#827)
Co-authored-by: sim <sim@local>
2026-07-15 13:20:57 +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 5aed1e46ed fix: audit batch 2 — correctness bugs + Android robustness (#696)
7 medium findings: corrupt-timestamp context truncation, voice_agent flag timing, Volcengine/Bailian ASR cancel-on-error, graceful store-init fallback (no startup panic), Android OVERLAY_VISIBLE desync (Rust+Kotlin onDestroy), JNI null-check, accessibility clipboard restore. All-platform CI green; 446 tests pass.
2026-06-17 11:39:55 +08:00
HKLHaoBinandCursor 0fe5fbfdcf feat(android): align release pipeline with desktop updater rules
Add signed release APK builds on v*-tauri tags, minisign manifests per ABI, custom Android in-app updater, and CI cargo check for aarch64-linux-android.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 19:48:07 +08:00
HKLHaoBin 1ea467a001 feat(android): port Android APK runtime onto beta 2026-06-12 18:13:12 +08:00