Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5cd47ac
refactor(desktop): simplify settings, live input and update delivery
Nov 6, 2026
d4c2f2e
fix(macos): keep live input consent local and fail closed without its…
Nov 6, 2026
37fd03c
fix(ci): reuse dependency downloads and validate current release gates
Nov 6, 2026
3494cff
fix(macos): validate application focus and native capsule input owner…
Nov 6, 2026
8609070
perf(ci): allow focused macOS architecture acceptance builds
Nov 6, 2026
f26f747
perf(ui): release idle and failed GPU resources and complete dark typ…
Nov 6, 2026
47ad335
fix(desktop): finalize interaction boundaries and parallel browser gates
Nov 6, 2026
0f21fb5
fix(ui): complete WebKit corners and elapsed-time motion validation
Nov 6, 2026
1371e91
perf(capsule): release settled glyph compositing hints and blur
Nov 6, 2026
6838921
fix(updater): recover GitHub release discovery after API rate limits
Nov 6, 2026
f79120d
ci(linux): bound dependency setup and share minimal package installation
Nov 6, 2026
51e1445
ci(linux): apply setup timeout at the calling workflow step
Nov 6, 2026
6319c5b
fix(desktop): finish settings and capsule interactions
Nov 7, 2026
c093fd3
test(ui): update translation popup radius contract
Nov 7, 2026
a1d4b65
feat(ui): smooth scrolling and continuous corners
Nov 7, 2026
12eac86
fix(ui): finish continuous corners in question panel
Nov 7, 2026
1baa33a
fix(qa): label the jump to latest control
Nov 7, 2026
6fcdb20
fix(qa): retain follow state across delayed scroll events
Nov 7, 2026
dbc4bcd
test(qa): wait for scroll state instead of fixed frames
Nov 7, 2026
b9da691
fix(ui): reconcile scroll resets with spring momentum
Nov 7, 2026
41a95fa
fix(ui): stabilize scroll momentum and browser coverage
Nov 7, 2026
34b1e17
fix(ui): restore capsule and switch geometry
Nov 8, 2026
e5ddbb4
fix(corrections): restore the eight pixel add button
Nov 8, 2026
c98382a
fix(ui): protect native capsule corner exceptions
Nov 8, 2026
5427c49
fix(ui): stabilize popup sizing at fractional zoom
Nov 8, 2026
405d1af
test(qa): await the painted exit state
Nov 8, 2026
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
11 changes: 11 additions & 0 deletions .github/actions/cache-npm/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ runs:
run: |
echo "path=$(npm config get cache)" >> "$GITHUB_OUTPUT"
echo "arch=$(node -p process.arch)" >> "$GITHUB_OUTPUT"
- name: Bound npm network stalls
shell: bash
run: |
echo "npm_config_prefer_offline=true" >> "$GITHUB_ENV"
echo "npm_config_audit=false" >> "$GITHUB_ENV"
echo "npm_config_fund=false" >> "$GITHUB_ENV"
echo "npm_config_fetch_retries=2" >> "$GITHUB_ENV"
echo "npm_config_fetch_timeout=60000" >> "$GITHUB_ENV"
echo "SEGMENT_DOWNLOAD_TIMEOUT_MINS=3" >> "$GITHUB_ENV"
# Keep setup-node's existing key and path so the current beta cache remains
# reusable. Cache lookup falls back to the PR base/default branch on a miss.
- name: Restore npm outside beta builds
Expand All @@ -17,9 +26,11 @@ runs:
with:
path: ${{ steps.npm.outputs.path }}
key: node-cache-${{ runner.os }}-${{ steps.npm.outputs.arch }}-npm-${{ hashFiles('openless-all/app/package-lock.json') }}
restore-keys: node-cache-${{ runner.os }}-${{ steps.npm.outputs.arch }}-npm-
- name: Maintain npm cache on beta builds
if: github.ref == 'refs/heads/beta' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
uses: actions/cache@v4
with:
path: ${{ steps.npm.outputs.path }}
key: node-cache-${{ runner.os }}-${{ steps.npm.outputs.arch }}-npm-${{ hashFiles('openless-all/app/package-lock.json') }}
restore-keys: node-cache-${{ runner.os }}-${{ steps.npm.outputs.arch }}-npm-
20 changes: 20 additions & 0 deletions .github/actions/setup-linux-dependencies/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Linux build dependencies
description: Bounded, noninteractive Ubuntu dependency setup shared by tests and packaging
runs:
using: composite
steps:
- name: Install Ubuntu build dependencies
shell: bash
run: |
set -euo pipefail
# Hosted Ubuntu 24.04 already enables universe. Adding it again also
# refreshes every configured package feed before our own update.
apt_network=(-o Acquire::Retries=2 -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30)
sudo timeout --kill-after=10s 180s apt-get "${apt_network[@]}" update
sudo DEBIAN_FRONTEND=noninteractive timeout --kill-after=10s 300s \
apt-get "${apt_network[@]}" install -y --no-install-recommends \
appstream build-essential cmake cpio desktop-file-utils \
fcitx5-modules-dev file libasound2-dev libdbus-1-dev \
libfcitx5config-dev libfcitx5core-dev libfcitx5utils-dev \
liblzma-dev libpipewire-0.3-dev libpulse-dev libssl-dev \
libwayland-dev libx11-dev libxkbcommon-dev pkg-config ripgrep rpm
11 changes: 7 additions & 4 deletions .github/workflows/cache-maintenance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ name: Cache maintenance
# cold build. This job keeps the budget visible and drops the scopes that can
# never be restored again: pull requests that are already closed or merged.
#
# It runs weekly and on demand. It never touches branch or tag scopes, so the
# caches the release path depends on are safe.
# It runs daily, when a pull request closes, and on demand. It retains the
# newest branch generations and never prunes tag scopes.
on:
schedule:
# Monday 03:17 UTC: after the weekend, before the working week.
- cron: '17 3 * * 1'
# Daily cleanup prevents superseded build generations evicting baseline caches.
- cron: '17 3 * * *'
pull_request:
types: [closed]
branches: [main, beta]
workflow_dispatch:

