Commit Graph
612 Commits
Author SHA1 Message Date
kiruno 9543a5a86f feat: Add Homebrew Cask install option (#322)
Adds Casks/openless.rb + update-cask.yml workflow + README install docs. Closes #254 #5.

Note: Formula/openless.rb known to fail in Homebrew sandbox (per author); will be removed in follow-up. Cask version will be bumped to current 1.2.23 in same follow-up.
2026-05-07 20:32:35 +08:00
Hongbro886 32133b3438 关于模型设置-模型下载进度条的若干修复 (#293)
* fix: Various fixes for the model settings - model download progress bar

* fix(local-asr): log partial-size errors and seed redownload progress
2026-05-07 20:21:51 +08:00
Chris233 813d9ec2e9 Merge pull request #324 from H-Chris233/fix/issue-323-llm-providers
增加更多 LLM Provider 预设
2026-05-07 20:19:31 +08:00
Chris233 93dc4b38cd Merge pull request #325 from Cooper-X-Oak/docs/backfill-cooper-developer-entry
docs: backfill developer entry
2026-05-07 20:19:06 +08:00
cooper 188efa7e68 docs: add Cooper to developer list 2026-05-07 19:59:38 +08:00
H-Chris233 336ac9a11c Broaden low-cost LLM provider choices
Issue #323 asks for easier switching to more OpenAI-compatible LLM providers instead of forcing users through a single custom slot. The settings page already stores credentials per active LLM provider id, so the narrow fix is to add practical presets and make provider switching seed the model field only when it is empty.

Constraint: Keep provider storage in the existing system credential vault schema

Rejected: Build named custom profile management | larger UI and persistence surface than needed for the first issue slice

Confidence: medium

Scope-risk: narrow

Directive: New LLM preset ids rely on the generic active LLM credential routing; do not special-case them in backend code unless the provider stops being OpenAI-compatible

Tested: npm run build

Tested: git diff --check

Related: #323
2026-05-07 19:29:51 +08:00
baiqing 5491ef5d33 chore(release): 1.2.23
Hotfix for 1.2.22:
- fix(recorder): macOS 麦克风停录后未释放(cpal Stream::drop 不调
  AudioOutputUnitStop,显式 pause 强制停 callback)
- fix(coord): 录音条等真实开始捕获 PCM 后再弹出,避免短录音漏首字
- fix(localasr): macOS 不再渲染 Windows 专属的 Foundry Local Whisper 卡片
- fix(hotkey): macOS 上 Alt/Meta 键标签显示 Option/Cmd 而非 Alt/Win
2026-05-07 16:57:18 +08:00
baiqing b1a07a4c66 fix(hotkey): macOS 上 Alt/Meta 键标签显示 Option/Cmd 而非 Alt/Win
QA 浮窗(划词追问触发的浮窗)一直在显示 "右Alt" 而不是用户实际按的
"右 Option"。

根因:QaPanel.tsx 用 getHotkeyBindingLabel(prefs.hotkey) → 走
getHotkeyBindingCodes → 把 trigger="rightOption" 通过 legacyTriggerCode
映射成键盘事件 code "AltRight" → getHotkeyCodeLabel("AltRight")
**平台无关**地返回 "右Alt" / "Right Alt"。

而 SelectionAsk 页用 formatComboLabel(prefs.dictationHotkey)(primary
"RightOption" → formatPrimary 走 "rightoption" 分支 → "Right ⌥"),
所以 SelectionAsk 页面是对的,QA 浮窗就显示成了 "Alt"。

同样的平台错配在 MetaLeft / MetaRight:之前一律显示 "Win",macOS
应该是 "Cmd / ⌘";OSLeft / OSRight 同样修复。

修复 getHotkeyCodeLabel:按 currentPlatform().isMac 分流:
- AltLeft  → macOS "左 ⌥" / "Left ⌥",其它 "左Alt" / "Left Alt"
- AltRight → macOS "右 ⌥" / "Right ⌥",其它 "右Alt" / "Right Alt"
- MetaLeft / OSLeft   → macOS "左 ⌘" / "Left ⌘"
- MetaRight / OSRight → macOS "右 ⌘" / "Right ⌘"
- Linux/Windows 路径不变

⌥/⌘ 与 formatPrimary 的输出格式一致,全 app hotkey 标签平台一致。
2026-05-07 16:33:29 +08:00
baiqing 2edaf522cd fix(recorder): 显式 pause cpal Stream 再 drop,释放 macOS 麦克风占用
用户报告:按热键结束录音后麦克风没有被释放(橙色 mic 指示灯不灭、
process_callback 持续打 cb# 日志直到进程退出)。

根因:cpal 0.15 的 Stream::drop 在 macOS coreaudio backend 上不会同步
调 AudioOutputUnitStop,只走 dispose。AudioUnit 的 render callback 仍被
系统调用,process_callback 以 ~5 ms / 帧的速率继续推到 consumer 和
level_handler;macOS 一直认为我们在用 mic,橙点不灭,其它 app 无法独占。

实测日志:
  T=01.786 hotkey 按下 → end_session 启动
  T=02.699 audio-mute released by dictation (rec.stop() 已返回 = 音频
                                              线程已 join 完成 = drop(stream)
                                              已执行)
  T=02.720 cb#750  ← 仍在跑
  T=03.110 cb#800
  …
  T=09.510 cb#2000 ← 直到用户杀进程才停

修复:在 drop(stream) 之前显式 stream.pause()。
StreamTrait::pause 在 cpal coreaudio backend 里直接调 AudioOutputUnitStop,
同步终止 callback;之后 drop 处理 dispose / 资源释放。pause 失败时仅打
warn,不阻塞 drop 路径。

同时在 drop 之后加一行 "cpal Stream dropped (mic released)" 日志,
让以后排查这类问题能直接看到 drop 是否真的执行。
2026-05-07 16:33:12 +08:00
baiqing 43f95a0888 fix(coord): 录音条等真实开始捕获 PCM 后再弹出,避免短录音漏首字
用户报告:说比较短的语音时,开头第一个字偶尔被吞。

根因:start_recorder_for_starting 在 Recorder::start 返回 Ok 后立即 emit
Recording capsule。但 Recorder::start Ok 仅表示 cpal Stream::play 完成,
audio 线程还没开始向 consumer 推 PCM —— macOS CoreAudio AudioUnit 启动到
第一帧 process_callback 中间有 50–200 ms 间隙(Windows 类似)。
用户看到录音条立刻开口,前几个字落在 cpal init 窗口里被吞。

修复:删掉 Recorder::start Ok 之后的立即 Recording emit。
Recording capsule 改由 level_handler 的第一次触发来 emit ——
recorder.rs::process_callback 的执行顺序是 consume_pcm_chunk → level_handler,
所以 level_handler 第一次执行 == PCM 已经真实流到 consumer,从这一刻起
用户说什么都被录到。capsule 自然晚 50–200 ms 出现,但出现 ==
mic 真的在录,匹配「麦先录、UI 再弹」的预期。

短按 / cancel 路径不动:
- stop_recorder_if_pending_start_stop 仍然在 cpal init 期间松键时把 capsule
  切 Transcribing(recorder 已 stop,level_handler 不会再触发)。
- level_handler 内部 phase != {Starting, Listening} 时直接 return,
  不会在 Cancelled / Error 状态上盖回 Recording。
2026-05-07 15:23:38 +08:00
baiqing 95f0b17ff4 fix(localasr): macOS 不再渲染 Windows 专属的 Foundry Local Whisper 卡片
LocalAsr 页面之前无条件渲染 Foundry Local Whisper 区块(标题、模型选择
器、语言 hint、设为默认 / 准备 / 立即释放按钮),macOS 用户进设置 →
模型设置就能看到 Windows 专属的 UI。后端 `foundry_runtime.rs` 早就
按 #[cfg(target_os = "windows")] 把真实实现关在 Win,非 Win 给的是
'only available on Windows' 的 stub —— 前端必须配合,否则一进页面
就发起 status / catalog 拉取并照常渲染整张卡片。

修复方式:用 detectOS() === 'win' 把 Foundry 卡片以及它对应的两个
side effect(refresh() 里的 status/catalog 拉取、prepare-progress
事件订阅)整体 gate 起来。Settings.tsx 的 ASR provider 下拉
(os === 'win' 已过滤 foundry-local-whisper)、allowNonTsfFallback
toggle (capability.adapter === 'windowsLowLevel')、Windows IME 后端
状态行 (windowsIme.state !== 'notWindows') 此前已各自做了 gate,
不需要改动。
2026-05-07 13:27:23 +08:00
baiqing 01aa439686 chore(release): 1.2.22 2026-05-07 13:08:00 +08:00
Chris233 025c23f969 Merge pull request #292 from millionart/codex/windows-local-asr
feat: improve Foundry local ASR setup
2026-05-07 13:00:47 +08:00
millionart e0f7ca2d78 fix: restore frontend Chinese encoding 2026-05-07 12:41:24 +08:00
TRIPandbaiqing 27d42e7303 fix(polish): #305 工作日报场景"清晰结构"无效 + 内置 AI 工具词 (#318)
## 修 #305 polish.rs Structured prompt
- 明确"已结构化 ≠ 不用改":原文是否已有标点 / 编号 / 换行不是判断依据;
  照抄原结构 = 失败
- 重组阈值降到 ≥3 条;即使原文已经是 "1. 2. 3." 也要按主题重新归类成
  双层 (a)(b) 子项,不能扁平照抄
- user_prompt 去掉"它不是问题,也不是任务"这条强 framing —— 旧措辞会
  让 LLM 把书面化输入误判为"已整理好"直接 passthrough(issue #305 截图
  根因)
- 新增 # 示例 3:工作日报场景(已半结构化输入仍要重组)作为回归示例

## 扩充 vocab-presets.json programmer 预设
追加 11 个 AI 工具名:Claude / Codex / Copilot / Cursor / Windsurf /
Anthropic / OpenAI / GPT / ChatGPT / Gemini / DeepSeek。启用 programmer
预设后会同时注入 ASR 热词 bias + polish 提示词的 # 热词 段,覆盖
"cloud → Claude"这类同音误识别。

## 测试
- polish.rs 新增 2 个 #305 回归测试:
  - structured_prompt_forces_regrouping_even_for_already_structured_input
  - user_prompt_no_longer_says_input_is_not_a_task
- cargo test --lib polish: 10/10 passed
- npx tsc --noEmit: clean

Closes #305

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-07 12:36:00 +08:00
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