Skip to content

[codex] Defer launcher ready until initial prompt data settles#43

Draft
ZeroPointSix wants to merge 7 commits into
masterfrom
codex/defer-launcher-ready
Draft

[codex] Defer launcher ready until initial prompt data settles#43
ZeroPointSix wants to merge 7 commits into
masterfrom
codex/defer-launcher-ready

Conversation

@ZeroPointSix

Copy link
Copy Markdown
Owner

Summary

Fix the Windows cold-launch blank/white launcher state by delaying the backend frontend_ready notification until after the first prompt search has completed and the Svelte page has a chance to write initial result state.

Root Cause

The route currently calls frontendReady() as soon as the component mounts. The backend treats that as permission to show the hidden Tauri window, even though config loading, prompt loading, and the first search result refresh still happen afterward. On Windows, the transparent hidden window can therefore be shown during a half-initialized frame; toggling Settings later forces another render/resize, which makes the launcher appear normal.

Changes

  • Added a small launcher ready gate that only notifies the backend after the frontend has mounted and initial data has returned.
  • Updated tauriClient.searchPrompts to schedule backend readiness after the first search result response.
  • Kept backend notification idempotent and retryable if the notification fails.
  • Added Node unit tests for the ready gate behavior.

Validation

  • Added prompt-launcher/src/lib/launcherReadyGate.test.js for the new readiness gate.
  • Expected CI path: npm run test:unit, npm run check, frontend build, and Tauri build on PR.
  • Local checkout/test execution was not available in this container because direct GitHub clone/download requests are blocked, so the PR CI should be used as the authoritative run.

Copy link
Copy Markdown
Owner Author

总体结论:这个 PR 把 frontend_ready 延后到首次搜索返回之后,方向能解释并缓解 Windows 冷启动白屏;但当前 ready gate 对首次搜索失败路径没有兜底,存在窗口一直不显示的回归风险,建议合并前补一个失败/空数据场景。

关键发现:

  • 高:tauriClient.frontendReady() 现在只调用 launcherReadyGate.markMounted(),真正通知后端依赖后续 searchPrompts() 成功返回后执行 scheduleAfterInitialData()。如果首次 search_prompts 因配置、目录权限、数据损坏或 Tauri invoke 临时失败而 reject,frontend_ready 不会发送,隐藏窗口可能一直保持不可见。建议在首次数据加载失败路径也安排一次后端 ready 通知,或增加一个短超时兜底:页面已 mount 后,即使初始搜索失败,也展示错误/空态而不是保持隐藏。
  • 中:新增 gate 测试覆盖了未 mounted、合并重复请求、失败重试,但没有覆盖“initial data promise reject 后仍应展示可诊断 UI”的产品路径。建议补一个单元测试或组件级测试,明确失败时会重试/兜底通知后端。
  • 低:prompt-launcher/src/lib/tauriClient.ts diff 显示文件末尾缺少换行。建议顺手补回,避免格式检查或后续 diff 噪声。

优先级建议:

  • 阻塞:首次搜索失败导致窗口可能永远不显示,需要先处理或明确证明调用方已有 catch 后会触发 ready。
  • 中:补失败路径测试。
  • 低:补文件末尾换行。

后续建议:

  • 保留“mounted + initial data settled 后再通知”的思路,但把触发条件从“搜索成功”调整为“搜索完成,无论成功或失败”,这样既避免半初始化白屏,也能让用户看到可恢复的错误状态。

@ZeroPointSix

Copy link
Copy Markdown
Owner Author

CodeXWeb 本轮自动巡检已认领这个 PR 的未解决修改意见,正在处理。

本轮自动巡检只会处理这一项:PR #43 中关于首次 search_prompts 失败时仍需触发可诊断 UI/后端 ready 通知的 review 反馈;不会同时处理其他 Issue 或 PR。

@ZeroPointSix

Copy link
Copy Markdown
Owner Author

CodeXWeb 本轮已完成 PR #43 中已认领的 review 反馈处理。

处理范围:

  • 针对 comment 4670504519 中的阻塞点,保留“mounted + initial data settled 后再通知 backend”的设计,但把 initial data 的判定改为 settled 语义:search_prompts 成功或失败后都会调度 frontend_ready
  • search_prompts 失败时仍会把原错误继续抛给现有 UI 初始化错误展示逻辑,因此不会吞掉失败原因。
  • 新增 notifyWhenInitialDataSettles() helper,并补充 rejected promise 场景单元测试,覆盖首次搜索失败仍触发 ready 调度。
  • 更新 DECISION_JOURNAL.md 留痕。

推送:

  • 5eefaab fix: notify launcher ready after failed initial search
  • 030d8c8 docs: record pr43 validation

远程沙箱验证:

  • npm ci --include=dev --no-audit --no-fund 通过
  • npm run test:unit 通过:15 passed
  • npm run check 通过:0 errors, 0 warnings
  • npm run build 通过
  • git diff --check 通过

限制/风险:

  • npm run tauri build 已尝试,但远程沙箱缺少 cargo,在 cargo metadata 阶段失败;本次未改 Rust/Tauri 源码。
  • 构建仍输出一个既有的 LogicalSize 未使用导入警告,未纳入本轮 review 反馈范围。

@ZeroPointSix ZeroPointSix left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

总体结论:本轮补充审查覆盖了原 review 之后新增的 head commit 030d8c8;阻塞点“首次 search_prompts 失败时隐藏窗口可能永远不显示”已经被正向修复,当前未发现新的阻塞问题。

关键发现:

  • 原高优先级风险已处理:searchPrompts() 现在通过 notifyWhenInitialDataSettles() 包装 invoke("search_prompts"),无论首次搜索成功还是 reject,finally 都会调用 gate.scheduleAfterInitialData()。这样可以让后端收到 frontend_ready,用户能看到已有错误态,而不是窗口继续隐藏。
  • 新增测试覆盖到位:launcherReadyGate.test.js 增加 rejected promise 场景,断言失败路径仍会调度 ready,同时保留原错误继续向外抛出,避免吞掉 UI 初始化失败原因。
  • ready gate 的幂等与重试语义仍合理:未 mounted 时不通知、重复 ready 请求合并、通知失败后允许后续再次调度,和本 PR 的“避免半初始化白屏,同时展示可诊断状态”目标一致。
  • 低:prompt-launcher/src/lib/tauriClient.ts 仍显示文件末尾缺少换行(patch 中有 No newline at end of file)。这不影响运行时行为,但建议在转 ready 前补上,避免格式检查或后续 diff 噪声。

优先级建议:

  • 阻塞:无。
  • 低:补回 tauriClient.ts 文件末尾换行。
  • 低:由于沙箱缺少 cargonpm run tauri build 未完成;本次未改 Rust/Tauri 源码,但合并前仍建议以 GitHub Actions 或具备 Rust/Tauri 环境的 runner 作为最终验证。

后续建议:

  • 可以保留当前设计:以“initial data settled”而不是“initial data succeeded”作为释放隐藏窗口的条件。这样既避免冷启动半初始化白屏,也能在初始化失败时显示可恢复的错误状态。

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants