Commit Graph
597 Commits
Author SHA1 Message Date
millionart 70455aa2a1 Merge remote-tracking branch 'upstream/main' into codex/windows-local-asr
# Conflicts:
#	openless-all/app/src-tauri/src/lib.rs
#	openless-all/app/src-tauri/src/types.rs
#	openless-all/app/src/lib/ipc.ts
#	openless-all/app/src/pages/Settings.tsx
2026-05-07 12:23:41 +08:00
millionart 33c253849e fix: address Settings review feedback 2026-05-07 12:19:46 +08:00
Chris233 19f4f64cd5 Restore Intel Mac release coverage (#317)
The release matrix had kept Intel macOS disabled because the old macos-13 pool was deprecated and repeatedly stalled releases. GitHub now exposes an explicit Intel runner label, so the release lane can be restored without returning to the unstable macos-13 runner.

Constraint: Intel Mac release artifacts must be produced separately from Apple Silicon artifacts

Rejected: Re-enable macos-13 | that runner was explicitly disabled due to deprecation and queue instability

Confidence: high

Scope-risk: narrow

Directive: Keep macOS updater artifact names architecture-qualified when multiple darwin lanes are active

Tested: git diff --check

Tested: Parsed release-tauri.yml matrix and verified macOS arm64/x86_64 lanes plus arch-specific updater paths

Not-tested: Full GitHub Actions release run
2026-05-07 12:19:06 +08:00
kaku.ki ec773f08ea feat(settings): add microphone device selection (#306) 2026-05-07 12:15:56 +08:00
millionart 0bb8d3ebcd merge upstream main into windows local asr 2026-05-07 11:48:25 +08:00
millionart a15e6f256e merge main and preserve Foundry selection 2026-05-07 11:44:56 +08:00
Chris233 ed555fb5a5 Merge pull request #309 from H-Chris233/fix/issue-303-log-rotation
fix(ops): 为 openless.log 增加启动轮转
2026-05-07 11:27:42 +08:00
millionart 593cf766a2 fix: clean up Foundry transcribe failures 2026-05-07 11:15:12 +08:00
H-Chris233 275a11e3e5 Prevent startup logs from growing without bounds
Long-running tray installs can accumulate an unbounded openless.log. Startup now checks the current log after single-instance arbitration but before simplelog opens the file, then rotates files over 10 MiB to openless.log.1. Normal append logging resumes with a fresh current log and log export continues to copy only openless.log.

Rotation remains best-effort: startup continues if archive cleanup or rename fails, but stderr receives an explicit warning so the failure is diagnosable even before the file logger is initialized. Boundary tests cover oversized, small, and missing log files.

Constraint: Issue #303 asks for a minimal startup size check with openless.log.1 archive.
Constraint: Duplicate macOS/Linux launches must exit before rotation so they cannot rename the owning instance's active log file.
Rejected: Add tracing-appender rolling support | new dependency and wider logging rewrite for a low-risk ops fix.
Rejected: Add platform-specific rotation-failure tests | brittle across Linux/macOS/Windows file locking semantics.
Confidence: high
Scope-risk: narrow
Directive: Keep export_error_log focused on openless.log; do not include rotated archives unless product explicitly asks for history export.
Directive: Keep log rotation best-effort; startup must continue even if archive cleanup or rename fails.
Tested: cargo test --manifest-path src-tauri/Cargo.toml log_
Tested: cargo check --manifest-path src-tauri/Cargo.toml
Tested: git diff --check
Not-tested: Manual startup rotation on Windows/macOS.
Related: #303
2026-05-07 11:10:21 +08:00
TRIPandbaiqing 32f2df31ee Add Claude Code GitHub Workflow (#308)
* "Claude PR Assistant workflow"

* "Claude Code Review workflow"

* ci(claude): 收紧 review 触发:只 OWNER @claude 才跑,默认 Sonnet 4.6

- 删除 claude-code-review.yml:原本 PR opened/sync 自动触发会无差别烧 OAuth 额度
- claude.yml if 加 author_association == 'OWNER' 门禁:只有仓库 owner 评论 @claude 才触发
- 加 Pick model step:默认 claude-sonnet-4-6;评论包含 --opus / claude-opus 时切 claude-opus-4-7
- 用 env 注入 body / title 而不是直接 inline expression,避免外部内容引号注入

---------

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-07 10:46:53 +08:00
millionart 5c92e87bc6 fix: initialize coordinator hotkey fields on macos 2026-05-07 10:46:44 +08:00
millionart b1cf0d4b36 fix: cancel Foundry prepare before release 2026-05-07 10:39:51 +08:00
millionart 3d4d82f23d fix: cancel Foundry prepare with provider 2026-05-07 10:38:12 +08:00
millionart a54ca77e9b fix: guard Foundry release and cancel stale transcripts 2026-05-07 10:08:36 +08:00
millionart 2290a6cbee merge upstream main into windows local asr 2026-05-07 09:37:24 +08:00
millionart b3c5554da7 merge upstream main into windows local asr 2026-05-07 09:34:39 +08:00
TRIP 2c9dca531d Merge pull request #307 from appergb/fix/post-pr236-i18n-selectionask-ui
fix(i18n,ui): 修 PR #236 合并后 ja/ko 缺键 + SelectionAsk 启用开关右置
2026-05-07 09:33:17 +08:00
baiqing 1e04433443 fix(i18n,ui): 补 ja/ko 缺失 key + SelectionAsk 启用开关右置
PR #236 合并后两处后续修复:

1. ja.ts / ko.ts 缺 PR 引入的 7 个 comboRecord* 键和 1 个
   triggers.custom 键,导致 main 的 npm run build 直接 TS 报错。
   补齐后 tsc 通过。

2. SelectionAsk 划词追问页:触发快捷键卡片把"右上角状态徽标 +
   下方启用按钮"换成与 Style 页一致的右上角 36×20 toggle;
   保存历史卡片同步从底部 44×24 开关改成右上角同款 toggle。
   抽出 CardHeaderToggle 复用,跟 design_handoff Style 页对齐。
2026-05-07 09:27:59 +08:00
TRIP 98da5970bf Merge pull request #236 from LeslieLeung/feature/key-binding
feat: add configurable shortcut bindings
2026-05-07 09:24:33 +08:00
millionart 60b4d45823 fix: restore Foundry model on prepare failure 2026-05-07 09:03:51 +08:00
Chris233 69e566277d Merge pull request #264 from weikeyi/capsule-windows-shadow-inset
fix(capsule): center Windows pill within shadow inset
2026-05-07 00:04:25 +08:00
millionart eaab08148f fix: use Foundry ASR keep-loaded TTL 2026-05-06 23:38:54 +08:00
weikeyi 62005a6391 test(capsule): tighten host centering regex 2026-05-06 23:32:28 +08:00
weikeyi 94e9686a45 fix(capsule): restore non-windows box sizing contract 2026-05-06 23:18:16 +08:00
millionart 0421ced5be fix: split Foundry prepare and transcription timeouts 2026-05-06 23:06:38 +08:00
millionart 4dc0246022 fix: bound Foundry ASR transcription wait 2026-05-06 23:01:32 +08:00
millionart f358260866 merge upstream main into windows local asr 2026-05-06 21:28:41 +08:00
baiqing d5fa5b7df3 chore(release): 1.2.21
主要修复
─────────
- fix(windows): TSF DLL 静态链接 CRT,防 host 进程(QQ 等)私有
  MSVCP140 劫持导致切微软拼音崩溃 0xc0000005(PR #287 + #289 + Codex
  P1 review)。
- fix(windows): 移除 DisableThreadLibraryCalls — /MT 下 CRT 需要
  thread attach/detach 通知做 per-thread TLS 清理,禁用反而触发崩溃。
- fix(recording): 录音条出现时 mic 已 capture,按 Option 不再吞开头
  字。emit Recording 加 race 检查避免短按时覆盖 stop/cancel UI 信号。
- fix(startup): splash 透明背景 + 卡片化,避免长启动时左半白屏。
- fix(vault): keyring chunks 用稳定 account name —— macOS Keychain
  Always-Allow 不再因 UUID 轮换失效;不再每次 load 都尝试删 9 个
  legacy entries 触发 ACL 弹窗(与 PR #277 一起)。

新功能
─────────
- feat(security): 凭据从 plaintext JSON 迁移到平台 credential vault
  (macOS Keychain / Windows Credential Manager / Linux libsecret)。
  Windows 2560 byte 限制下用 chunked storage;partial-write safe。
  legacy 多源迁移完成后自动清理(PR #277)。

工程
─────────
- chore(ci): 暂时搁置 macos-13(Intel mac)matrix —— GH Actions
  runner pool 紧张到每次 dispatch queue 1-2h(已观测 4 次)。Apple
  Silicon 用户 dmg 仍发;Intel mac 用户保留 v1.2.20 dmg + Rosetta
  说明(issue #299)。
- chore(devex): CI 加 macOS 矩阵 + 5-way 版本号一致性校验 +
  scripts/bump-version.sh 一行同步 5 处版本号。.gitignore 加
  promo-openless-v2 / node_modules / dist / target 全局兜底(PR #294)。
- docs: docs/audit-2026-05-06.md 工程审计基线,覆盖架构 / UI bug /
  多端一致性 / IPC 1:1 校验 / P0/P1/P2 改进路径。
- chore: 9 个改进 issue (#295-#303) 跟踪 audit 列出的所有 P1/P2/P3
  问题。
2026-05-06 21:24:51 +08:00
TRIP b9adb6cf67 Merge pull request #294 from appergb/chore/ci-quality-gate-and-version-bump
chore(devex): CI 加 mac 矩阵 + version-triplet 校验 + bump-version.sh
2026-05-06 21:24:10 +08:00
millionart a1d6e59a1c fix: address Foundry ASR review feedback 2026-05-06 21:18:15 +08:00
baiqing 97fca4abab fix(devex): bump-version 修 BSD sed / lock 失败吞错 / package-lock 未同步
Codex 在 PR #294 上提了 3 个 P2,全部采纳:

P2-A: BSD sed 不支持 GNU 行号范围 0,/.../
  原 sed -E -i.bak "0,/^version = .../s//.../" 在 macOS 默认 BSD sed 上
  会 fail。换成 awk first-match 替换(mac BSD awk + GNU awk 都支持)。

P2-B: Cargo.lock 同步失败被 `|| true` 吞了
  原 cargo update -p openless ... || true 会让脚本继续,validate 又只
  校验 Cargo.toml 不校验 Cargo.lock。删 || true,让 set -euo pipefail
  在 cargo update fail 时立刻退出;同时 validate 加 Cargo.lock 校验。

P2-C: package-lock.json 未跟着同步
  npm 把 root version 也存在 package-lock.json 里(root + packages['']
  两处)。原脚本只 sed package.json 不更 lock,会让 npm ci 在 CI 出现
  EUSAGE。换成 npm version --no-git-tag-version --allow-same-version
  一次更两个文件。

ci.yml 的 verify step 也升级到校验 5 处一致:
  package.json / package-lock.json root+nested / tauri.conf.json /
  Cargo.toml / Cargo.lock 的 [openless] 包。

dry-run 已验证(用当前版本 1.2.20 跑一遍输出全部一致)。
2026-05-06 21:04:28 +08:00
millionart 091bbdc2f3 fix: release inactive Foundry runtime 2026-05-06 21:00:29 +08:00
baiqing 938c6a74b9 docs: 工程审计基线 (audit-2026-05-06.md)
完整工程审计报告(系统化逐项检查):
- 后端架构总评 + 5 个 P1/P2 优化点(coordinator/commands 拆分等)
- 前端 4 个 UI bug(tab 切换竞态、流式滚动打断 QA 等)
- 工程化水平评估 + 4 条改善(CI 门禁 / E2E / gitignore / 版本号)
  → 其中 3 条已在本 PR 实现(CI matrix + gitignore + bump-version 脚本)
- 多端逻辑与体验一致性表(macOS vs Windows 平台差异 vs 行为一致性)
- UI/后端 IPC 1:1 映射校验(全部命令前后端对齐 ✓)
- 改进建议汇总:P0 无;P1 5 项;P2 6 项
- 总结:项目整体健康,建议下迭代处理 coordinator 拆分 + 前端动画竞态

把这份基线纳入 git,让 main 留下 v1.2.20→v1.2.21 这一阶段的工程现状
锚点,后续审计有 baseline 对照。
2026-05-06 20:57:38 +08:00
millionart 4fa34b486e merge upstream main into windows local asr 2026-05-06 20:55:25 +08:00
baiqing b997f5fca2 chore(devex): CI 加 mac 矩阵 + version-triplet 校验 + bump-version.sh
审查反馈:
1. CI 缺质量门禁 — 仅 windows-latest 1 job,mac 端 cargo check 路径
   无 PR-time 验证,每次 release-tauri.yml 才暴露平台问题
2. .gitignore 不全 — promo-openless-v2/ 反复出现在 git status;
   node_modules / dist / target 没全局兜底
3. 版本号同步风险 — package.json + tauri.conf.json + Cargo.toml 三处
   人工改,每次发版都担心漏一处

改动:

A. .github/workflows/ci.yml
   - 单一 windows-tauri job → matrix(macos-latest + windows-latest)
   - mac job:cargo check + npm run build 验证跨平台编译
   - Windows job:保留原 preflight + ps1 tokenize
   - 新加 step:Verify version triplet stays in sync(两端都跑)—
     一旦 package.json / tauri.conf.json / Cargo.toml 三处 drift 立刻
     fail,给发版工程加 long-running guard

B. .gitignore
   - 加 promo-openless-v2/(已实测出现在 untracked)
   - 加 node_modules/ + dist/ + target/ 全局兜底(避免某子目录漏配
     时 build artifact 进 PR)
   - 加 .cargo/registry / .cargo/git 兜底

C. scripts/bump-version.sh(新文件)
   - 1 个参数(X.Y.Z),sed 同步改 3 个文件 + cargo update -p openless
     同步 Cargo.lock
   - 验证三处一致后输出后续 git 操作建议
   - 跨 macOS sed / GNU sed 兼容(-i.bak 后 rm)

下次发版:./scripts/bump-version.sh 1.2.21 一行搞定。
未来 PR 漏改版本号 CI 立刻 fail,不需要靠人记忆。
2026-05-06 20:55:03 +08:00
millionart 018cacad4f fix: skip Foundry transcription timeout 2026-05-06 20:48:26 +08:00
TRIP 095e3127bb Merge pull request #277 from H-Chris233/fix/issue-230-credential-storage-model
对齐凭据存储策略与威胁模型
2026-05-06 20:27:13 +08:00
TRIP c0118ee481 Merge pull request #290 from appergb/chore/skip-macos-13-runner
chore(ci): 暂时搁置 macos-13 (Intel mac) 构建 — GH runner pool 卡死
2026-05-06 20:27:08 +08:00
TRIP 08b5b882f1 Merge pull request #291 from appergb/fix/startup-splash-transparent
fix(startup): splash 透明背景 + 卡片化,避免长启动时左半白屏
2026-05-06 20:27:03 +08:00
baiqing 0505c2fc54 fix(vault): keyring chunks 用稳定名 + 不再每次 load 都删 legacy
用户实测:首次允许 Keychain 后仍反复弹窗十几次。

根因:
1. save_credentials 每次都生成新 UUID 作为 chunk account 命名前缀
   (credentials.v1.chunk.<NEW_UUID>.0/.1)。macOS Keychain 的「始终允许」
   绑定到 (binary 签名, entry 名),每次保存设置都让 chunk entry 名变 →
   之前 ACL 全失效 → 重新弹。
2. load_credentials / load_credentials_for_update 每次都调
   remove_legacy_keyring_credentials() —— 对 9 个旧 stable account
   各做一次 keyring delete。delete 在 macOS 上仍触发 ACL 检查,
   每次 load 都弹 9 次「OpenLess 想删除 X」。

合计每次 IPC 触发的 load 12 次弹窗,跟实测吻合。

修复(数据安全优先):

A. chunk account 命名稳定化
   - chunk_account(generation: Option<&str>, idx) 接受可选 generation
   - save_credentials 总用 None(稳定 credentials.v1.chunk.{idx})
   - 新 manifest 不写 generation 字段(serde skip_serializing_if=None)
   - 旧 manifest 仍可读(generation: Option<String>,含 UUID 时按旧格式
     读)→ 一次 save 后无缝迁移到新格式 + 删除旧 UUID chunks

B. partial-write 安全
   - 仍保留「先写所有 chunks,再写 manifest」顺序
   - chunks 数量减少时主动删除 idx >= new count 的旧 entries
   - 旧 UUID chunks 保留删除路径(迁移用)

C. legacy keyring delete 仅在 migration 路径触发
   - load_credentials / load_credentials_for_update 不再调用
     remove_legacy_keyring_credentials()
   - migrate_legacy_sources_for_update 内部仍调用一次 → 首次成功迁移
     就清干净;之后 load 不再尝试 delete 不存在的 entries
   - legacy 文件 delete 不需 ACL,best-effort 调用保留

D. 不影响 Windows
   - Windows Credential Manager 没有 ACL 弹窗概念
   - 仍走 chunked storage(2560 byte 限制需要分块)

修复后体感:
- 首次启动迁移:~3 次弹(manifest + 2 chunks),用户点 Always Allow
- 之后启动 / 保存设置:0 次弹(ACL 长期有效)
2026-05-06 20:18:02 +08:00
millionart 2a03f15292 Merge remote-tracking branch 'upstream/main' into codex/windows-local-asr
# Conflicts:
#	openless-all/app/src-tauri/Cargo.lock
#	openless-all/app/src-tauri/src/commands.rs
#	openless-all/app/src-tauri/src/coordinator.rs
#	openless-all/app/src-tauri/src/lib.rs
2026-05-06 20:15:12 +08:00
baiqing fa30161f52 fix(startup): splash 透明背景 + 卡片化,避免长启动时左半白屏
用户反馈:当启动时间较长时(凭据迁移 / 权限 probe / hotkey hook 还没
ready),窗口左侧出现白色矩形并显示「OpenLess 正在启动」,本应是纯
磨砂玻璃背景。

根因:main window 在 tauri.conf.json 是 transparent + macOSPrivateApi
(NSVisualEffectView vibrancy)。但 StartupShell 之前用:

    background: linear-gradient(180deg, rgba(245,245,247,0.96), ...)

96% 不透明渐变盖过 vibrancy。在窗口内容布局首帧或啥的时候,左侧 paint
StartupShell 浅灰,右侧未完成 vibrancy → 视觉割裂「左白右磨砂」。

修:StartupShell 容器改 background: transparent 让 vibrancy 全屏展开;
提示文字 + icon 用一个圆角 pill 卡片承载(rgba(255,255,255,0.55) +
backdrop-filter blur),跟 Capsule 视觉一致。
2026-05-06 20:05:46 +08:00
millionart 2d07493d40 feat: improve Foundry local ASR setup 2026-05-06 20:02:28 +08:00
baiqing b2868378bf chore(ci): 暂时搁置 macos-13 (Intel mac) 构建
GitHub Actions 把 macos-13 runner 标记为 deprecated,pool 容量紧张到
每次 dispatch 都 queue 1-2h 拿不到分配。已观测 4 次 release run
(25415755417 / 25417633813 / 25419948896 / 25420193625)均因 mac-13
卡 queue 整个 run conclusion 永远不变 success,阻塞自动化判断。

暂时把 macos-13 matrix 项注释掉:
- macOS arm64 (Apple Silicon) 仍发 dmg
- Windows x64 + Linux 不变
- Intel mac 用户在 v1.2.21+ 期间用 Apple Silicon dmg + Rosetta(性能稍降但可用)

恢复条件(任一):
- GH 把 macos-13 pool 容量恢复
- GH 提供 macos-14-x86_64 或 macos-15-large-x86_64 替代 runner
- 项目 self-host runner

恢复方法:删除注释符即可。
2026-05-06 19:49:45 +08:00
TRIP ab65432c1c Merge pull request #289 from appergb/fix/recording-no-swallow-first-words
fix(recording): 录音条出现时 mic 已 capture,不再吞开头字
2026-05-06 19:21:13 +08:00
TRIP 96ca96609f Merge pull request #287 from appergb/fix/windows-ime-static-crt
fix(windows-ime): 静态链接 CRT 防 host 进程 MSVCP140 劫持(修 QQ 切微软拼音崩溃)
2026-05-06 19:21:09 +08:00
baiqing 5c5b5758b6 fix(recording): emit Recording 加 race 检查,避免覆盖 stop/cancel
Codex P2 (PR #289):上一版我把 emit_capsule(Recording) 放到
stop_recorder_if_pending_start_stop 之后,且无条件 emit。这会让短按热键
(用户在 Recorder::start 仍在 cpal init 期间松开)的场景出现 UI 闪烁:
stop / cancel 路径已经发出 Transcribing / Cancelled,本行又把 UI 覆盖
回 Recording,并在 Volcengine 路径的 open_session().await 期间持续保持。

修复(按 Codex 建议):
1. emit 挪到 stop_recorder_if_pending_start_stop 之前
2. emit 之前在同一 lock 内检查 phase / pending_stop / cancelled / session_id;
   只有 recorder 真的会继续运行时才 emit
3. 不满足条件就让 stop / cancel 路径接管 UI 信号

不改变首次说话不丢字的修复目标(emit 仍在 Recorder::start 成功后),
只让 race 路径下的 UI 一致。
2026-05-06 19:13:50 +08:00
baiqing 02dd8c56ea fix(recording): 录音条出现时 mic 已 capture,不再吞开头字
用户反馈:按 Option 键后看到录音条,但开口的前几个字被吞掉。

根因:begin_session() 在 line 1128 立刻 emit_capsule(Recording),但
Recorder::start 还要再走 ~57 行(read creds / new ASR / new bridge /
acquire mute / cpal init),其中 cpal init 在 macOS 上有 50-200ms 启动
延迟。窗口期内:
- 视觉:录音条已显示
- 物理:mic 还没产生第一帧 PCM
- 用户开口的前几个字物理上无法被 capture(不是丢字,是没录到)

DeferredAsrBridge 已经能覆盖 "recorder 已开 → ASR 没连上" 的间隙(缓存
PCM 等 ASR attach 后按顺序后送),但 "录音条已显 → recorder 没开" 这段
之前没人覆盖。

修复(surgical):把 emit_capsule(Recording) 从 begin_session() 挪到
start_recorder_for_starting() 内部 Recorder::start 成功的 Ok 分支里。
三条 ASR 路径(Local Qwen3 / Whisper / Volcengine)共用同一函数,自动
受益。代价是用户按热键到看到录音条多 50-200ms 延迟,但「录音条出现 =
mic 100% 在 capture」体感诚实,开头不再丢。

ASR 慢连接的兜底逻辑(DeferredAsrBridge 按顺序缓冲 + attach 后 drain)
保持不变。
2026-05-06 19:09:32 +08:00
baiqing 901e9dfe3f fix(windows-ime): 移除 DisableThreadLibraryCalls — /MT 下需 thread 通知
Codex P1 (PR #287):DLL 改用 /MT 静态链接 CRT 后,仍调
DisableThreadLibraryCalls(instance) 会让静态 CRT 拿不到 DLL_THREAD_DETACH
通知,per-thread TLS 初始化/清理断裂 — 在 host 进程(QQ / Office /
微软拼音切换)创建新 input thread 时反而把这次想修的崩溃问题重新引回。

Microsoft 文档 DisableThreadLibraryCalls 备注明确:使用 static CRT 的
DLL 不应禁用 thread library calls。

修复:删除该调用;保留 g_module 缓存。
2026-05-06 19:07:54 +08:00
millionart f03499576e fix: show Foundry ASR option on Windows 2026-05-06 18:49:23 +08:00