Skip to content

feat: add style pack store v1 DRAFT! 别动我PR#429

Draft
Cooper-X-Oak wants to merge 12 commits into
Open-Less:betafrom
Cooper-X-Oak:cooper/style-pack-store-v1-beta
Draft

feat: add style pack store v1 DRAFT! 别动我PR#429
Cooper-X-Oak wants to merge 12 commits into
Open-Less:betafrom
Cooper-X-Oak:cooper/style-pack-store-v1-beta

Conversation

@Cooper-X-Oak
Copy link
Copy Markdown
Contributor

@Cooper-X-Oak Cooper-X-Oak commented May 13, 2026

User description

Summary

  • add the v1 Style Pack runtime, persistence, import/export, and runtime prompt selection flow
  • add the store-style Style management UI and updated example presentation
  • align the branch with current beta settings structure so the feature lands cleanly on the active development base

Verification

  • npm run build
  • cargo check --manifest-path src-tauri/Cargo.toml
  • npx tsx src/lib/stylePrefs.test.ts

PR Type

Enhancement, Bug fix, Tests


Description

  • Add persistent style pack storage

  • Route polishing through active packs

  • Sync prefs, tray, and exports

  • Move prompt editing into styles


Diagram Walkthrough

flowchart LR
  A["Style Pack UI"] -- "manage, import, export" --> B["Tauri commands"]
  B -- "persist and sync" --> C["StylePackStore"]
  C -- "update active pack" --> D["UserPreferences"]
  C -- "provide prompt/runtime" --> E["Polish and Dictation runtime"]
  E -- "preview diagnostics" --> A
Loading

File Walkthrough

Relevant files
Enhancement
11 files
persistence.rs
Add style pack persistence and import-export                         
+803/-3 
types.rs
Define style pack and prompt models                                           
+407/-0 
polish.rs
Assemble prompts from style pack content                                 
+134/-19
commands.rs
Expose style pack management commands                                       
+268/-28
coordinator.rs
Wire coordinator into style pack runtime                                 
+129/-19
lib.rs
Register style pack commands and tray                                       
+18/-7   
llm_gemini.rs
Pass style prompts into Gemini requests                                   
+2/-0     
Settings.tsx
Move prompt editing guidance into settings                             
+28/-1   
Style.tsx
Rebuild style pack management screen                                         
+1084/-223
ipc.ts
Add IPC bindings for style packs                                                 
+447/-6 
types.ts
Add frontend style pack types                                                       
+69/-0   
Bug fix
2 files
dictation.rs
Switch dictation to active style packs                                     
+115/-103
_atoms.tsx
Fix button cursor affordance                                                         
+1/-1     
Tests
2 files
backend_rust.rs
Add backend prompt stubs for tests                                             
+15/-0   
stylePrefs.test.ts
Cover style preference sync behavior                                         
+8/-0     
Documentation
5 files
ja.ts
Localize new style prompt settings copy                                   
+14/-0   
zh-TW.ts
Localize new style prompt settings copy                                   
+14/-0   
ko.ts
Localize new style prompt settings copy                                   
+14/-0   
zh-CN.ts
Localize new style prompt settings copy                                   
+14/-0   
en.ts
Add English copy for style prompts                                             
+14/-0   

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 13, 2026

PR Reviewer Guide 🔍

(Review updated until commit c77e235)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Stale prefs