permissions:
Expand Down
22 changes: 4 additions & 18 deletions .github/workflows/check-linux-egui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,8 @@ jobs:
if: inputs.scope != 'none'
# Same list as the packaging job: the fcitx5 plugin build and the
# `pwsh` contract scripts both live here now.
run: |
sudo add-apt-repository -y universe || true
sudo apt-get update
sudo apt-get install -y \
appstream build-essential cmake cpio desktop-file-utils \
fcitx5-modules-dev file libasound2-dev libdbus-1-dev \
libfcitx5config-dev libfcitx5core-dev libfcitx5utils-dev \
liblzma-dev libpipewire-0.3-dev libpulse-dev libssl-dev \
libwayland-dev libx11-dev libxkbcommon-dev pkg-config ripgrep rpm
timeout-minutes: 10
uses: ./.github/actions/setup-linux-dependencies

- uses: swatinem/rust-cache@v2
if: inputs.scope != 'none'
Expand Down Expand Up @@ -163,15 +156,8 @@ jobs:

- name: Install native build and packaging dependencies
if: inputs.scope != 'none'
run: |
sudo add-apt-repository -y universe || true
sudo apt-get update
sudo apt-get install -y \
appstream build-essential cmake cpio desktop-file-utils \
fcitx5-modules-dev file libasound2-dev libdbus-1-dev \
libfcitx5config-dev libfcitx5core-dev libfcitx5utils-dev \
liblzma-dev libpipewire-0.3-dev libpulse-dev libssl-dev \
libwayland-dev libx11-dev libxkbcommon-dev pkg-config ripgrep rpm
timeout-minutes: 10
uses: ./.github/actions/setup-linux-dependencies

- uses: dtolnay/rust-toolchain@stable
with:
Expand Down
29 changes: 25 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ on:
# Cancel old runs when the same PR is pushed repeatedly; workflow_dispatch is isolated by run_id.
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && github.run_id || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
cancel-in-progress: true

jobs:
# 判定这次改动能不能影响到各平台门禁。只有“改动物理上够不到”的变更才会
Expand Down Expand Up @@ -75,12 +75,16 @@ jobs:
done

ui-motion:
name: UI motion (Chromium + WebKit)
name: UI motion / ${{ matrix.browser }}
needs: [changes]
# Browser-rendered surface only: 15 minutes of Playwright on a change that
# cannot alter what Chromium/WebKit paints is pure cost.
if: (github.event_name != 'workflow_dispatch' || inputs.platform != 'macos') && needs.changes.outputs.frontend != 'false'
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
browser: [chromium, webkit]
# A hung Chromium/WebKit process must not hold the runner after the step cap.
# Setup plus the 12 minute dependency cap and the 30 minute browser cap.
timeout-minutes: 50
Expand Down Expand Up @@ -138,15 +142,31 @@ jobs:
key: ${{ steps.playwright_cache.outputs.cache-primary-key }}
- name: Run Chromium and WebKit UI motion checks
timeout-minutes: 30
run: npm run test:ui-motion
run: npm run test:ui-motion -- --project=${{ matrix.browser }}
- uses: actions/upload-artifact@v4
if: failure()
with:
name: ui-motion-failure
name: ui-motion-failure-${{ matrix.browser }}
path: |
openless-all/app/test-results/
openless-all/app/playwright-report/

ui-motion-result:
name: UI motion (Chromium + WebKit)
needs: [changes, ui-motion]
if: always() && (github.event_name != 'workflow_dispatch' || inputs.platform != 'macos')
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Require both browser results
env:
BROWSER_RESULT: ${{ needs.ui-motion.result }}
FRONTEND_REQUIRED: ${{ needs.changes.outputs.frontend }}
run: |
[ "$BROWSER_RESULT" = success ] || {
[ "$FRONTEND_REQUIRED" = false ] && [ "$BROWSER_RESULT" = skipped ]
}

android-check:
needs: [changes]
# Android compiles its own Rust graph: a bundle-only change cannot break it.
Expand Down Expand Up @@ -673,6 +693,7 @@ jobs:
# so the arm64 runner is not OOM-killed
# at peak memory.
CARGO_BUILD_JOBS: 2
CARGO_PROFILE_DEV_DEBUG: 0
CARGO_PROFILE_TEST_DEBUG: 0
CMAKE_BUILD_PARALLEL_LEVEL: 2
defaults:
Expand Down
15 changes: 9 additions & 6 deletions .github/workflows/release-tauri.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ on:
platform:
description: Desktop platforms to build (branch builds do not publish)
type: choice
options: [all, macos, windows]
options: [all, macos, macos-aarch64, macos-x86_64, windows]
default: all
windows_hang_diagnostics:
description: Opt-in issue 1266 Windows observation build (branch dispatch only)
Expand Down Expand Up @@ -63,7 +63,7 @@ jobs:
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.platform == 'windows' && '[{"platform":"windows-latest","rust-target":"x86_64-pc-windows-msvc","updater-target":"windows","updater-arch":"x86_64"}]' || github.event_name == 'workflow_dispatch' && inputs.platform == 'macos' && '[{"platform":"macos-latest","rust-target":"aarch64-apple-darwin","updater-target":"darwin","updater-arch":"aarch64"},{"platform":"macos-15-intel","rust-target":"x86_64-apple-darwin","updater-target":"darwin","updater-arch":"x86_64"}]' || '[{"platform":"macos-latest","rust-target":"aarch64-apple-darwin","updater-target":"darwin","updater-arch":"aarch64"},{"platform":"macos-15-intel","rust-target":"x86_64-apple-darwin","updater-target":"darwin","updater-arch":"x86_64"},{"platform":"windows-latest","rust-target":"x86_64-pc-windows-msvc","updater-target":"windows","updater-arch":"x86_64"}]') }}
include: ${{ fromJSON(github.event_name == 'workflow_dispatch' && inputs.platform == 'macos-aarch64' && '[{"platform":"macos-latest","rust-target":"aarch64-apple-darwin","updater-target":"darwin","updater-arch":"aarch64"}]' || github.event_name == 'workflow_dispatch' && inputs.platform == 'macos-x86_64' && '[{"platform":"macos-15-intel","rust-target":"x86_64-apple-darwin","updater-target":"darwin","updater-arch":"x86_64"}]' || github.event_name == 'workflow_dispatch' && inputs.platform == 'windows' && '[{"platform":"windows-latest","rust-target":"x86_64-pc-windows-msvc","updater-target":"windows","updater-arch":"x86_64"}]' || github.event_name == 'workflow_dispatch' && inputs.platform == 'macos' && '[{"platform":"macos-latest","rust-target":"aarch64-apple-darwin","updater-target":"darwin","updater-arch":"aarch64"},{"platform":"macos-15-intel","rust-target":"x86_64-apple-darwin","updater-target":"darwin","updater-arch":"x86_64"}]' || '[{"platform":"macos-latest","rust-target":"aarch64-apple-darwin","updater-target":"darwin","updater-arch":"aarch64"},{"platform":"macos-15-intel","rust-target":"x86_64-apple-darwin","updater-target":"darwin","updater-arch":"x86_64"},{"platform":"windows-latest","rust-target":"x86_64-pc-windows-msvc","updater-target":"windows","updater-arch":"x86_64"}]') }}
runs-on: ${{ matrix.platform }}
# A release build takes ~33 minutes from a cold cache; anything past this is
# a hang that would otherwise hold the runner and the release for hours.
Expand Down Expand Up @@ -117,14 +117,15 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
cache-dependency-path: 'openless-all/app/package-lock.json'
- name: Reuse baseline npm downloads
uses: ./.github/actions/cache-npm

- name: Verify repair source CI and version
if: inputs.release_tag != ''
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TOOLING_SOURCE_SHA: ${{ github.sha }}
run: |
set -euo pipefail
source_sha=$(git rev-parse HEAD)
Expand All @@ -134,8 +135,10 @@ jobs:
[ "${version%%+*}" = "$tag_version" ] || { echo "::error::Tag/application version mismatch"; exit 1; }
ci_id=$(gh api "repos/$GITHUB_REPOSITORY/actions/runs?head_sha=$source_sha&status=success&per_page=100" --jq "[.workflow_runs[] | select(.name == \"CI\" and .head_sha == \"$source_sha\" and .conclusion == \"success\")][0].id")
[[ "$ci_id" =~ ^[0-9]+$ ]] || { echo "::error::No green CI for the exact tagged commit"; exit 1; }
green=$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$ci_id/jobs?filter=latest&per_page=100" --jq '(.total_count == 7 and all(.jobs[]; .conclusion == "success"))')
[ "$green" = true ] || { echo "::error::All seven tagged-commit CI gates must pass"; exit 1; }
gh api "repos/$GITHUB_REPOSITORY/actions/runs/$ci_id/jobs?filter=latest&per_page=100" > "$RUNNER_TEMP/release-ci-jobs.json"
# The repaired tag may predate this verifier; use the immutable workflow source.
gh api "repos/$GITHUB_REPOSITORY/contents/openless-all/app/scripts/verify-release-ci.mjs?ref=$TOOLING_SOURCE_SHA" --jq .content | base64 --decode > "$RUNNER_TEMP/verify-release-ci.mjs"
node "$RUNNER_TEMP/verify-release-ci.mjs" "$RUNNER_TEMP/release-ci-jobs.json"
echo "Repair source verified: $source_sha ($version)"

- uses: dtolnay/rust-toolchain@stable
Expand Down
1 change: 0 additions & 1 deletion docs/2.0-desktop-acceptance.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
| 词库与纠错 | `src/pages/{Vocab,Corrections}.tsx`、`src-tauri/src/commands/dictionary.rs`、Core `vocabulary.rs` / `correction.rs` | 词库管理、纠错记录展示/删除/批量清理、重启后持久化与错误反馈 |
| 风格包与市场 | `src/pages/{Style,Marketplace}.tsx`、`src-tauri/src/commands/{style_packs,marketplace}.rs` | 导入/应用/导入导出失败反馈;市场浏览/安装/OAuth |
| 划词与 QA | `src/pages/{SelectionAsk,SelectionVoiceIntentPicker,QaPanel}.tsx`、Core `selection_voice_service.rs` | 选区编辑与空选区起草→意图→预览→应用/取消/撤回;传统/Omni 录音;终态不被迟到音量覆盖 |
| Less Computer | `src/pages/LessComputer{Panel,Glow}.tsx`、`src-tauri/src/coding_agent/` | 工具审批/输出/取消;Windows Job 对象与进程清理 |
| 手机输入 | `src-tauri/src/remote_server/`、远程输入页面 | 配对/TLS/会话桥接/弱网与陈旧地址处理 |
| 胶囊与多屏 | `src/components/Capsule.tsx`、`src-tauri/src/coordinator/capsule_focus.rs` | 跟随光标所在屏、多显示器/多 Space 正确显示;默认胶囊及翻译条支持明暗主题,磨砂层不遮挡控件、不扩散到透明宿主区域,入场/退出和打断重入连续 |
| 音频提示 | `src/components/AudioCue.tsx`、`src-tauri/src/audio_mute.rs` | 提示音、系统静音/恢复所有终态恢复音量 |
Expand Down
Loading
Loading