Commit Graph
291 Commits
Author SHA1 Message Date
baiqing 0bf4f7e253 fix(capsule): Windows 翻译模式 host 高度跟随 translation flag
PR Reviewer (PR Agent) 指出:getCapsuleHostMetrics(os, false) 把
translation 参数硬编码成 false,Windows 端 host 在翻译模式下应该从
84 长到 118,硬编码后徽章 bottom 用更短 host 量出来 → 跟 118pt 实际
窗口尺寸错位、徽章可能溢出或被裁。

修:把 useState<translation> 提到 hostMetrics 之前,调用改回
getCapsuleHostMetrics(os, translation)。macOS / Linux 不受影响 —
capsuleLayout 在那两个分支已经忽略 translationActive 返回固定 42。
2026-05-03 15:04:36 +08:00
baiqing d39072a21f Merge remote-tracking branch 'origin/main' into codex/fix-macos-window-ui
# Conflicts:
#	openless-all/app/src-tauri/src/polish.rs
2026-05-03 13:55:44 +08:00
baiqing 65f84305cc feat(polish): 自动纠错 + 按整体意图组织自然书面表达
补 COMMON_RULES 两条:
- 规则 3 扩展:在保留原意和语气的前提下,按用户的整体意图把零碎口语
  组织成协调、自然的书面表达。
- 规则 5(新增)自动纠错:明显的 ASR 同音 / 形近错字按上下文纠回正确字面,
  覆盖"跟目录/根木鹿→根目录"、"代码厂→代码仓"、"编一编→编译"、
  "的/得/地"、"做/作"等常见错别字。专有名词、人名、品牌名、不在常见
  中文词典里的词原样保留,不强行改字;改动会引起含义变化的不改。

不动 ROLE_BLOCK / OUTPUT_BLOCK / 各 mode 任务段,保持"不要激进改写"
的边界(feedback memory)。translate / qa prompt 与本次诉求无关,未改。

加一个测试 common_rules_include_auto_correction_and_natural_organization
覆盖四个 mode,防止规则被回退或遗漏。
2026-05-03 13:36:31 +08:00
baiqing f06f305774 fix(macos): align with 1.2.11 window/capsule UI + tab cross-fade
红绿灯
- trafficLightPosition x=14 y=20(Apple Notes / Safari 视觉),
  MAC_TITLEBAR_HEIGHT 30→28,paddingTop 30→28,让红绿灯在 titlebar
  内对称居中。

胶囊几何回退到 1.2.11
- macOS / Linux 上 capsule_window_bounds 固定 220×110,capsule_visual_height
  改回 96,emit_capsule 不再随 translation_active 改 size + 位置。修两个
  回归:(a) 录音胶囊 pill 左右被裁;(b) 按 Shift 后窗口高度从 42→110
  导致整体下移。
- 单元测试断言同步更新。

emit_capsule macOS show 路径回退到 1.2.11
- show_capsule_window_no_activate macOS 实现删除(合进 cfg(not(windows))
  stub 返回 false),fallback 走 window.show() + restore_main_window_key_if_active。
  orderFrontRegardless 路径在 webview 未完整初始化时偶发不可见。

Translation 设置页 + i18n 回退到 1.2.12
- 撤回 d7d274f 整页重排,回到 1.2.11/1.2.12 的简洁布局。

tab 切换 cross-fade with blur
- FloatingShell.tsx 加 displayTab + tabPhase;点新 tab 触发旧页
  ol-page-fadeout(opacity 1→0、blur 0→8px、180ms),结束后挂载
  新页走现有 ol-page-slide。修 Windows 徽章 bottom 公式:保留
  hostMetrics 路径(pill 不在 win host 中线,calc(50%) 不对)。

Capsule.tsx 动画化简
- 徽章/capsule-in 撤回 motion-soft / motion-spring 别名 + filter blur,
  回到 1.2.11 的 ease-out / cubic-bezier。
2026-05-03 13:29:53 +08:00
Chris233 90497a6147 Merge pull request #197 from H-Chris233/main
fix(window): 恢复 macOS 原生交通灯
2026-05-03 12:54:06 +08:00
H-Chris233 6545231d83 Restore mac traffic lights without enabling native chrome on Linux/Windows
Keep custom chrome on non-mac platforms while restoring native traffic lights on macOS. Also remove the extra outer mac shell radius/border to avoid double-rounded corners.