Disabling or deleting a style pack only updates StylePackStore; it never resyncs UserPreferences. If the active pack is turned off or removed, active_style_pack_id and enabled_modes can keep pointing at the old pack until restart, so tray state and runtime selection can disagree with the persisted prefs in the same session.

                    log::warn!(
                        "[coord] QA hotkey 第 {attempts} 次注册超时(主线程未回执);3s 后重试"
                    );
                }
                std::thread::sleep(std::time::Duration::from_secs(3));
                continue;
            }
        };

        match init_result {
            Ok(monitor) => {
                *inner.qa_hotkey.lock() = Some(monitor);
                log::info!(
                    "[coord] QA hotkey listener installed on main thread (after {} attempt(s))",
                    attempts + 1
                );
                let inner_clone = Arc::clone(&inner);
                std::thread::Builder::new()
                    .name("openless-qa-hotkey-bridge".into())
                    .spawn(move || qa_hotkey_bridge_loop(inner_clone, rx))
                    .ok();
                attempts = 0;
            }
            Err(e) => {
                attempts += 1;
                if attempts <= 3 || attempts % 10 == 0 {
                    log::warn!("[coord] QA hotkey 第 {attempts} 次注册失败: {e}; 3s 后重试");
                }
                std::thread::sleep(std::time::Duration::from_secs(3));
            }
        }
    }
}

fn qa_hotkey_bridge_loop(inner: Arc<Inner>, rx: mpsc::Receiver<QaHotkeyEvent>) {
    while let Ok(evt) = rx.recv() {
        if inner.shortcut_recording_active.load(Ordering::SeqCst) {
            continue;
        }
        let inner_cloned = Arc::clone(&inner);
        match evt {
            QaHotkeyEvent::Pressed => {
                async_runtime::spawn(async move { handle_qa_hotkey_pressed(&inner_cloned).await });
            }
        }
    }
}

// ─────────────────────────── combo hotkey supervisor ───────────────────────────

