Skip to content

fix: restore packaged Nexu home and welcome redirect#885

Merged
lefarcen merged 1 commit intomainfrom
fix/restore-packaged-nexu-home
Apr 7, 2026
Merged

fix: restore packaged Nexu home and welcome redirect#885
lefarcen merged 1 commit intomainfrom
fix/restore-packaged-nexu-home

Conversation

@Siri-Ray
Copy link
Copy Markdown
Contributor

@Siri-Ray Siri-Ray commented Apr 7, 2026

What

Restore packaged desktop NEXU_HOME back to ~/.nexu, add a one-time migration for configs previously written under userData/.nexu, and keep the welcome page redirect gated on a ready auth session.

Why

Recent packaged builds started binding NEXU_HOME to userData/.nexu instead of the persistent ~/.nexu home. After upgrading, the controller could read a fresh empty config root and all channels appeared missing until users recreated them manually.

How

  • stop deriving packaged NEXU_HOME from userData
  • resolve packaged desktop home back to ~/.nexu
  • add a one-time migration that merges legacy userData/.nexu config and metadata into the stable home
  • add regression coverage for the new home path and migration behavior
  • keep the existing welcome-page auth-session redirect fix in this branch

Affected areas

  • Desktop app (Electron shell)
  • Controller (backend / API)
  • Web dashboard (React UI)
  • OpenClaw runtime
  • Skills
  • Shared schemas / packages
  • Build / CI / Tooling

Checklist

  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes
  • pnpm generate-types run (if API routes/schemas changed)
  • No credentials or tokens in code or logs
  • No any types introduced (use unknown with narrowing)

Notes for reviewers

I also built a local unsigned Apple Silicon package to verify the packaged desktop flow after the path fix.

@sentry
Copy link
Copy Markdown

sentry Bot commented Apr 7, 2026

Codecov Report

❌ Patch coverage is 79.71698% with 43 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
apps/desktop/main/services/nexu-home-migration.ts 89.67% 17 Missing and 2 partials ⚠️
apps/desktop/main/bootstrap.ts 0.00% 16 Missing ⚠️
apps/web/src/pages/welcome.tsx 11.11% 8 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7107e7769b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/main/services/nexu-home-migration.ts
Comment thread apps/desktop/shared/desktop-paths.ts
@lefarcen
Copy link
Copy Markdown
Collaborator

lefarcen commented Apr 7, 2026

审了一下,方向 OK,但有 1 个必须修的 bug 和 1 个建议改的点。考虑到范围只是 1.0.10 → 当前未发版窗口(仅影响装过 buggy 内部包的 QA),我把过度估计的部分都收回了。

🔴 必须修:welcome.tsx 违反 Rules of Hooks

apps/web/src/pages/welcome.tsx 在 9 个 useState 之后、两个 useEffect 之前插入了 early return:

if (setupComplete && authPending) {
  return <div className=\"min-h-screen bg-[#0b0b0d]\" />;
}
if (setupComplete && session?.user) {
  return <Navigate to=\"/workspace\" replace />;
}

useEffect(() => { ... }, [navigate]);   // ← 有时被跳过
useEffect(() => { ... }, [...]);        // ← 有时被跳过

当 `authPending` 从 true 变 false 时,渲染的 hook 数量会从 N 变成 N+2,React 会抛 "Rendered more hooks than during the previous render." 直接白屏。

这是 `react-hooks/rules-of-hooks` 必检的模式,PR 描述里说 `pnpm lint` 通过比较反常,建议本地再跑一次或检查 ESLint 配置是否启用了该规则。

修法:把跳转逻辑挪到一个 `useEffect` 里调 `navigate("/workspace", { replace: true })`,loading 态和 session 态用普通 state/JSX 表达,保证所有 hook 调用顺序稳定。


🟠 建议改:目录级 `existsSync` 太粗,会丢新文件

`nexu-home-migration.ts` 的 `copyDirIfMissing`:

```ts
if (!existsSync(sourceDir) || existsSync(targetDir)) {
return 0;
}
```

只要测试同学的 `~/.nexu/runtime/`(或 `artifacts/`、`logs/`、`skillhub-cache/`)已存在——哪怕里面是几个月前的旧文件——buggy 版本期间在 `userData/.nexu/runtime/` 里产生的新文件一个都不会迁移过去

`runtime/` 这个目录尤其要紧,里面是 openclaw 的 state(agents/sessions/extensions/identity/canvas/devices 等),这些是 buggy 版本期间用户实际操作积累出来的。如果 QA 已经在 buggy 包里跑过 openclaw,这部分状态会被静默丢弃。

建议:至少对 `runtime/` 改成递归文件级 merge(对每个 source 文件做 `copyFileIfMissing`),其他几个目录看实际写入频次决定要不要一并改。配套补一个测试:source 和 target 都有 `runtime/` 目录但内容不同的场景。


✅ 其他看过没问题的点

  • `mergeNexuConfig` 的 source-wins 语义对(buggy 版本里的修改是用户最近意图)
  • 数组 by id merge 对(channels/bots/providers/integrations)
  • stamp 文件机制对(防重入 + source 不存在也写 stamp)
  • `getLegacyPackagedNexuHomeDir` 抽出来作为兼容路径,结构清晰

⏸ 可以暂缓的点

  • 我一开始担心 `nexu.db` / `openclaw/` / `medeo*.json` 没在迁移列表里。但范围既然只是 1.0.10 → 当前未发版窗口,正确的判断方式是"buggy 版本的代码实际会写出哪些文件"而不是"我机器上 ~/.nexu 全量有什么"。如果想 double-check,可以扫一下 1.0.10 之后哪些代码引用 `process.env.NEXU_HOME` 或 `getDesktopNexuHomeDir` 写文件,确认列表是否覆盖。
  • dev 模式现在也读 `~/.nexu`(之前是 dev userData 下的 `.nexu`),开发者本地会和已安装的 nexu 共享数据。如果是有意的可以忽略;如果不是,建议保留一个 `NEXU_HOME` 环境变量 override 给 dev 用。

总结:hook bug 阻塞合并必须修;runtime/ 的目录级合并强烈建议改,避免 QA 数据丢失;其他可以这个 PR 不动。

@lefarcen lefarcen merged commit e11cdde into main Apr 7, 2026
19 checks passed
@lefarcen lefarcen mentioned this pull request Apr 8, 2026
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