Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release-tauri.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
- uses: actions/checkout@v4
with:
# vendor/qwen-asr 是 macOS 上 build.rs 必须的 git submodule(cc-rs 编译
# antirez/qwen-asr 的 C 源),不拉就会在 mac 端 cargo build 阶段挂掉。
# Open-Less/qwen-asr fork 的 C 源),不拉就会在 mac 端 cargo build 阶段挂掉。
submodules: recursive

- uses: actions/setup-node@v4
Expand Down
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "openless-all/app/src-tauri/vendor/qwen-asr"]
path = openless-all/app/src-tauri/vendor/qwen-asr
url = https://github.com/antirez/qwen-asr.git
url = https://github.com/Open-Less/qwen-asr.git
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ OpenLess does one thing: **turn speech into usable written text (especially AI p
- Tauri 2 + Rust backend + React/TS frontend. macOS 12+, Windows 10+.
- **Toggle and push-to-talk** recording modes. `Esc` cancels at any phase, including polish/insert.
- **Cloud ASR**: Volcengine streaming ASR, OpenAI Whisper-compatible batch ASR, Apple Speech (macOS).
- **Local ASR**: bundled Qwen3-ASR (0.6B / 1.7B) via vendored `antirez/qwen-asr`; Windows Foundry Local Whisper variants.
- **Local ASR**: bundled Qwen3-ASR (0.6B / 1.7B) via vendored `Open-Less/qwen-asr`; Windows Foundry Local Whisper variants.
- **Polish providers**: Ark / DeepSeek / OpenAI / Doubao / Anthropic-compatible chat-completions, plus any OpenAI-compatible endpoint you bring.
- 4 output modes: raw, light polish, structured (**AI prompt mode**), formal. Plus a **translation hotkey** that converts speech directly into the configured target language ([#43](../../issues/43)).
- **Selection-ask QA panel** — separate hotkey opens a floating panel that runs voice Q&A against the highlighted text in any app ([#118](../../issues/118)).
Expand Down Expand Up @@ -189,7 +189,7 @@ Full end-user walkthrough: [USAGE.md](USAGE.md).

## Build from source (developers)

The active codebase is in `openless-all/app/` (Tauri 2 + Rust + React/TS). The macOS build links a vendored C ASR engine ([`antirez/qwen-asr`](https://github.com/antirez/qwen-asr)) pulled in as a git submodule under `src-tauri/vendor/qwen-asr/`, so initialize submodules on first clone.
The active codebase is in `openless-all/app/` (Tauri 2 + Rust + React/TS). The macOS build links a vendored C ASR engine ([`Open-Less/qwen-asr`](https://github.com/Open-Less/qwen-asr), forked from `antirez/qwen-asr`) pulled in as a git submodule under `src-tauri/vendor/qwen-asr/`, so initialize submodules on first clone.

```bash
# First clone only — pull in vendored submodules
Expand Down
4 changes: 2 additions & 2 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ OpenLess 只做一件事:**把语音变成可用的书面文字(尤其是 AI
- Tauri 2 + Rust 后端 + React/TS 前端;macOS 12+,Windows 10+。
- **切换式 + 按住说话** 双模式录音;任意阶段按 `Esc` 都能取消(包括润色 / 插入中)。
- **云端 ASR**:火山引擎流式 ASR、OpenAI Whisper 兼容批式 ASR、Apple Speech(macOS)。
- **本地 ASR**:内置 Qwen3-ASR(0.6B / 1.7B),通过 vendored `antirez/qwen-asr` 链接;Windows 端支持 Foundry Local Whisper。
- **本地 ASR**:内置 Qwen3-ASR(0.6B / 1.7B),通过 vendored `Open-Less/qwen-asr` 链接;Windows 端支持 Foundry Local Whisper。
- **润色 Provider**:Ark / DeepSeek / OpenAI / Doubao / Anthropic 兼容的 Chat Completions,以及任意 OpenAI 兼容的自定义 endpoint。
- 4 种输出模式:原文、轻度润色、清晰结构(**AI prompt 模式**)、正式表达。另含**翻译热键**——按下后说一段话直接转成目标语言插入([#43](../../issues/43))。
- **划词语音问答(QA)面板** — 独立热键打开浮窗,对当前选中文本发起语音 Q&A([#118](../../issues/118))。
Expand Down Expand Up @@ -192,7 +192,7 @@ OpenLess 只做一件事:**把语音变成可用的书面文字(尤其是 AI

## 从源码构建(开发者)

当前活跃代码库在 `openless-all/app/`(Tauri 2 + Rust + React/TS)。macOS 构建会链接一份 vendored 的本地 ASR 引擎([`antirez/qwen-asr`](https://github.com/antirez/qwen-asr)),以 git submodule 形式挂在 `src-tauri/vendor/qwen-asr/`,首次 clone 后必须先拉子模块。
当前活跃代码库在 `openless-all/app/`(Tauri 2 + Rust + React/TS)。macOS 构建会链接一份 vendored 的本地 ASR 引擎([`Open-Less/qwen-asr`](https://github.com/Open-Less/qwen-asr),fork 自 `antirez/qwen-asr`),以 git submodule 形式挂在 `src-tauri/vendor/qwen-asr/`,首次 clone 后必须先拉子模块。

```bash
# 首次 clone 后拉取子模块
Expand Down
131 changes: 131 additions & 0 deletions docs/git-branching-workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Git branching workflow

## 目标

把这个 fork 固定成一套可执行、低风险的工作流:

- `origin/beta`:日常开发与集成缓冲区
- `origin/main`:稳定可发版分支
- `upstream/main`:原始项目主线,只作为同步来源,不直接在其上开发

## 一次性设置

确认 remote:

```bash
git remote -v
```

预期结果:

```text
origin https://github.com/rackliu/openless.git
upstream https://github.com/appergb/openless.git
```

## 日常开发

每次开始新任务,固定从 `beta` 切功能分支:

```bash
git checkout beta
git pull --ff-only origin beta
git checkout -b feature/<short-name>
```

开发完成后推到 fork:

```bash
git push -u origin feature/<short-name>
```

然后在 GitHub 上创建 PR:

- base: `beta`
- head: `feature/<short-name>`

规则:

- 不直接在 `main` 上写功能程式碼。
- 不把多个独立问题塞进同一个功能分支。
- 每个功能分支只服务一个明确目标。

## 同步 upstream

同步原始项目时,不直接把 `upstream/main` 合进 `main`。先进入 `beta` 做集成和验证:

```bash
git fetch upstream --prune
git checkout beta
git pull --ff-only origin beta
git merge upstream/main
```

如果冲突较大,改用专用同步分支:

```bash
git checkout beta
git pull --ff-only origin beta
git checkout -b sync/upstream-YYYYMMDD
git merge upstream/main
```

处理冲突后,在本机完成最小验证,再合回 `beta`。

## 发版路径

稳定版只从 `main` 发,不从 `beta` 直接打 tag。

标准顺序:

```text
feature/* -> beta -> main -> tag release
```

建议操作:

```bash
git checkout main
git pull --ff-only origin main
git merge --ff-only beta
git push origin main
```

如果 `main` 不能 fast-forward 到 `beta`,不要强推;改走 PR 或手动审查差异后再合并。

## 向 upstream 提交

只有在 fork 中已经验证过的最小切片,才向 upstream 提交。

推荐顺序:

1. 功能先在 `feature/*` 完成。
2. 合入 `origin/beta` 并通过 CI / 本机验证。
3. 从最新 `upstream/main` 切一个干净分支。
4. 只挑选要贡献的最小提交或最小 diff。
5. 向 upstream 建立 PR。

这样做的目的,是把你的 fork 专属改动和可上游化改动分开,避免一次 PR 带入本地策略、实验开关或未成熟流程。

## 每次开始工作前的检查

```bash
git status --short --branch
git remote -v
git branch -vv
```

看到以下任一情况时,先停下来整理:

- 当前在 `main` 但准备改功能程式碼
- `beta` 落后 `origin/beta` 很多
- 本地有未提交修改,但准备切到另一个不相关任务
- 正准备同步 upstream,却还没先更新本地 `beta`

## 当前仓库约定

截至 2026-05-15,本仓库已完成以下设置:

- 已建立 `beta` 分支并推送到 `origin`
- 当前开发应默认进入 `beta` 或其子分支
- 已添加 `upstream = https://github.com/appergb/openless.git`
49 changes: 49 additions & 0 deletions docs/qwen-asr-submodule-upgrade-checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# qwen-asr submodule 升级检查清单

`openless-all/app/src-tauri/vendor/qwen-asr` 是 macOS 本地 Qwen3-ASR 的 C 引擎来源。OpenLess 只从组织 fork `https://github.com/Open-Less/qwen-asr.git` 拉取 submodule;`antirez/qwen-asr` 只作为上游同步来源,不直接进入主仓构建链路。

## 升级原则

- 不直接把 `.gitmodules` 改回个人上游仓库。
- 不在未审查 upstream diff 的情况下推进 submodule commit。
- 每次升级只推进 submodule 指针;除非编译或 FFI 必需,不混入 OpenLess 主项目逻辑改动。
- 保留当前锁定 commit 的可回滚性,必要时能 `git checkout <old-commit> -- openless-all/app/src-tauri/vendor/qwen-asr` 回退。

## 操作步骤

1. 在 `Open-Less/qwen-asr` fork 中同步 upstream。
2. 审查 fork 中待引入 commit:
- C 源码:`qwen_asr*.c`、`qwen_asr*.h`
- 构建脚本 / 模型下载脚本
- 新增二进制、大文件、网络下载地址或 shell 命令
- FFI API 是否改变:`qwen_load`、`qwen_free`、`qwen_set_token_callback`、`qwen_transcribe_audio`、`qwen_transcribe_stream`
3. 在 OpenLess 主仓更新 submodule:
```bash
git submodule sync --recursive openless-all/app/src-tauri/vendor/qwen-asr
git submodule update --init --recursive openless-all/app/src-tauri/vendor/qwen-asr
cd openless-all/app/src-tauri/vendor/qwen-asr
git fetch origin
git checkout <reviewed-commit>
cd -
```
4. 验证 submodule 来源仍是组织 fork:
```bash
git config --file .gitmodules --get submodule.openless-all/app/src-tauri/vendor/qwen-asr.url
git -C openless-all/app/src-tauri/vendor/qwen-asr remote get-url origin
git submodule status openless-all/app/src-tauri/vendor/qwen-asr
git diff --submodule=log -- openless-all/app/src-tauri/vendor/qwen-asr
```
5. 至少运行:
```bash
cd openless-all/app
npm run build
cargo check --manifest-path src-tauri/Cargo.toml
```
macOS 发布前还要用 `INSTALL=0 ./scripts/build-mac.sh` 验证 C 源编译和链接。

## PR / commit 说明必须包含

- 旧 submodule commit 和新 submodule commit。
- 已审查的 upstream commit 范围。
- 是否有 FFI API、模型文件结构、下载脚本或构建参数变化。
- 已运行的验证命令和未覆盖的平台。
25 changes: 15 additions & 10 deletions docs/windows-upstream-pr-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,27 @@

## 目标

Windows 主线先在 `fork/dev` 完成发现、修复、CI、自审和复审,再收敛成明确 upstream 维护项。不要把未收敛的真机 findings 直接写到 upstream issues 或 upstream PR。
Windows 主线先在 fork 的 `origin/beta` 完成发现、修复、CI、自审和复审,再收敛成明确的 upstream 维护项。不要把未收敛的真机 findings 直接写到 upstream issues 或 upstream PR。

当前 remote 约定:

- `origin` = 你的 fork:`https://github.com/rackliu/openless.git`
- `upstream` = 原始仓库:`https://github.com/appergb/openless.git`

## 标准流程

1. 在 `fork/dev` 修复问题
1. 从 `beta` 切功能分支修复问题
- 每个提交只解决一个明确问题。
- findings 先写到本地记录或 fork issue。
- 不向 upstream 新增噪声 issue。

2. 在 `fork/dev` 触发 CI。
2. 在功能分支和 `origin/beta` 上触发 CI。
- Windows build 必须过。
- 新增/修改的 Windows smoke 必须能在本机复跑。
- 真实凭据、物理热键、ASR、插入 fallback 等不能完全 CI 化的项目,要留下本机证据路径和日志摘要。

3. 在 fork 上开自有 PR。
- base: `fork/dev`
- base: `beta`
- head: 功能分支
- PR 描述使用中文,按模板填写。
- PR 必须包含 fork CI 链接、真机回归摘要、自审结论。
Expand All @@ -30,16 +35,16 @@ Windows 主线先在 `fork/dev` 完成发现、修复、CI、自审和复审,
5. 收敛 upstream 维护项。
- 从 fork PR 中拆出最小 upstream 维护切片。
- upstream PR 只包含已验证的最小改动。
- upstream PR 描述必须带 fork PR / fork CI 链接,说明该切片来自已验证的 `fork/dev` 工作流。
- upstream PR 描述必须带 fork PR / fork CI 链接,说明该切片来自已验证的 `origin/beta` 工作流。
- upstream issue 只用于已经确认、可维护、可复现、需要 upstream 跟踪的问题;不要把探索期 findings 扔到 upstream。

## upstream PR 进入条件

- `fork/dev` 已包含修复。
- `origin/beta` 已包含修复。
- fork PR 已通过 CI。
- fork PR 已完成自审和复审。
- upstream 分支从最新 upstream base 切出。
- upstream diff 能独立解释,不依赖 fork/dev 的其他未提交上下文
- upstream 分支从最新 `upstream/main` 切出。
- upstream diff 能独立解释,不依赖 `beta` 中其他未提交上下文
- PR 描述包含:
- 单一目标
- 不包含范围
Expand All @@ -50,7 +55,7 @@ Windows 主线先在 `fork/dev` 完成发现、修复、CI、自审和复审,
## 禁止项

- 禁止从未验证的本地 finding 直接创建 upstream issue。
- 禁止绕过 fork/dev CI 直接推 upstream PR。
- 禁止绕过 `origin/beta` CI 直接推 upstream PR。
- 禁止把多个 Windows 真机问题混成一个 upstream PR。
- 禁止在 upstream PR 中提交真实服务凭据、用户本地配置、构建产物或临时目录。

Expand All @@ -59,7 +64,7 @@ Windows 主线先在 `fork/dev` 完成发现、修复、CI、自审和复审,
后续 Windows 主线默认顺序为:

```text
fork/dev 修复 -> fork/dev CI -> fork PR -> 自审/复审 -> upstream 最小 PR
feature/* 修复 -> origin/beta CI -> fork PR -> 自审/复审 -> upstream 最小 PR
```

如果 upstream PR 需要更新,先确认对应 fork PR 和 fork CI 证据,再同步 upstream PR。
2 changes: 1 addition & 1 deletion openless-all/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This is the current cross-platform OpenLess workspace.

## App Directory

The runnable Tauri app lives in `app/`. The macOS build links a vendored C ASR engine (`antirez/qwen-asr`) tracked as a git submodule under `app/src-tauri/vendor/qwen-asr/`, so initialize submodules on first clone.
The runnable Tauri app lives in `app/`. The macOS build links a vendored C ASR engine (`Open-Less/qwen-asr`, forked from `antirez/qwen-asr`) tracked as a git submodule under `app/src-tauri/vendor/qwen-asr/`, so initialize submodules on first clone.

```bash
# First clone only — pull in vendored submodules
Expand Down
13 changes: 11 additions & 2 deletions openless-all/app/scripts/windows-ime-install-smoke.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,26 @@ $ErrorActionPreference = "Stop"

$TextServiceClsid = "{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}"
$ProfileGuid = "{9B5F5E04-23F6-47DA-9A26-D221F6C3F02E}"
$LangId = "0x00000804"
$KeyboardCategoryGuid = "{34745C63-B2F0-4784-8B67-5E12C8701A31}"
$ImmersiveCategoryGuid = "{13A016DF-560B-46CD-947A-4C3AF1E0E35D}"
$SystrayCategoryGuid = "{25504FB4-7BAB-4BC1-9C69-CF81890F0EF5}"

function Resolve-OpenLessLangId {
$lang = [System.Globalization.CultureInfo]::InstalledUICulture.Name.ToLowerInvariant()
if ($lang -like "zh-tw*" -or $lang -like "zh-hk*" -or $lang -like "zh-mo*" -or $lang -like "zh-hant*") {
return "0x00000404"
}
return "0x00000804"
}

$LangId = Resolve-OpenLessLangId

# Keep this script aligned with the backend status check and the TSF IPC path
# used by OpenLessImeSubmit-* named pipes.
$ExpectedBackendKeys = @(
"Software\Classes\CLSID\{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}\InprocServer32",
"Software\WOW6432Node\Classes\CLSID\{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}\InprocServer32",
"Software\Microsoft\CTF\TIP\{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}\LanguageProfile\0x00000804\{9B5F5E04-23F6-47DA-9A26-D221F6C3F02E}",
"Software\Microsoft\CTF\TIP\{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}\LanguageProfile\$LangId\{9B5F5E04-23F6-47DA-9A26-D221F6C3F02E}",
"Software\Microsoft\CTF\TIP\{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}\Category\Category\{34745C63-B2F0-4784-8B67-5E12C8701A31}\{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}",
"Software\Microsoft\CTF\TIP\{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}\Category\Category\{13A016DF-560B-46CD-947A-4C3AF1E0E35D}\{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}",
"Software\Microsoft\CTF\TIP\{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}\Category\Category\{25504FB4-7BAB-4BC1-9C69-CF81890F0EF5}\{6B9F3F4F-5EE7-42D6-9C61-9F80B03A5D7D}"
Expand Down
Loading
Loading