fn combo_hotkey_supervisor_loop(inner: Arc<Inner>) {
    let mut attempts: u32 = 0;
    loop {
        if inner.shutdown.load(Ordering::SeqCst) {
            return;
        }
        // 读当前 prefs
        let prefs = inner.prefs.get();
        if crate::shortcut_binding::legacy_modifier_trigger(&prefs.dictation_hotkey).is_some() {
            // 不是 Custom → 睡着等 prefs 改动
            take_combo_hotkey_on_main_thread(&inner);
            std::thread::sleep(std::time::Duration::from_secs(5));
            continue;
        }

        let binding = prefs.dictation_hotkey.clone();
Partial typing bug

On the streaming path, the code now appends the full delta whenever type_unicode_chunk returns Ok(_), but the old implementation used the returned typed-char count. If that function can emit only a prefix of delta on success, typed_text will advance past characters that were never actually inserted, causing later chunks and finalization to drift.

match crate::unicode_keystroke::type_unicode_chunk(&delta) {
    Ok(_) => {
        typed_text.push_str(&delta);
    }

@Cooper-X-Oak
Copy link
Copy Markdown
Contributor Author

Cooper-X-Oak commented May 13, 2026

先别动我的PR 别动 别动 别动,等github的review,等我自己的review,等测试

@Cooper-X-Oak Cooper-X-Oak marked this pull request as draft May 13, 2026 06:20
@Cooper-X-Oak Cooper-X-Oak changed the title feat: add style pack store v1 feat: add style pack store v1 DRAFT! 别动我PR May 13, 2026
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 7616ef0

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit c77d9f4

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 0a19ad3

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 0c6cc8b

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 16dd99c

@Cooper-X-Oak
Copy link
Copy Markdown
Contributor Author

补充一轮 review fix:

  • 修了 tray 样式切换只改 default_mode、没有同步 active_style_pack_id 的问题。现在托盘、set_default_polish_modeset_active_style_pack 复用同一套激活 helper,切换内置样式会统一启用目标 pack、写 active id、同步持久化并刷新 tray。
  • 修了流式插入路径在字符已经打到光标后又继续做简繁/纠错后处理的问题。现在 already_streamed=true 时直接以已流式输出的文本作为最终结果,避免 screen / clipboard / history 分叉。
  • 顺手补了两个低成本修复:legacy custom prompt 迁移避免重复追加,get_or_default_active fallback 到 builtin light 时也要求该 pack 处于 enabled。

本地验证:

  • npm run build 通过
  • npx tsx src/lib/stylePrefs.test.ts 通过
  • cargo check --manifest-path src-tauri/Cargo.toml 通过
  • cargo fmt --manifest-path src-tauri/Cargo.toml --check 通过
  • 本机 cargo test --manifest-path src-tauri/Cargo.toml --lib 当前在启动 test harness 时直接异常退出,返回 0xc0000139 STATUS_ENTRYPOINT_NOT_FOUND--no-run 可通过,说明编译层面正常,这个看起来是当前 Windows 本地测试运行环境问题,不是新增断言失败。CI 已重新触发,等线上结果补充。

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit a4c4cc2

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit ae2c7e4

@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit c77e235

@Cooper-X-Oak
Copy link
Copy Markdown
Contributor Author

Final merge-ready review summary

这一轮我按 origin/beta...HEAD 做了面向真实本地使用链路的最终复核,目标是判断 Style Store / Style Pack v1 及其后续 review fix 是否已经达到可合并质量,而不是继续扩功能。

复核范围

  • diff review:覆盖 origin/beta...HEAD 及其直接受影响链路
  • 本地产品验收:Style Store / Style Pack、导入导出、持久化、tray 切换、streaming insertion、一致性/回归风险
  • 工程门禁:前端构建、TS 校验、Rust 编译检查、可运行后端测试、PR CI

过程中的关键问题与修复

1. 导出未保存 draft 时导出的是旧持久化内容

  • 复现:编辑 builtin style pack,修改名称/Prompt 但不保存,直接点“导出 ZIP”
  • 预期:阻止导出,要求先保存当前 draft
  • 实际:UI 提示导出成功,但导出的仍是旧的 persisted pack
  • 修复:ae2c7e4
  • 结果:现在会明确提示“请先保存当前风格包,再导出 ZIP。”,不再导出旧内容

2. tray / 热键切换 style 后 UI 与 prefs 不同步

  • 复现:通过 switch-style 热键切换当前 style
  • 预期:prefs、tray、前端状态同步更新
  • 实际:prefs 写了,但 prefs:changed / tray refresh 不完整,UI 可能滞后
  • 修复:ae2c7e4
  • 结果:切换后会补发 prefs:changed,并在主线程刷新 tray

3. builtin style pack 保存/重置后,store 与 prefs 兼容字段可能重新分叉

  • 复现路径:builtin style pack 保存/重置只更新 store,不同步 prefs.style_system_prompts;后续任意 Settings 保存可能把旧 prefs 再写回
  • 预期:store / prefs / 后续 set_settings 持久化保持同一事实源
  • 实际:存在“新 style pack store + 旧 prefs 兼容字段”的持久化不一致风险
  • 修复:c77e235
  • 修复内容:
    • set_settings 先按当前 style pack store 归一化 style prefs
    • builtin pack 的保存/重置后立即同步 prefs 并广播
    • sync_style_pack_preferences 现在会把 builtin prompts 回填到 prefs,并清空遗留 custom_style_prompts
  • 结果:style pack store 重新成为单一事实源,避免后续设置保存把旧 prompt 回写覆盖

本地验证结果

  • npm run build:通过
  • cargo check --manifest-path src-tauri/Cargo.toml:通过
  • npx tsx src/lib/stylePrefs.test.ts:此前通过
  • cargo test --manifest-path openless-all/app/src-tauri/backend-tests/Cargo.toml --test backend_rust -- --nocapture:47/47 通过

CI 结果

当前 PR head 已更新为 c77e235,本轮 CI 全绿:

  • Linux checks: pass
  • Windows checks: pass
  • macOS checks: pass
  • pr_agent_job: pass

最终结论

这一轮复核里发现过真实阻塞项,但都已经用最小必要改动修复并完成本地回归 + CI 回归。以当前 PR head 来看,我这边的结论是:已达到 merge-ready,可继续正常评审/合并。

唯一保留说明:主 crate 的 cargo test --lib 在这台 Windows 环境里仍受既有 STATUS_ENTRYPOINT_NOT_FOUND 测试运行时问题影响,所以新增的持久化回归测试目前主要依赖代码审查 + cargo check + 现有 backend harness + CI 交叉覆盖;这不构成当前 PR 的 merge blocker。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant