Commit Graph
63 Commits
Author SHA1 Message Date
weikeyi 58c229dace fix(windows-ci): WiX 工具按 WixTools* 通配查找,避免 Tauri 升级后路径失效
Windows MSI Repair 之前硬编码 `C:\Users\22933\AppData\Local\tauri\WixTools314\light.exe`,Tauri 升级到新 WiX 版本(如 WixTools315)后路径不存在,Repair 步骤直接挂。

改为 WixTools* glob,按数字后缀降序回退到名称降序,取最新可用版本。同步更新 windows-package-msvc.ps1::Find-WixTool 和 release-tauri.yml 的 Repair 步骤;保留 -sice:ICE80、NSIS/MSI 两轮 build、bash shell 等 Windows CI 红线不变。

补 4 条 windows-package-msvc.test.mjs 防回归断言:禁止 WixTools314 出现在脚本/workflow,要求两边都按 WixTools* glob 查找。

Refs: #298
2026-05-11 16:50:20 +08:00
H-Chris233andOmX 029232a269 Make backend state tests runnable without Tauri
Windows cannot reliably execute the full Tauri lib test harness in CI because the process exits before Rust tests start in the desktop runtime loader path. Split the coordinator session state transitions into a Tauri-free Rust module used by coordinator.rs, and add a small Rust-only backend test crate that path-includes coordinator/hotkey/recorder/insertion logic for real Windows execution.

Constraint: User scoped this follow-up to backend-only Rust-to-Rust tests, not app/runtime smoke tests.
Constraint: Existing Windows CI still keeps full lib --no-run cfg/link coverage.
Rejected: Keep trying to execute cargo test --lib on Windows | it starts the full Tauri-linked test binary and fails before unit tests run.
Rejected: Rework release/runtime DLL handling | outside the backend unit-test scope.
Confidence: high
Scope-risk: moderate
Directive: Keep Windows actual unit execution on the Rust-only backend-tests manifest unless the full Tauri lib harness is proven runnable on clean Windows CI.
Tested: cargo test --manifest-path openless-all/app/src-tauri/backend-tests/Cargo.toml
Tested: cargo test --manifest-path openless-all/app/src-tauri/Cargo.toml --lib
Tested: cargo check --manifest-path openless-all/app/src-tauri/Cargo.toml
Tested: python yaml parse for .github/workflows/ci.yml; git diff --check
Not-tested: Windows runner execution; intended to be verified by GitHub Actions.
Related: #295
Co-authored-by: OmX <omx@oh-my-codex.dev>
2026-05-09 07:44:57 +08:00
H-Chris233 ffeaa243d9 Keep backend test CI executable on Windows
The #295 unit suite now runs in CI, but the Windows clean runner exits before the lib test harness starts with STATUS_ENTRYPOINT_NOT_FOUND when optional native runtime entrypoints are absent. Windows still needs cfg/link coverage, while macOS and Linux can execute the shared Rust unit suite.

Constraint: Preserve the new Rust test gate without making optional Windows native runtime installation a CI prerequisite.
Rejected: Install Foundry/Windows App Runtime into every CI run | broader, slower, and unrelated to backend unit-test coverage.
Confidence: high
Scope-risk: narrow
Directive: Do not switch Windows back to executing the lib test binary until the optional native runtime dependency is present on the runner.
Tested: cargo test --manifest-path openless-all/app/src-tauri/Cargo.toml --lib
Not-tested: Windows CI rerun before push.
2026-05-08 19:15:54 +08:00
H-Chris233 88e8418982 Make backend regressions visible in CI
Issue #295 calls out that core Rust paths have been too dependent on manual app runs. Keep the change narrow by covering existing pure state/audio/clipboard helpers instead of refactoring coordinator or touching hardware-facing code, then wire the existing lib test suite into the lightweight CI lane.

Constraint: Global hotkey, recorder, and insertion integration still require real OS permissions and devices.

Rejected: Split coordinator before adding tests | broader refactor would raise review risk and is tracked separately.

Confidence: high

Scope-risk: narrow

Directive: Keep Rust CI on --lib unless integration tests get explicit OS fixtures.

Tested: npm run build

Tested: cargo test --manifest-path src-tauri/Cargo.toml --lib

Tested: cargo check --manifest-path src-tauri/Cargo.toml

Not-tested: Live microphone, global hotkey, clipboard, and insertion device paths.

Related: #295
2026-05-08 15:18:40 +08:00
Chris233 29c9160b9f Merge pull request #346 from H-Chris233/fix/issue-300-linux-ci-gate
为 PR CI 增加 Linux cargo check 门禁
2026-05-08 09:48:47 +08:00
TRIPandbaiqing b7685cadda docs(release): make macOS xattr workaround discoverable (#347)
发现的真因:v1.2.23 Stable 和 v1.2.24-1 Beta 的 macOS DMG 都是 ad-hoc 签名 + 未经 Apple 公证(仓库没配 APPLE_CERTIFICATE 等 secrets)。macOS 14+ Gatekeeper 默认拒绝运行未公证的 app,弹"OpenLess 已损坏"。
build-mac.sh:40-41 注释已经写明这是已知限制:
  "用户免手工 xattr 的根本方案是 Developer ID 签名 + Apple notarization"

之前 README 只在 brew install 段写了 xattr -cr 指令,DMG 直装路径没写。
用户首次装 Beta 不知道要做这一步,看到"已损坏"以为 release 坏了。

本 PR:
- README.md / README.zh.md 的「下载与安装」段,DMG 直装路径加上 xattr -cr 指令 + 一句解释为什么需要(ad-hoc 签名、未公证)
- release-tauri.yml 的 Create release step 加 body 模板,所有未来 release 自动 prepend 一段:macOS xattr 指令 + Beta/Stable 渠道说明。用 append_body: true 让它放在 generated notes 之前

不在本 PR:配 Apple Developer 证书 + secrets——那是根治方案,需要 $99/年 Apple Developer 账号 + 用户决定要不要走那条路。

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-08 09:27:16 +08:00
H-Chris233 c8fa63e30e Catch Linux cfg drift before release
CI only checked macOS and Windows before merge, so Linux-only Rust paths could fail cargo check for the first time during release packaging. The matrix now includes an Ubuntu lane that runs the same frontend build and backend cargo check, with only the Linux libraries needed for checking Tauri dependencies and no bundle step.

Constraint: Issue #300 asks for PR-time Linux validation while skipping Tauri bundle work.\nRejected: Add Linux release bundle to CI | too slow and duplicates release-tauri.yml.\nConfidence: high\nScope-risk: narrow\nTested: python ci.yml textual assertions; git diff --check; cd openless-all/app && npm run build; cd openless-all/app && cargo check --manifest-path src-tauri/Cargo.toml\nNot-tested: Full GitHub Actions ubuntu-latest runner execution before PR.\nRelated: https://github.com/appergb/openless/issues/300
2026-05-08 09:16:46 +08:00
TRIPandbaiqing 58a0ad9e62 fix(release): use tagged URL in beta manifest, not releases/latest (#344)
修复 v1.2.24-1-beta-tauri release verification 时发现的 latent bug:
Beta manifest 里 url 字段指向 https://github.com/.../releases/latest/download/<asset>,
但 releases/latest 永远是最新非-prerelease(即 Stable),Beta 用户按这个 url
auto-update 会拉到 Stable 包:

- macOS Beta: 文件名 OpenLess_aarch64.app.tar.gz 跟 Stable 重名 → 下载 Stable 包,
  装上的是 1.2.23 但 manifest 声称 1.2.24-1,version drift
- Windows/Linux Beta: 文件名带版本号 OpenLess_1.2.24-1_x64-setup.exe / .AppImage,
  releases/latest 路径下没这个文件 → 直接 404

Stable 渠道沿用 releases/latest 是对的(latest = Stable)。

修法:write-updater-manifest.mjs 多读一个 OPENLESS_RELEASE_TAG env,beta 时
url 拼成 releases/download/<tag>/<asset>(指定具体 tag,不被 prerelease 折叠
影响);stable 不变。脚本对 beta 缺 tag 做 fail-fast。

release-tauri.yml 在 manifest step 多注入 OPENLESS_RELEASE_TAG: ${{ github.ref_name }}。

为什么不重发 v1.2.24-1:当前走 Path A 手动下载式 opt-in,前端调
fetch_latest_beta_release 拿 GitHub release 页 html_url,用户跳浏览器手动选包,
不消费 manifest.url。所以 v1.2.24-1 已发布的 manifest 里 url 错也是 dormant。
下一轮 Beta tag(v1.2.24-2-beta-tauri 或 stable cut 后再做 Beta)会用修复后
的脚本产出正确 URL。

本地 smoke test:
- channel=beta + 缺 OPENLESS_RELEASE_TAG → fail-fast 抛 "is required"
- channel=beta + 有 tag → env 检查通过,进入 artifact 解析
- channel=stable + 不传 tag → 维持原行为
- python yaml.safe_load() 解析 release-tauri.yml 通过

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-08 09:04:14 +08:00
TRIPandbaiqing 2246d8f660 fix(release): merge duplicate jobs.build.env block in release-tauri.yml (#335)
PR #330 在 jobs.build 顶层多加了一个 env: 块来定义 OPENLESS_RELEASE_CHANNEL,
但下面 strategy/runs-on 之后已经有一个 env: 块(TAURI_SIGNING_PRIVATE_KEY 等)。
YAML map 不允许重复 key——GitHub Actions 解析直接 fail,整条 release-tauri.yml
工作流变成 "workflow file issue" 启动失败。

修复:把 OPENLESS_RELEASE_CHANNEL 并到下面那个唯一的 env: 块里,保留完整注释。

校验:
- python -c "yaml.safe_load(...)" 解析成功
- jobs.build.env 现在有 3 个 key: OPENLESS_RELEASE_CHANNEL, TAURI_SIGNING_PRIVATE_KEY,
  TAURI_SIGNING_PRIVATE_KEY_PASSWORD

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-07 22:16:27 +08:00
TRIPandbaiqing ec9584ea0c feat(release): split updater manifest by channel from tag suffix (#330)
让 release pipeline 根据 tag 名后缀区分 Beta / 正式版渠道,是 opt-in beta
机制的服务端基础。客户端读取的 endpoint 在 PR-B-2 接入。

约定:
- `v<v>-tauri`           = 正式版渠道(stable)
- `v<v>-beta-tauri`      = Beta 渠道(beta)

release-tauri.yml 改动:
- 在 jobs.build 顶层加 OPENLESS_RELEASE_CHANNEL job-env,由
  endsWith(github.ref_name, '-beta-tauri') 决定;workflow_dispatch 与
  非 tag 触发回退为 stable,不改变现有 dispatch 行为。
- Write updater manifest step 把 OPENLESS_RELEASE_CHANNEL 透传给脚本。
- Upload-artifact 的 manifest path 改为 `latest-{tgt}-{arch}*.json` glob,
  让 stable 和 beta 两种文件名(或 mirror 变体)都能被收集,避免
  if-no-files-found 在 beta release 时挂掉。
- Create release 的 prerelease 改为
  `${{ env.OPENLESS_RELEASE_CHANNEL == 'beta' }}`:beta tag 自动标
  GitHub prerelease(UI 折叠 + 默认不算 latest),stable 保持不变。

write-updater-manifest.mjs 改动:
- 读取 OPENLESS_RELEASE_CHANNEL(默认 stable);非 stable / beta 时
  fail-fast,避免拼错 env 静默走错路径。
- beta 渠道时 manifest 文件名加 `-beta` 后缀:
    latest-{tgt}-{arch}-beta.json
    latest-{tgt}-{arch}-beta-mirror.json
  正式版用户的 endpoint 永远指向不带后缀的旧文件名,不会被 beta release 覆盖。

向后兼容:
- 现有 v1.2.23-tauri 等 stable release 行为完全不变(文件名、prerelease=false 沿用旧逻辑)。
- workflow_dispatch 不打 tag 时也照常构建 + 不上传 release。

发版后 checklist(PR-B-2 文档段会写进 CLAUDE.md):
- 推 v<v>-beta-tauri tag → GitHub Release 应标 prerelease 且只含
  latest-*-beta.json
- 推 v<v>-tauri tag → 正式 release 且只含 latest-*.json(不带后缀)

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-07 22:00:08 +08:00
TRIPandbaiqing 2fe5f2e0d4 docs: introduce Beta/Stable two-channel branching workflow (#327)
把分支模型从「dev/main」改造为「Beta/正式版」双渠道,渠道语义直接由分支名承载:

- `beta` — Beta 渠道(开发版),默认分支、集成缓冲区,所有 PR 一律打到这里。
  Beta 包不推送给普通用户,只面向主动加入 Beta 渠道的用户。
- `main` — 正式版渠道(Stable),始终可发布。仅由维护者在双端冒烟测试通过后从
  beta 合入;普通用户默认拿到的就是这条线。

文档与 CI 改动:
- README.md / README.zh.md:把「Contributing workflow / 贡献流程」章节
  改写为 Beta/正式版双渠道,含分支流向 ASCII 图、6 条核心规则,
  以及「Beta 不溢出正式版」的隔离要求。
- CLAUDE.md:把 `### Branch & contribution workflow` 改名为
  `### Branch & release-channel workflow`,明确「分支名=渠道名」。
- ci.yml:触发分支从 [main, dev] 改为 [main, beta]。

仓库侧已同步:
- 远端 dev 分支已重命名为 beta(git push origin dev:beta + 删除旧 dev)
- GitHub 仓库默认分支已切到 beta
- release-tauri.yml 用 v*-tauri tag 触发,跟分支无关,发版机制不受影响

Beta 包的 opt-in 分发机制(per-channel updater endpoint + 设置页开关)
将在独立 PR 中接入。在它落地之前,所有 v*-tauri tag 都按正式版对待,
不要从 beta 分支直接打 tag。

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-05-07 21:55:31 +08:00
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
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
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
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
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
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
baiqing 262a9ad2d7 fix(ci): checkout 拉 submodules — 修 mac 端 qwen-asr build fail
release-tauri.yml run 25415755417 mac arm64 在 cargo build 时挂在:

    error: no such file or directory: 'vendor/qwen-asr/qwen_asr.c'

根因:build.rs 的 #[cfg(target_os = "macos")] 分支用 cc-rs 编译
vendor/qwen-asr/*.c,但 vendor/qwen-asr 是 git submodule,CI 的
actions/checkout@v4 默认不拉 submodule,目录是空的。Linux/Windows
build.rs 不进 cc 编译路径,所以没踩;mac 是唯一编译 qwen-asr 的平台。

修:release-tauri.yml + ci.yml 的 actions/checkout@v4 都加
\`with: submodules: recursive\`,让所有平台都拉一致的源码树。
2026-05-06 13:03:36 +08:00
TRIP b84b0bdae3 Merge pull request #279 from appergb/fix/local-asr-release-flow
fix(windows): NSIS 安装包注册 TSF DLL + local-asr RAM 真正归还
2026-05-06 11:07:27 +08:00
baiqing c52658b08b fix(windows): NSIS 也注册 32-bit TSF DLL — 修 P1 review
Codex review 发现:windows_ime_profile.rs::inspect_windows_ime_registration() 同时
用 KEY_WOW64_64KEY 和 KEY_WOW64_32KEY 两次检查 HKLM\Software\Classes\CLSID\{...}\
InprocServer32,少了任一边就返回 RegistrationBroken("OpenLess 32-bit COM
registration is missing")。MSI 流程通过 wxs 同时跑了 64-bit 和 SysWOW64\regsvr32
注册两份;之前的 NSIS hook 只注册了 x64,所以 NSIS / updater 用户依然在 Settings
页看到「不可用」。

修复:
- bundle.resources 拆出 x64 / x86 两份 dll target;x64 → tsf-ime\x64,x86 → tsf-ime\x86
- installer.nsh PostInstall/PreUninstall 增加 x86 分支,
  x86 用 $WINDIR\SysWOW64\regsvr32.exe(写 KEY_WOW64_32KEY 必需)
- CI Build Windows IME native DLLs 步骤把复制 dll 移到循环里,x64 + x86 都覆盖
  仓库占位
- 仓库新增 0 字节 x86 占位 dll,让本地 mac/linux 构建也能 resolve resources
2026-05-06 10:47:03 +08:00
baiqing 5aec74653b fix(windows): NSIS 安装包注册 OpenLess TSF DLL — 修"输入法后端:不可用"
## 现象
1.2.15 起在 Settings 页"Windows 输入法后端"出现 Pill「不可用」。`get_windows_ime_status()`
查 HKLM 注册表四件套(COM CLSID + TSF LanguageProfile + 三个 Category),缺一即报 NotInstalled。

## 根因
- MSI 通过 wix/openless-ime.wxs 的 RegisterOpenLessIme* CustomAction 跑 regsvr32 → 注册齐全。
- NSIS 包既没把 OpenLessIme.dll 打进去(wxs.componentRefs 是 MSI-only),也没 hook 跑
  regsvr32 → 用 setup.exe 安装的用户、走 updater 自动升级的存量用户全部命中"不可用"。
- 由于 updater latest-windows-x86_64.json 是 NSIS pass 写的,老 MSI 用户每次更新后也
  会被替换为没 TSF 的 NSIS 版本。

## 修复
- 加 src-tauri/installer.nsh:NSIS_HOOK_POSTINSTALL/PREUNINSTALL 跑 regsvr32 注册/反注册。
- bundle.resources map 把 OpenLessIme.dll 拷贝到 $INSTDIR\tsf-ime\OpenLessIme.dll
  (target 路径避开 wxs File 已声明的 windows-ime\x64\,避免 MSI component 路径冲突)。
- bundle.windows.nsis.installMode = "perMachine",让 NSIS 以管理员身份运行(写 HKLM 必需)。
- CI 在 build native dll 后把真 dll 复制到 src-tauri/openless-ime-payload/x64/OpenLessIme.dll;
  仓库 commit 0 字节占位文件,让本地 mac 端 tauri build 也能 resolve resources 路径。
- build-mac.sh 与 Linux build 步骤加 --config '{"bundle":{"resources":{}}}' 跳过 Windows-only
  的 dll 占位,避免污染 mac .app / Linux .deb/.rpm/.AppImage。

## Trade-off
- NSIS perMachine 升级需要 UAC,老 currentUser 用户首次升级时多一次 UAC 提示。
- MSI 包里 dll 会有两份(wxs File + bundle.resources),磁盘冗余 ~几百 KB,无功能影响。
2026-05-06 10:41:07 +08:00
H-Chris233 bd4547b613 Pin PR-Agent runtime while preserving automatic reviews
The workflow must keep reviewing every PR and every pushed commit automatically, including fork PRs, so the hardening focuses on pinning the code that actually runs in the secrets-bearing job. The wrapper action commit still delegates to a mutable Docker tag, so the workflow now calls the PR-Agent container by immutable digest directly.

Constraint: Maintainer preference is automatic PR-Agent coverage for each PR and synchronize event.

Constraint: Issue #222 requires removing mutable third-party execution refs from the secrets-bearing path.

Rejected: Pin only the action repository commit | the wrapper Dockerfile still resolves pragent/pr-agent:github_action at runtime.

Rejected: Require trusted comment triggers for fork PRs | too inconvenient because new commits would not be reviewed automatically.

Confidence: medium

Scope-risk: moderate

Directive: If fork PR automation remains required, keep the runtime container digest-pinned and do not checkout PR head code in this workflow.

Tested: Parsed .github/workflows/pr-agent.yml with PyYAML and asserted docker:// sha256 form; git diff --check; grep confirmed no action ref or github_action tag remains in the workflow.

Not-tested: Live GitHub Actions execution or Docker Hub digest pull from this host.

Related: https://github.com/appergb/openless/issues/222
2026-05-06 07:51:46 +08:00
millionart b303ea405b fix: guard windows installer smoke exits 2026-05-05 19:05:56 +08:00
millionart 753236dd55 fix: register Windows IME from NSIS installer 2026-05-05 17:38:28 +08:00
Chris233 3e1ba69bfc Merge pull request #252 from Cooper-X-Oak/fix/recorder-timeout-238
fix(recorder): 添加 liveness watchdog 和全局超时保护以修复 #238
2026-05-05 12:32:37 +08:00
cooperandClaude Sonnet 4.6 27451298da audit(system): 完成系统级多尺度审计 - 发现 3 大架构风险和 13 项技术债务
建立多尺度审计框架(4 个尺度):
- 尺度 1: 系统级(架构、安全、扩展性)
- 尺度 2: 模块级(设计、接口、依赖)
- 尺度 3: 功能级(实现、体验、边界)
- 尺度 4: 代码级(bug、风格、性能)

**系统级审计关键发现**:

架构风险(3 项):
- 🔴 Coordinator 过于庞大(3462 行)
- 🔴 缺少统一的 ASR Provider trait
- 🔴 测试基础设施缺失(覆盖率接近 0%)

技术债务(13 项):
- P0: 2 项(测试相关)
- P1: 5 项(架构 + 测试 + 代码)
- P2: 4 项(架构 + 文档 + 代码)
- P3: 2 项(文档)
- 预计偿还成本: 14 周(3.5 个月)

**关键决策**:
1. ✅ 需要架构重构
2. ⏸️  暂停低尺度审计(先解决高尺度问题)

**下一步行动**:
1. 编写测试策略文档
2. 编写 Coordinator 拆分设计文档
3. 编写 ASR Provider trait 设计文档

**审计产出**:
- 多尺度审计框架文档
- 架构风险地图
- 技术债务矩阵
- 系统级审计总结
- 系统级审计脚本

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 23:16:12 +08:00
baiqing 0bd338a94c ci(release): split Windows tauri build into NSIS + MSI passes
Tauri 的签名 / updater artifact 是 post-bundle 钩子,单次 tauri build 内
任意 bundler 失败都会跳过 .sig 生成。MSI 必踩 ICE80,所以单 pass 永远
拿不到 NSIS 的 .exe.sig(v1.2.18 build 验证)。

拆两轮:
- Pass 1: --bundles nsis 单独跑,必须成功,产出 .exe + .exe.sig
- Pass 2: --bundles msi 单独跑,允许 ICE80 失败,Repair 用 light 重链兜底

不 bump 版本号——下一次 release 之前用 workflow_dispatch 验证 CI 全绿。
2026-05-04 23:11:41 +08:00
cooperandClaude Sonnet 4.6 7e7b200198 docs(epic): 建立 Cooper 贡献体系 - 两大 EPIC 母体与 Finding 流程
建立完整的贡献规划体系:

**两大 EPIC 母体**:
- EPIC-001: 测试基础设施建设 (41 tasks, 6 weeks)
  - 目标:测试覆盖率 0% → 60%+
  - Phase 1: 核心模块单元测试
  - Phase 2: 集成测试
  - Phase 3: CI 自动化

- EPIC-002: ASR 功能扩展与优化 (71 tasks, 6 weeks)
  - Phase 1: 混淆词纠错层 (对应 #89)
  - Phase 2: 本地 ASR 支持 (对应 #211)
  - Phase 3: ASR 架构优化

**Finding 基础设施**:
- finding-helper.sh: 自动化分析脚本
- 生成 4 份 finding 报告:
  - 测试覆盖率分析
  - ASR 模块分析
  - 依赖关系分析
  - Finding 总结

**工作流程文档**:
- COOPER_README.md: 快速开始指南
- COOPER_WORKFLOW.md: 详细工作流程
- COOPER_CONTRIBUTION_STRATEGY.md: 贡献策略分析

**关键指标**:
- 包含测试的文件数: 15
- 测试函数数: 76
- ASR 模块代码量: 1164 行

下一步:开始实现混淆词纠错层(EPIC-002 Phase 1)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 23:00:25 +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
cooper 84e1649681 docs: 添加 Watchdog 线程影响分析与风险评估
- 分析了 5 个潜在风险点
- 验证了 ASR 资源清理逻辑
- 结论:当前实现完全安全,可以合并
2026-05-04 22:31:08 +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
cooper d1c68f0f30 test: 添加实机测试报告(仅保留在 fork)
- BUILD_TEST_REPORT.md: 构建和启动测试
- P1_TEST_REPORT.md: 麦克风异常恢复测试
- TEST_VERIFICATION.md: 代码审查验证

这些文档仅用于 fork 仓库的测试记录,不提交到上游 PR
2026-05-04 22:21:14 +08:00
cooper 4e66c91e07 docs: 添加 Issue #238 修复的代码审查验证报告 2026-05-04 21:54:35 +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
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
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
H-Chris233 c8ccff0669 Avoid macOS updater asset collisions across architectures
Intel and Apple Silicon macOS jobs produced the same updater bundle filename,
which let one matrix job overwrite the other release asset and could point
both architecture manifests to a single binary. Rename macOS updater bundles
per architecture before release upload and prefer arch-specific artifact lookup
when generating updater manifests.

Constraint: Keep existing updater manifest format and release action usage
Rejected: Split macOS uploads into separate release jobs | larger workflow churn
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Any new macOS updater lane must keep unique asset names to preserve manifest correctness
Tested: release-tauri.yml YAML parse; diff audit for rename+manifest path alignment
Not-tested: End-to-end tagged GitHub Actions release run
2026-05-04 01:02:44 +08:00
H-Chris233 fbcddc40db Add Intel macOS artifacts to Tauri release matrix
The release workflow only produced Apple Silicon macOS packages, so Intel
users had no official GitHub Release artifact. Extend the matrix with an
x86_64 macOS lane and align artifact naming and updater-manifest paths
with per-arch outputs.

Constraint: Keep existing release pipeline shape and signing flow unchanged
Rejected: Split Intel build into separate workflow file | higher maintenance and duplicated logic
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep macOS conditions architecture-agnostic so new mac runners are not skipped accidentally
Tested: YAML syntax parse via python yaml.safe_load; workflow diff reviewed for mac gating/artifact paths
Not-tested: Full GitHub Actions matrix run on tag push
2026-05-04 00:27:02 +08:00
TRIP 7f64a1b464 fix(ci): allow PR-Agent review on external PRs 2026-05-03 09:55:17 +08:00
Chris233 280b50ea17 更新 pr-agent.yml 2026-05-02 21:16:12 +08:00
Chris233 69d7f62161 更新 pr-agent.yml 2026-05-02 20:07:26 +08:00
Chris233 4027909a8c 更新 pr-agent.yml 2026-05-02 19:23:44 +08:00
Chris233 14149207a4 更新 pr-agent.yml 2026-05-02 19:15:19 +08:00
Chris233 dbb95abab7 更新 pr-agent.yml 2026-05-02 18:55:56 +08:00
Chris233 f7c0c59408 创建 pr-agent.yml 2026-05-02 17:40:27 +08:00
Cooper-X-Oak e34b3feee7 fix updater download acceleration 2026-05-01 23:47:58 +08:00
baiqing 9b2f65fe71 fix: harden Windows hotkey release handling 2026-04-30 19:26:31 +08:00
baiqing a9c81e6e0e feat(updater): 增加应用自动更新入口 (#84)
H-Chris233: closes #33。

实现 Tauri 内置 updater 集成:
- Cargo: tauri-plugin-updater v2
- tauri.conf.json: 加 updater 配置(pubkey + endpoint 指向 GitHub Releases latest)
- capabilities/default.json: 授予 updater:default 能力
- lib.rs: 注册 updater 插件 + restart_app 命令
- src/pages/Settings.tsx + i18n: 关于区域加'检查'按钮、检查/下载/安装/重启对话框流
- 新脚本 scripts/write-updater-manifest.mjs: release 侧从 build artifact 拉签名生成 manifest
- workflow: TAURI_SIGNING_PRIVATE_KEY env + 各平台 build 时 createUpdaterArtifacts true

注意:下次 v*-tauri tag 必须配 TAURI_SIGNING_PRIVATE_KEY secret,否则 CI 硬失败。
2026-04-30 17:20:32 +08:00
TRIPandbaiqing e3f91e849c ci(release): 显式 strip macOS bundle xattr 作为 defense-in-depth (#83)
GitHub Actions 输出本来就不带 com.apple.quarantine (actions/upload-artifact
不跨机器持久化 xattr, softprops/action-gh-release 上传 binary stream 也不带),
但加这一步让 "云端 artifact 一定干净" 变成可验证的承诺, 未来 release 不会因
runner 环境变化退化.

用户下载到本地后浏览器/LaunchServices 仍会加 quarantine, 依赖 release notes
里的 xattr -cr 指引或一行安装命令处理.

Co-authored-by: baiqing <lbx12309@icloud.com>
2026-04-30 14:56:22 +08:00