Constraint: macOS must show native traffic lights for issue #183
Constraint: Windows/Linux should keep custom titlebar behavior
Rejected: set decorations=true in tauri.conf globally | enables native chrome on Linux
Confidence: high
Scope-risk: narrow
Directive: Platform-specific window decoration behavior should be controlled at runtime, not by global config
Tested: npm run build (openless-all/app)
Not-tested: manual visual verification on real macOS/Linux/Windows runtimes
2026-05-03 12:22:14 +08:00
Chris233 a2a5605239 Merge pull request #193 from H-Chris233/main
fix(llm): 允许无密钥 LLM 配置
2026-05-03 12:13:50 +08:00
H-Chris233 b85006c9a9 Allow keyless custom LLM endpoints while blocking default Ark fallback leakage
Content flows now allow empty Ark API keys only when a custom Ark endpoint is configured. If both key and endpoint are empty, we fail locally instead of falling back to the public Ark endpoint, preserving the privacy guard while restoring ticket #192 keyless self-hosted behavior.

Constraint: Keep no-key self-hosted OpenAI-compatible LLM support from issue #192
Constraint: Prevent transcript content from being sent to default public Ark endpoint when key is empty
Rejected: unconditional API-key requirement in coordinator | breaks keyless self-hosted usage
Rejected: unconditional default-endpoint fallback | risks accidental data egress on fresh installs
Confidence: high
Scope-risk: narrow
Directive: Any future endpoint fallback change must preserve the blank-key + blank-endpoint local guard for content-sending flows
Tested: rustfmt --edition 2021 --check src/coordinator.rs; cargo test --lib resolve_ark_endpoint_
Not-tested: end-to-end UI interaction for keyless custom endpoint polish/translate/chat
2026-05-03 11:40:52 +08:00
baiqing d7d274fa87 fix(ui): clean sidebar and translation settings 2026-05-03 10:03:40 +08:00
H-Chris233 7e36d0756c Block keyless Ark content flows before default endpoint fallback
Polish, translate, and QA chat now fail locally when ArkApiKey is blank, so fresh installs and keyless LLM setups do not leak transcript content to the default public Ark endpoint. Model discovery remains keyless because it is a separate non-content path.

Constraint: LLM model discovery must stay keyless
Rejected: rely on downstream provider auth failures | leaks user content over the network
Confidence: high
Scope-risk: narrow
Directive: Keep the blank-key guard ahead of any Ark endpoint fallback in content-sending flows
Tested: cargo test --lib require_ark_api_key_rejects_blank_key; rustfmt --edition 2021 --check src/coordinator.rs
Not-tested: full UI settings flow
2026-05-03 10:03:39 +08:00
baiqing 91f1c5fae8 fix(macos): keep native traffic lights visible 2026-05-03 09:56:47 +08:00
TRIP 7f64a1b464 fix(ci): allow PR-Agent review on external PRs 2026-05-03 09:55:17 +08:00
H-Chris233 1d0dcef18c Skip auth header for blank-key LLM model discovery
Model discovery now matches the keyless LLM path by omitting Authorization when the stored API key is blank. This keeps Fetch models usable for endpoints that reject empty Bearer credentials while preserving authenticated discovery for configured providers.

Constraint: ASR still requires an API key
Rejected: send a fake or empty Bearer header | breaks keyless endpoints
Confidence: high
Scope-risk: narrow
Directive: Do not reintroduce auth headers for blank LLM keys without a provider-specific requirement
Tested: cargo test --lib fetch_provider_models_omits_authorization_when_api_key_is_empty; rustfmt --edition 2021 --check src/commands.rs
Not-tested: full frontend integration flow
2026-05-03 09:51:39 +08:00
baiqing 420c5425e6 fix(macos): tune window chrome motion 2026-05-03 09:43:19 +08:00
baiqing f89a285877 fix(macos): restore native window chrome and capsule focus 2026-05-03 09:29:59 +08:00
H-Chris233 0fe00ced9a Allow LLM validation without a saved API key
Some OpenAI-compatible LLM endpoints do not require an API key, so the LLM validation and runtime polish paths should not invent one or fail early when the key field is blank. The client now omits the Authorization header when the key is empty, the coordinator stops treating a blank LLM key as a hard error, and the settings validation continues to distinguish a missing model from a genuinely failed connection.

Constraint: Keep the change minimal and preserve the existing HTTP-status error mapping.
Rejected: Keep key-required behavior for all LLM endpoints | it mislabels keyless endpoints such as local 11443-style servers as invalid.
Confidence: high
Scope-risk: moderate
Directive: Empty LLM API keys are allowed only for the OpenAI-compatible path; ASR remains key-required.
Tested: npm run build; cargo test --lib
Not-tested: Live behavior against a real keyless endpoint outside the test harness
2026-05-02 23:32:27 +08:00
Chris233 280b50ea17 更新 pr-agent.yml 2026-05-02 21:16:12 +08:00
Chris233 dbd0503c55 Merge pull request #187 from H-Chris233/main
fix(settings): 用当前模型验证连接
2026-05-02 20:23:05 +08:00
Chris233 69d7f62161 更新 pr-agent.yml 2026-05-02 20:07:26 +08:00
H-Chris233 e99619948e Treat missing LLM model as unconfigured
The LLM connection check no longer falls back to an Ark-specific default model when the user has not configured one. Instead, it returns a dedicated marker and the settings UI surfaces the empty-state copy, which keeps the validation result aligned with the actual configuration state.

Constraint: Preserve the existing provider-status parsing and keep the change minimal.
Rejected: Keep the deepseek-v3-2 fallback | it creates a false positive for unconfigured non-Ark providers.
Confidence: high
Scope-risk: narrow
Directive: Validation should never invent a model when the user has not saved one.
Tested: npm run build; cargo test --lib
Not-tested: Live provider behavior with a truly empty model field on a real endpoint
2026-05-02 19:59:09 +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
H-Chris233 5725e4433a Preserve provider HTTP markers in LLM validation failures
LLM validation now maps non-2xx completion responses back to the same providerHttpStatus:<code> marker used by the model-listing path. That keeps the settings page on its existing error-copy branch so real API-key, endpoint, and model failures stay diagnosable instead of collapsing into a generic message.

Constraint: Keep the change minimal and preserve the existing settings error-message parser.
Rejected: Teach the frontend to parse LLMError::InvalidResponse text | this would duplicate provider-status semantics and broaden the UI change.
Confidence: high
Scope-risk: narrow
Directive: Validation error strings for provider status should stay normalized at the command boundary.
Tested: cargo test --lib
Not-tested: Live provider error text against a real non-2xx endpoint
2026-05-02 17:03:55 +08:00
Chris233 a259b57d5e Merge branch 'appergb:main' into main 2026-05-02 16:11:42 +08:00
baiqing 89dd4e49bb chore: release 1.2.12 2026-05-02 12:19:28 +08:00
TRIP 7aefb8199e Merge pull request #181 from Cooper-X-Oak/codex/windows-native-titlebar-off
fix(windows): 收紧主窗口 shell 外观契约
2026-05-02 12:18:12 +08:00
Cooper-X-Oak 802ee653c9 fix(windows): 收紧主窗口 shell 外观契约 2026-05-02 12:12:46 +08:00
Cooper-X-Oak 946d842023 fix(windows): restore custom chrome interactions 2026-05-02 12:12:02 +08:00
Cooper-X-Oak 4ea8389ceb fix(windows): align custom shell rounded frame 2026-05-02 12:12:02 +08:00
Cooper-X-Oak f83a5339c7 fix(windows): remove native titlebar before first show 2026-05-02 12:12:02 +08:00
TRIP a2d243f333 Merge pull request #182 from Cooper-X-Oak/codex/windows-capsule-geometry-pr
fix(windows): 收紧 Capsule 几何契约
2026-05-02 12:11:51 +08:00
baiqing 9fd726ec87 test(windows): 对齐 capsule geometry 新契约断言 2026-05-02 12:06:22 +08:00
Cooper-X-Oak 9875e089d8 fix(windows): 收紧 capsule 几何契约 2026-05-02 12:05:09 +08:00
Cooper-X-Oak f8c5337084 docs(windows): 为 issue 142 建立 capsule 占位 2026-05-02 12:04:28 +08:00
TRIP 13d9d29233 Merge pull request #180 from appergb/fix/issue-165-linux-contract-alignment
fix(linux): 收敛平台契约错配与 best-effort 降级
2026-05-02 11:53:24 +08:00
TRIP 9510611a82 Merge pull request #179 from appergb/fix/issue-167-clipboard-restore-queue
fix(windows): 收敛 clipboard restore 并发恢复竞态
2026-05-02 11:49:22 +08:00
TRIP ae6be2defc Merge pull request #178 from appergb/fix/issue-164-qa-window-no-activate
fix(windows): QA 浮窗显示时不再抢前台焦点
2026-05-02 11:49:14 +08:00
TRIP 652b6d7bab Merge pull request #177 from appergb/fix/issue-166-mic-permission-no-activate
fix(mic): dictation 缺麦克风权限时不再抢前台焦点
2026-05-02 11:49:06 +08:00
baiqing dd7c02558f fix(linux): 收敛平台契约错配与 best-effort 降级 (closes #165) 2026-05-02 11:48:15 +08:00
baiqing d74d947106 fix(windows): 收敛 clipboard restore 并发恢复竞态 (closes #167) 2026-05-02 11:41:40 +08:00
baiqing 6a915c762f chore(windows): 补齐 QA no-activate 依赖锁文件 2026-05-02 11:40:06 +08:00
baiqing d4e7a8b4fe fix(windows): QA 浮窗显示时不再抢前台焦点 (closes #164) 2026-05-02 11:38:30 +08:00
baiqing 1fc6d9bd3f fix(mic): 听写路径请求麦克风权限时不再抢前台焦点 (closes #166) 2026-05-02 11:35:45 +08:00
TRIP 0c4fbb9815 Merge pull request #176 from appergb/fix/issue-161-qa-cancel-race
fix(qa): 修划词追问浮窗 4 个取消 race (closes #161)
2026-05-02 11:34:30 +08:00
baiqing db27107e7a fix(qa): 修划词追问浮窗 4 个取消 race (closes #161)
issue #161 4 个子修复合并为一个 PR(取消相关,紧密耦合)。

## 1. Esc 路由
coordinator.rs::handle_window_hotkey_event 之前无条件 cancel_session(dictation
取消),即使在 QA 浮窗里按 Esc 也杀的是 dictation。现在先查 qa_state.panel_visible
+ phase != Idle,是 → close_qa_panel;否 → 走 dictation 取消。

## 2. SSE 流取消旗标
- Inner 加 qa_stream_cancelled: Arc<AtomicBool>
- begin_qa_session 重置 false
- cancel_qa_session set true
- polish.rs::chat_completion_history_streaming 的 SSE loop 每帧检查
  should_cancel() flag,true 时立即 break,避免取消后 LLM 继续 drain
  HTTP body 烧 token

## 3. session_id 守卫
on_delta 闭包捕获本会话的 captured_session_id;emit chunk 前比对当前
qa_state.session_id,不等就跳过。修复"取消后开新会话,旧 LLM 流的
chunk 漏进新气泡"。

## 4. loading 帧
types.ts::QaStateKind 加 'loading';QaPanel.tsx switch 加 case:把 status
切到 'thinking' 视图,避免 ASR finalize 期间 UI 卡 'recording' 几百 ms
反馈缺失。

## API 变化
- polish::answer_chat_streaming<F, C> 签名加 should_cancel: C
- polish::chat_completion_history_streaming<F, C> 同
- coordinator::answer_chat_dispatch<F, C> 同

## 测试
- cargo check ✅
- npm run build ✅
2026-05-02 10:56:40 +08:00
TRIP f5ffd9ef0f Merge pull request #175 from appergb/fix/issue-168-qa-recorder-error-monitor
fix(qa): QA recorder error monitor (closes #168)
2026-05-02 10:51:36 +08:00
TRIP fcd37fbc71 Merge pull request #174 from appergb/fix/issue-169-macos-exit-main-thread
fix(macos): stop_qa_hotkey_listener 包 run_on_main_thread (closes #169)
2026-05-02 10:51:30 +08:00
baiqing 65d4b5243b fix(qa): 加 QA recorder runtime error monitor (closes #168)
QA 录音中麦克风设备消失 / cpal 内部 panic 时,QA 流程之前**没有**对应
runtime error 监听器(recorder_errors 用 _ 弃用),导致:
- QA 浮窗一直显示"录音中"
- 用户按 Option 第二次没反应
- 必须按 Esc 才能脱困

修:
- 新增 spawn_qa_recorder_error_monitor,镜像 dictation 现有 spawn_recorder_error_monitor
- begin_qa_session Recorder::start 成功后启动监听器
- 用 qa_state.session_id 守卫 stale 事件
- 收到 error → finish_qa_with_error("录音设备异常: ..") → emit 错误胶囊 + 浮窗错误状态

测试:
- cargo check ✅
2026-05-02 10:46:03 +08:00