Commit Graph
406 Commits
Author SHA1 Message Date
H-Chris233 e50bc17a15 Add complete Traditional Chinese UI locale support
Add zh-TW locale resources and wire it through language selection,
persistence, and system-locale detection. Also add static shape typing
for zh-TW to prevent future key drift from zh-CN.

Constraint: Keep changes minimal and localized to i18n + language pickers
Rejected: Partial zh-TW translation only for language section | fails full locale support goal
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep zh-TW key shape locked to zh-CN when adding new translation keys
Tested: npm run -s build (openless-all/app)
Not-tested: Manual runtime walkthrough on all platform shells
2026-05-05 10:51:46 +08:00
baiqing 429780b5e4 chore(release): 1.2.18 — Windows bundle 顺序锁 nsis,msi 让 updater 资产先落盘
历史链:
  1.2.13 ✓  无 IME wxs,MSI+NSIS 全过
  1.2.15 ✗  加 IME wxs;CI pwsh 把 JSON 引号吃掉,tauri 连 candle 都没跑
  1.2.16 ✗  shell 切 bash 后到 light 阶段,但 ICE80 触发,Repair 没 -sice
  1.2.17 ✗  Repair 加了 -sice:ICE80 修了 MSI;但 Tauri 字母序 msi→nsis 让
            MSI 先挂掉,NSIS 永远没机会跑,updater .exe(.sig) 缺失
  1.2.18    显式 --bundles nsis,msi:NSIS 先写盘产 updater 资产,MSI 再失败
            由 Repair 兜底 light.exe 重链

唯一改动:Build (Windows) 步骤两个分支都加 --bundles nsis,msi。
预留:NSIS 不读 wix.fragmentPaths,所以 .exe 暂不带 IME DLL;MSI 仍带,
后续单独 issue 跟进 NSIS IME 集成,不挂当前发版。
2026-05-04 22:56:33 +08:00
baiqing a5f1a8f16d chore(release): 1.2.17 — Windows MSI 修 light.exe ICE80 报错
x86/x64 IME DLL 都装进 INSTALLDIR\windows-ime\,32-bit 组件落在 64-bit
Directory 是 ICE80 的硬性报错。本场景路径绝对指向、不依赖 SysWOW64
重定向,按 Microsoft 文档是合法用法,给手动 light.exe 重链加 -sice:ICE80
即可放行。改动同步覆盖 CI workflow 和本地打包脚本。
2026-05-04 22:21:50 +08:00
baiqing 49210363d6 chore(release): 1.2.16 — Windows MSI 修 PowerShell 引号吞双引号 bug
1.2.15 第 4 轮 Windows job 在 wix 阶段之前就 exit 2,根因是上一版我把
Build (Windows) 整步切成 shell:pwsh 后,& npm run tauri --- build --config
'{"bundle":{"createUpdaterArtifacts":true}}' 这条命令 PowerShell 调外部
进程时把 JSON 内的双引号剥光,tauri 收到 {bundle:{createUpdaterArtifacts:true}}
直接拒绝。log 第 586 行能看到剥过引号的 commandline。

修法:
- Build (Windows) 切回 shell:bash(单引号能保留内部双引号)。set +e 抓
  exit code 写到 GITHUB_ENV,让本步不直接失败,把判断权交给下一步。
- 新增独立 step "Repair Windows MSI if Tauri failed at WiX link"(pwsh),
  仅在 tauri 非零退出且 MSI 不存在时手动从 appRoot 跑 light.exe 重链。
  本地 windows-package-msvc.ps1::Repair-TauriMsiBundle 同款手术。
2026-05-04 21:53:23 +08:00
Chris233 88452cb2ca Merge pull request #251 from H-Chris233/feat/asr-e2e-validation
feat(settings): add end-to-end ASR provider validation
2026-05-04 21:45:45 +08:00
H-Chris233 cb2eb8e9ce Preserve query parameters when building ASR transcription validation URL
ASR validation URL normalization now edits the parsed URL path instead of string-appending to the raw endpoint, so endpoints with query parameters (e.g. api-version) remain valid after adding /audio/transcriptions.

Constraint: Keep endpoint normalization minimal and avoid changing query/fragment semantics

Rejected: Drop query parameters during validation | would break Azure-style OpenAI-compatible deployments

Confidence: high

Scope-risk: narrow

Tested: cargo test -q
2026-05-04 21:35:14 +08:00
H-Chris233 df2d51e014 Normalize ASR transcription endpoint and enforce streaming response cap
Addresses review feedback: ASR validation now recognizes OpenAI-style /chat/completions endpoints when building the /audio/transcriptions URL, and response-size protection is enforced while streaming the body instead of after buffering it all.

Constraint: Keep ASR validation behavior provider-agnostic and minimal in scope

Rejected: Heuristic URL rewrites beyond known suffixes | risk of breaking custom reverse proxies

Confidence: high

Scope-risk: narrow

Directive: If changing reqwest features, keep Cargo.lock in sync and re-run tests

Tested: cargo test -q
2026-05-04 21:16:46 +08:00
H-Chris233 fd60f815c0 Accept /audio base URLs when validating ASR transcription endpoint
Some OpenAI-compatible deployments expose ASR under a base URL that already ends with /audio. ASR validation now treats that as a valid prefix and appends only /transcriptions to avoid generating /audio/audio/transcriptions.

Constraint: Keep ASR validation URL normalization conservative and backwards-compatible

Rejected: Full URL path rewrite heuristics | risk of breaking custom reverse-proxy layouts

Confidence: high

Scope-risk: narrow

Tested: cargo test -q
2026-05-04 20:51:40 +08:00
baiqing dcfeb405bf chore(release): 1.2.15 — Windows MSI 修复 IME bundle 集成
1.2.14 三轮 release pipeline Windows job 全挂在 WiX 集成上:
  1. 没构建 IME DLL → light.exe 找不到文件
  2. 加了 build 步骤后用相对路径 src-tauri\target\... → Tauri wix bundler
     cwd 和本地脚本不同,相对路径 resolve 错位
  3. 改 $(env.OPENLESS_IME_DLL_X64) 想用绝对路径 → candle 处理 env var
     substitution 时 abort(具体原因被 Tauri 吞掉)

1.2.15 切换到本地 windows-package-msvc.ps1 已经验证可行的 Repair 思路:
  - wxs 维持字面相对路径 src-tauri\target\... (让 candle 正常吃过)
  - workflow 接住 tauri build 失败:从 appRoot (openless-all/app/) 手动跑
    light.exe 重链 main.wixobj + openless-ime.wixobj。这是 light 唯一能
    resolve 该相对路径的 cwd。
2026-05-04 20:39:22 +08:00
Chris233 9c3ab9b100 Merge pull request #250 from H-Chris233/chore/readme-update
docs: add final acknowledgements for sponsors, developers, and LinuxDo community
2026-05-04 20:28:10 +08:00
H-Chris233 73dbd4cef7 Harden ASR validation path against endpoint and response regressions
Follow-up fixes from dual review keep the new end-to-end ASR check while removing compatibility and robustness regressions: normalize transcription endpoint URL, enforce HTTPS except localhost, cap response size, and switch to stable backend error codes mapped in i18n.

Constraint: Preserve issue #242 full-chain validation behavior with minimal surface change

Rejected: Revert to model-list-only validation | no longer verifies real transcription route

Confidence: high

Scope-risk: narrow

Directive: Keep providerHttpStatus:* and stable error-code contract synchronized with Settings error mapping

Tested: npm run build; cargo check -q

Not-tested: Manual validation against all third-party ASR endpoints
2026-05-04 20:27:08 +08:00
H-Chris233 2ae3bdf68a Use real transcription call for ASR connection validation
ASR validation now runs one end-to-end /audio/transcriptions request with the currently selected model and a tiny bundled silence WAV payload. This verifies endpoint, auth, model routing, and response schema in one pass instead of model-list reachability only.

Constraint: Keep UI/API contract unchanged and avoid touching recording pipeline

Rejected: Reuse live microphone capture in settings validation | invasive and non-deterministic for quick checks

Confidence: high

Scope-risk: narrow

Directive: Preserve providerHttpStatus:* error marker so frontend can keep status-specific guidance

Tested: npm run build; cargo check -q

Not-tested: Live validation against every third-party ASR provider implementation
2026-05-04 20:27:08 +08:00
H-Chris233 2438c901eb Ensure ASR connection check validates the configured model
Issue #242 asks ASR to reach parity with LLM availability checks. Validation now requires a configured ASR model and verifies it exists in the provider model list, instead of only checking endpoint/auth reachability.

Constraint: Keep existing settings flow and IPC shape with minimal UI change

Rejected: Add a new ASR test-audio transcription request | adds latency and provider-specific request complexity

Confidence: high

Scope-risk: narrow

Directive: Keep validate and fetch-models semantics aligned; validate should fail when configured model cannot actually be selected

Tested: npm run build; cargo check -q

Not-tested: Manual Settings UI interaction against live third-party ASR endpoints
2026-05-04 20:27:08 +08:00
H-Chris233 2861a30cbe Add end-of-file acknowledgements for sponsors, developers, and LinuxDo community
README updates now place a unified acknowledgement section near the end (before License) in both English and Chinese, explicitly thanking sponsors, developers/contributors, and the LinuxDo community with a neutral non-endorsement disclaimer.

Constraint: Keep existing sponsor/developer showcase blocks intact while adding final acknowledgement wording

Rejected: Put acknowledgement near top profile blocks | user requested end-of-file placement

Confidence: high

Scope-risk: narrow

Directive: Keep acknowledgement wording neutral and avoid implying official affiliation

Tested: Manual README markdown diff review

Not-tested: Render preview in GitHub UI
2026-05-04 20:26:11 +08:00
baiqing ac2edbe961 ci(release): wxs 用 env 绝对路径定位 IME DLL
之前 light.exe 失败的根因:openless-ime.wxs 的 Source 写的相对路径
src-tauri\target\windows-ime-msvc\... ,要从 openless-all/app/ 才能
resolve;但 Tauri 内置 wix bundler 的 candle/light cwd 是 src-tauri/,
路径错位,文件找不到 → light 失败。

本地 windows-package-msvc.ps1 通过 Repair-TauriMsiBundle 从 appRoot 手动
跑 light 兜底,CI 没有这个兜底所以挂掉。

修法:wxs Source 改用 $(env.OPENLESS_IME_DLL_X64) / _X86 绝对路径变量;
工作流的 IME build 步骤把绝对路径写到 $GITHUB_ENV。这样无论 candle/light
cwd 在哪,都能拿到正确的 DLL 路径。

本地脚本本就 set 这两个 env var(windows-package-msvc.ps1:213),改后
本地 + CI 共用同一条 absolute-path 路径,Repair fallback 不再必需。
2026-05-04 20:04:18 +08:00
baiqing f0040d0dd1 ci(release): build Windows IME DLLs before tauri bundle
openless-ime.wxs 引用 src-tauri\target\windows-ime-msvc\{x64,x86}\Release\
OpenLessIme.dll;release-tauri.yml 之前没有构建这两个 DLL 的步骤,导致
WiX light.exe 链接 MSI 时找不到文件,Windows 发版全挂。

复用本地 windows-package-msvc.ps1 同款方案:在 tauri build 之前调
windows-ime-build.ps1 编译 x64 + Win32 两个 Release DLL 到对应路径。
windows-latest runner 自带 VS Build Tools / vswhere,windows-ime-build.ps1
里的 Find-MSBuild 会自动定位。
2026-05-04 19:30:08 +08:00
baiqing 72ebe76be0 chore(release): 1.2.14
包含自 1.2.13 以来的修复与新功能:
- feat(autostart): 跨端开机自启 (#194)
- feat(asr): SiliconFlow / GLM-ASR / Groq / OpenAI Whisper preset (#212)
- fix(qa): Windows / Linux 划词追问浮窗 Esc + 拖拽 + 文案 (#205 / #206)
- fix(settings): preset 切换 race + per-provider 凭据隔离 (#219 / #220)
- fix(overview): 概览整屏适配 + 嵌套 scroller 细滚动条 (#243 / #248)
- 一系列 Windows IME (TSF) 模块 (#233 / #240 等)
2026-05-04 18:58:03 +08:00
Chris233 5d15f1d2f2 Merge pull request #241 from H-Chris233/main
security(qa): sanitize assistant markdown rendering in QA panel
2026-05-04 18:52:05 +08:00
TRIP 0ddd04fafb Merge pull request #248 from appergb/fix/overview-no-scroll-243
fix(ui): 概览页整屏不滚 + 其他页 scrollbar 变细 (#243)
2026-05-04 18:44:45 +08:00
baiqing fd0b2fdf02 fix(overview): Codex P1 + P2 — 保留 fallback scroll + 嵌套 scroller 同步细化
Codex P1:之前 displayTab==='overview' 时 wrapper 用 overflow:hidden,
窗口被压缩或文案变长(i18n / 字体放大)后底部 Recent Card 整片不可达,
没有 scroll 兜底路径。

修法:所有 tab 一律 overflow:auto。Overview.tsx 内部已经用 flex 把底部
行 grow 到撑满 → 正常尺寸下内容刚好占满,浏览器不显示 scrollbar;真挤
不下了 fallback 出细 scrollbar。"整屏不滚"的视觉效果保留,但有 scroll
保险。

Codex P2:::-webkit-scrollbar 不级联到子节点,所以 .ol-thinscroll 加
在 wrapper 上对 History / SettingsModal 等内层 overflow:auto 容器无效。
把 className 显式补到这些嵌套 scroller:
- History 左侧列表 + 右侧详情 Card(Card 组件加 className prop 透传)
- Settings.tsx 内嵌模式右栏
- SettingsModal personalize/about 块
QaPanel 是独立窗口,不在主壳 thinscroll 范围内,保留默认。
2026-05-04 18:26:34 +08:00
baiqing 8b435b4844 fix(overview): 底部行 flex:1 + 仅最近识别区域滚动
#243 第一版给外层 wrapper 加了 overflow:hidden 让概览不滚,但底部「近 7 天 +
最近识别」grid 仍按自然高度展开 → 内容超出 wrapper 时被硬裁,看不到底部
圆角;最近识别第 5 行只露半截。

修法(Overview.tsx 底部 grid):
- grid 自身 flex:1, minHeight:0,撑满父 flex:column 的剩余高度
- 两张 Card 都加 display:flex/column + minHeight:0;最近识别 Card 还加
  overflow:hidden,让内层行严格剪裁到 Card 的圆角
- 最近识别的 list <div> 加 .ol-thinscroll + flex:1 + overflow:auto,自己
  独立滚动;其他区域按需求保持不滚

视觉效果:底部圆角现在完整显示并与上方 metrics / providers 对齐;只有最
近识别区域出现细滚动条,整体仍是 dashboard「一眼看完」节奏。
2026-05-04 18:19:22 +08:00
H-Chris233 806fa26693 Keep QA code snippets readable while preserving markdown XSS guard
Review feedback found that pre-escaping the entire markdown payload caused double-encoding in inline/fenced code, making HTML/JSON/XML examples unreadable. Switch to raw markdown parsing with renderer-level HTML token escaping so code formatting stays readable while raw HTML remains inert.

Constraint: Maintain issue #221 security boundary without broad sanitizer rewrite

Rejected: Keep full-string pre-escape | breaks code snippet readability

Confidence: high

Scope-risk: narrow

Directive: Escape only raw HTML tokens, not the whole markdown source

Tested: npm run build (openless-all/app)

Not-tested: Manual QA panel rendering across all markdown edge cases
2026-05-04 18:06:51 +08:00
baiqing b41c904104 fix(ui): 概览页整屏不滚 + 其他页 scrollbar 变细 (#243)
FloatingShell.tsx 的 page wrapper:
- displayTab === 'overview' 时 overflow:hidden,让 Overview 真"一眼看完"
- 其他 tab 维持 overflow:auto,加上 .ol-thinscroll 让 scrollbar 细而可见

tokens.css 新增 .ol-thinscroll —— 与既有 .ol-noscrollbar 同位置;区别是
"细而仍可见",保留可滚动的视觉 affordance(不像 noscrollbar 完全隐藏)。

Closes #243
2026-05-04 18:02:25 +08:00
H-Chris233 d397f92cd7 Restore QA single-newline rendering behavior
Code review flagged a UX regression after sanitizer refactor: assistant single newlines stopped rendering as hard breaks. Re-enable marked breaks mode in the shared QA renderer to preserve previous panel readability for streamed and lightly formatted answers.

Constraint: Keep sanitizer fix while matching prior QA markdown display behavior

Rejected: Add newline post-processing in QaPanel | duplicates renderer concern and increases drift risk

Confidence: high

Scope-risk: narrow

Directive: QA markdown display flags must be centralized in qaMarkdown.ts to keep streaming/final parity

Tested: npm run build (openless-all/app)

Not-tested: Manual visual QA panel check on desktop runtime
2026-05-04 17:47:59 +08:00
H-Chris233 7edd0cde9e Close reviewer-found QA markdown sanitizer gaps
Two parallel reviews flagged a high-risk fallback path and a link-encoding regression in the new QA sanitizer. This patch keeps the minimal #221 approach while ensuring failure fallback stays inert and safe links preserve query strings correctly.

Constraint: Preserve minimal change scope for issue #221

Rejected: Expand into CSP/capability hardening in same patch | out of issue scope and higher blast radius

Confidence: high

Scope-risk: narrow

Directive: Never return raw model output into dangerouslySetInnerHTML fallback paths

Tested: npm run build (openless-all/app)

Not-tested: Manual desktop exploit reproduction on Windows/macOS
2026-05-04 17:33:52 +08:00
H-Chris233 a57978e739 Harden QA markdown rendering to block WebView script injection
Issue #221 requires closing the QA markdown XSS surface without broad CSP or architecture changes. This switches assistant and streaming markdown to one shared safe renderer that escapes raw HTML and rejects non-http(s)/mailto/tel links.

Constraint: Keep markdown readability while preventing executable HTML in QA WebView

Rejected: Add DOMPurify dependency | avoid new dependency for minimal fix

Confidence: medium

Scope-risk: narrow

Directive: Keep streaming and final assistant rendering on the same sanitizer path

Tested: npm run build (openless-all/app)

Not-tested: Manual malicious payload interaction in packaged desktop app
2026-05-04 17:21:26 +08:00
Chris233 f87e598044 Merge pull request #240 from H-Chris233/main
fix(windows): make QA panel close button clickable
2026-05-04 17:12:15 +08:00
H-Chris233 337eaeb7ef Restore Windows QA no-activate contract without breaking close interaction
Issue #239 required the close button to be clickable, but a plain window.show() regression can steal focus and break selection capture assumptions in QA flow. Keep an explicit no-activate show on Windows while simplifying the native call path to only SW_SHOWNOACTIVATE.

Constraint: QA panel must not steal foreground focus when opening

Rejected: Keep plain window.show() | violates non-activation contract and risks wrong selection source

Confidence: medium

Scope-risk: narrow

Directive: If Windows QA show logic changes again, verify both close-button clickability and front-app selection capture

Tested: cargo check -q (openless-all/app/src-tauri)

Not-tested: Manual Windows interaction on physical device
2026-05-04 17:09:58 +08:00
Chris233 d81bbc4261 Merge pull request #233 from H-Chris233/main
feat(vocab): 增加词汇表场景预设
2026-05-04 16:45:34 +08:00
H-Chris233 647fc2ded0 Fix autostart runtime loading and preset apply disabled-term behavior
Address review feedback by removing fragile runtime import of the autostart
plugin package and invoking plugin commands via Tauri core bridge, so production
bundles no longer depend on unresolved bare imports.

Also update preset batch apply to re-enable existing disabled terms and continue
processing remaining terms/presets when one add operation fails.

Constraint: Minimal changes limited to existing Settings/Vocab flows
Rejected: New backend batch endpoint for preset apply | broader cross-layer change
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Preset apply should be idempotent and restore disabled matching terms
Tested: npm run build
Not-tested: Manual autostart toggle check on packaged desktop build
2026-05-04 16:33:50 +08:00
H-Chris233 47069cea4a Harden preset save/apply against partial failures
Preset edits were applied to local UI state before persistence finished, so
storage failures could show a misleading saved state and then lose changes on
reload. Also, batch apply aborted on first add_vocab error and skipped later
selected presets.

Make preset save await persistence before mutating UI/closing editor, and make
batch apply continue across per-term failures while reporting aggregated errors.

Constraint: Minimal behavior fix within existing Vocab page flow
Rejected: Add transactional backend endpoint for batch apply | larger cross-layer change
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep UI success states aligned with durable persistence completion
Tested: npm run build
Not-tested: Manual readonly-disk simulation for persist failure
2026-05-04 16:25:03 +08:00
H-Chris233 f2122dc4f9 Persist only user preset deltas to keep builtin updates receivable
Saving presets previously wrote the merged list (including built-ins) into user
storage, which froze old builtin copies and shadowed future app updates with the
same preset ids. Switch preset persistence to a delta store: custom presets,
overrides for edited built-ins, and disabled builtin ids.

Constraint: Keep current preset UI and command names unchanged
Rejected: Force builtin presets to always overwrite user file | would discard intentional user edits
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Never persist untouched builtin presets into user store
Tested: cargo test vocab_presets_roundtrip_json_file -q; npm run build
Not-tested: Manual end-to-end UX for builtin delete/restore (no delete UI yet)
2026-05-04 16:10:39 +08:00
H-Chris233 d1b4adbff8 Keep built-in vocab presets available after user saves custom presets
Loading presets from app-data JSON previously replaced bundled defaults entirely,
so adding any custom preset made shipped scenarios disappear on the next load.
Merge user presets onto bundled defaults by id so built-ins always remain
available while still allowing user overrides.

Constraint: Minimal change in preset loading path without altering storage schema
Rejected: Persist defaults into user file on first run | unnecessary write churn and migration complexity
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Preserve default+user merge behavior when adding future preset sources
Tested: npm run build
Not-tested: Manual Tauri UI check for merged list ordering
2026-05-04 16:09:45 +08:00
H-Chris233 91dd39932d Prevent unsaved preset drafts from polluting persisted storage
New preset previously persisted an empty entry immediately on click, so cancel
or navigation left permanent junk rows without any delete path. Keep new preset
as in-memory draft and persist only after explicit save.

Also add a regression test for vocab preset JSON persistence roundtrip to cover
the new preset storage workflow with automated verification.

Constraint: Minimal UI change without introducing preset delete UX in this patch
Rejected: Auto-delete blank presets on load | implicit cleanup can remove user-intended drafts
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep create flow non-persistent until user confirms save
Tested: cargo test vocab_presets_roundtrip_json_file -- --nocapture; npm run build
Not-tested: Manual UX walkthrough for preset draft cancel across app restart
2026-05-04 16:09:45 +08:00
H-Chris233 21da4f912d Unblock web build by lazy-loading autostart plugin in Settings
The frontend build failed because the autostart plugin import could not be
resolved in the browser-targeted Vite bundle, and strict TS also flagged
implicit any in the same flow. Switch the autostart integration to runtime
lazy-loading behind the Tauri guard and type the callback parameters explicitly.

Constraint: Keep autostart UX behavior unchanged on Tauri runtime
Rejected: Add Vite external alias for plugin package | hides integration mismatch in app code
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Tauri-only plugin modules should stay runtime-gated to keep web build healthy
Tested: npm run build (openless-all/app) passed
Not-tested: End-to-end autostart toggle interaction on all desktop platforms
2026-05-04 16:09:45 +08:00
H-Chris233 9f8e9650e0 Add vocabulary presets with JSON-based repo and user storage
Issue #224 requires scenario presets with multi-select apply and editable custom
presets, while preparing for import/export. This revision moves built-in presets
into a repository JSON file and stores user presets in the app data directory as
JSON via Tauri commands, so preset persistence uses one JSON shape both in repo
and user space.

Constraint: Keep vocabulary entry backend and UI interaction model unchanged
Rejected: Keep presets in localStorage/TS constants | does not satisfy unified JSON storage requirement
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Preserve vocab-presets JSON schema compatibility for future import/export
Tested: cargo check (src-tauri) passed
Not-tested: npm build currently fails on pre-existing Settings.tsx typing issues unrelated to this change
2026-05-04 16:09:09 +08:00
Chris233 4b53310f75 Merge pull request #210 from millionart/main
[codex] Add Windows TSF IME insertion backend
2026-05-04 13:37:00 +08:00
millionart ec16958d4d fix: restore IME before abort idle 2026-05-04 13:15:49 +08:00
millionart 9e2c79598a fix: classify Windows IME focus failures 2026-05-04 12:37:56 +08:00
millionart 1de10d32ae fix: skip stale Windows IME session restores 2026-05-04 11:58:18 +08:00
millionart 77eb569468 fix: restore IME profile after activation failure 2026-05-04 11:11:21 +08:00
millionart e040caebf9 fix: extend Windows IME submit timeout 2026-05-04 10:48:23 +08:00
millionart 104793cf18 merge upstream main into Windows IME PR 2026-05-04 10:23:42 +08:00
millionart 2554259d80 fix: harden Windows IME review edge cases 2026-05-04 10:17:56 +08:00
Chris233 1a8f4aac2c Merge pull request #220 from appergb/fix/preset-switch-race-219
fix(settings): 切换 LLM/ASR preset UI 不刷新 (#219)
2026-05-04 09:21:40 +08:00
baiqing 1eec2fa21c fix(settings): 拆 committed*Provider 让受控 <select> 立即响应 (#220 P2)
Codex P2: 上一版把 setLlmProvider/setAsrProvider 挪到所有 await 之后,
受控 <select> 的 value 现在依赖 IPC 完成顺序——用户连点两次时,先发的
请求晚到会用旧 id 覆盖最新的 setProvider,UI 卡在错误选项上。

修法(state 二分):
- *Provider:立即跟随用户输入,驱动 <select>
- committed*Provider:仅在所有 await 完成后才 commit,驱动 CredentialField
  的 key 与 placeholder/preset 的渲染
- *SwitchSeqRef:每次进入 handler 自增,每段 await 后比对,发现已有更新的
  switch 在飞就 abort 当前 commit,stale write 保护

效果:
- 用户切换 <select> 立刻看到新选项(受控反馈正确)
- CredentialField 等到后端 active 真切完才 remount 读 entry(issue #219 修复保留)
- 100ms 内连点两次:只有最后那次的 commit 落地,UI 不会被旧请求覆盖
2026-05-04 09:04:41 +08:00
baiqing 1accecbd57 fix(settings): 切换 LLM/ASR preset 顺序错导致 UI 显示旧 active 凭据
底层 providers HashMap 已是 per-provider,bug 完全在前端两个 onChange:

1) Race
setLlmProvider(id) / setAsrProvider(id) 是同步 React state 改动,
CredentialField 用 `key={`${provider}:api_key`}` 强制重挂载、读后端
ark.api_key —— 但此时 await setActive*Provider 还没跑,root.active.llm
还是旧值,lookup_account 落到旧 entry。把 await setActive 移到
setLlm/AsrProvider 之前修。

2) 覆盖
旧实现无条件 setCredential('ark.endpoint', preset.baseUrl),把用户在
该 provider 上之前自定义的 baseUrl 覆盖掉。改成「仅在 entry 该字段
为空」才填默认值,保留用户自定义。ASR 端的 endpoint + model 同款修。

不动 persistence schema、不动 IPC、不动 coordinator。

Closes #219
2026-05-04 08:44:37 +08:00
Chris233 bdd4cb1c7d Merge pull request #217 from appergb/feat/autostart-194
feat(autostart): macOS / Linux / Windows 三平台开机自启
2026-05-04 08:09:13 +08:00
TRIP e4f6f2eb43 Merge pull request #206 from appergb/fix/windows-qa-panel-205
fix(qa,windows): 划词追问浮窗读用户当前录音键 + Windows 加 toolbar 拖拽 (#205)
2026-05-04 07:33:28 +08:00
baiqing 07c083d9a1 fix(autostart): toggle 失败给用户看错误,不再吞到 console (#194)
原版 AutostartRow 的 onToggle catch 只 console.error + 回滚,
失败完全不在 UI 上反馈:Windows 写 HKCU\Run 被组策略拦、
macOS LaunchAgent plist 写入失败 这些真实场景下,用户只看到
toggle 弹回去,根本不知道为什么。

补一个 error state:
- onToggle 进入清 null,catch 里 setError(message)。
- SettingRow children 改成 flex column:toggle 上面、错误小字下面。
- 配色 var(--ol-err) 跟 about 卡片的 update error 同款。
- i18n 加 settings.recording.startupAtBootError,{{message}} 插
  入插件抛的具体错。

不动 isEnabled 失败路径(#194 验收没列);不动 prefs 持久化
策略(仍由 OS 持有真相)。
2026-05-04 07:33:00 +08:00