Skip to content

chore(desktop): rename packages/desktop-shell to packages/desktop - #12653

Merged
yiliang114 merged 7 commits into
mainfrom
chore/rename-desktop-shell
Sep 25, 2026
Merged

yiliang114 merged 7 commits into
mainfrom
chore/rename-desktop-shell

Conversation

@yiliang114

@yiliang114 yiliang114 commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

What this PR does

Renames packages/desktop-shell to packages/desktop and updates every load-bearing reference: npm/pnpm workspace negations, the ci.yml crate filter, desktop-release.yml, the desktop isolation guard, eslint/prettier ignores, scripts and CLI test fixtures, the brand-builder skill, and living docs (docs/developers/architecture.md, .qwen/skills/).

The crate name (qwen-code-desktop), productName ("Qwen Code Desktop"), bundle identifier, updater feed, desktop-v* tag scheme, and the legacy electron-bridge asset names are all unchanged — nothing user-facing moves. One name does change: the npm package is now @qwen-code/desktop (it is private: true, and the old name appears nowhere outside the package's own manifest and lockfile).

Why it's needed

#8596 retired the Electron app; #9085 removed the old packages/desktop, and the OpenWork downstream has since forked. The desktop-shell name is the last artifact of the transition period — the short name is free, and keeping the suffix permanently costs every reader a "which desktop is this?" moment. No open PR touched packages/desktop-shell when this branch was cut, so this was the quiet window to do it. #12649 has since opened and edits two old-path files — see Risk & Scope.

Reviewer Test Plan

How to verify

  1. git diff --stat should show the move as renames with high similarity, plus targeted reference edits — no logic changes.
  2. npm run check:desktop-isolation — now guards both the new and the old path.
  3. cd packages/desktop && npm ci && npm test — compiles the crate at the new path and runs the Rust suite.
  4. node packages/desktop/scripts/test-release.js.
  5. Focused suites: npx vitest run src/commands/review/ (workspace fixtures) and the scripts tests below.

Evidence (Before & After)

  • Before: packages/desktop-shell; references across 41 files.
  • After: packages/desktop; git grep desktop-shell returns only deliberate hits — the isolation-guard tripwire, the two ci.yml comments that name both sides of the rename, docs/design/9152-architecture-invariant-classification.md (names both spellings and is accurate), the date-prefixed docs/design/2026-07-31-desktop-web-shell-release.md (historical record, deliberately not rewritten), and the new test that pins the tripwire.
  • Green locally: check:desktop-isolation ✅; desktop crate cargo test 34/34 ✅; test-release.js ✅; CLI workspace suites 377/377 ✅; qwen-autofix-workflow.test.js 325 passed / 13 skipped ✅; prettier/eslint clean on touched files. (desktop-smoke-teardown.test.js has 2 SIGTERM timing tests that fail identically on unmodified main on this machine — pre-existing flake, not from this change.)

Tested on

OS Status
macOS (arm64) ✅ all suites above
Linux/Windows crate compile ⚠️ delegated to the Desktop Shell CI matrix on this PR

Risk & Scope

  • Main risk: branches cut before this merge still carry packages/desktop-shell/, and the ci.yml changed-files filter no longer matches that path — so desktop_shell skips those heads and reports green without compiling them. This is not the Cargo.toml existence guard; that one covers the other side (a head the filter matched because ci.yml itself changed, with no crate at the new path), and the job comment now says so explicitly.
  • That skip is also not loud, which the first version of this description got wrong: a 100%-similarity directory rename merges cleanly with an edit to the old path, so such a branch reports no conflict. Those branches need a rebase to be gated again.
  • Concrete case: fix(standalone): pin @lydell/node-pty-linux-arm64 and fail release on missing prebuilds #12649 is open now and edits packages/desktop-shell/scripts/prepare-runtime.js and packages/desktop-shell/scripts/test-release.js — the exact two files the skipped node scripts/test-release.js step exercises. It should be rebased onto this rename before it merges.
  • Widening the filter to packages/desktop(-shell)?/ was considered and rejected for this PR. On its own it is a no-op: a pre-rename head then matches the filter, and the guard sets changed=false anyway because packages/desktop/src-tauri/Cargo.toml is absent. Making it real means resolving a crate_dir in the filter step and plumbing it into the guard, the rust-cache workspaces: and both working-directory: values — a transition-window redesign of the job, out of scope for a rename.
  • What this PR does instead: scripts/tests/desktop-isolation.test.js pins all five ci.yml crate-path sites to one directory and asserts that directory's src-tauri/Cargo.toml exists, and pins nativePrefixes (superset-shaped, so the packages/desktop-shell tripwire stays legal) against the root workspace negations. Verified by mutation: reverting the filter alternative or either working-directory, dropping 'packages/desktop' from nativePrefixes, or dropping !packages/desktop from package.json each turns it red.
  • Open PR fix(ci): harden the already-published desktop probe #12184 edits desktop-release.yml's probe block (different lines than the path edits here); a rebase should be mechanical.
  • Not validated: a real desktop release from the renamed path — the next desktop-v* tag exercises it; the workflow edits are path substitutions only.
  • Out of scope: the capability classification discussion in Deprecate the Electron desktop app and rename desktop-shell to desktop #8596 stays open there.

Linked Issues

Refs #8596

中文说明

本 PR 做了什么

把 packages/desktop-shell 改名为 packages/desktop,并更新所有承重引用:npm/pnpm 的 workspace 排除项、ci.yml 的 crate 过滤器、desktop-release.yml、桌面隔离守卫、eslint/prettier 忽略配置、scripts 与 CLI 的测试夹具、brand-builder 技能,以及活跃文档(docs/developers/architecture.md、.qwen/skills/)。

crate 名(qwen-code-desktop)、productName("Qwen Code Desktop")、bundle identifier、updater feed、desktop-v* tag 体系、legacy electron-bridge 产物名全部不变——没有任何用户可见的东西移动。

为什么现在做

#8596 退役了 Electron 应用;#9085 删除了旧的 packages/desktop,OpenWork 下游也已 fork。desktop-shell 这个名字是过渡期最后的残留——短名字已经空出来,而一直留着后缀会让每个读者都多想一次"这是哪个 desktop"。切出本分支时没有任何 open PR 触碰 packages/desktop-shell,正是安静的窗口期。#12649 之后开出来了,改了两个旧路径文件——见「风险与范围」。

验证

  • check:desktop-isolation ✅(现在同时守卫新旧两个路径名);桌面条目 cargo test 34/34 ✅;test-release.js ✅;CLI workspace 套件 377/377 ✅;qwen-autofix-workflow.test.js 325 通过 / 13 跳过 ✅;改动文件 prettier/eslint 干净。
  • desktop-smoke-teardown.test.js 有 2 个 SIGTERM 时序用例在未改动的 main 上同样失败——预存 flake,与本改动无关。

风险与范围

  • 主要风险:合并前切出的分支仍带 packages/desktop-shell/,而 ci.yml 的变更文件过滤器已不再匹配该路径——所以 desktop_shell 会跳过这些 head,并在什么都没编译的情况下报绿。这不是 Cargo.toml 存在性守卫管的:守卫覆盖的是另一侧(过滤器因 ci.yml 自身变更而命中、但新路径下没有 crate 的 head),任务注释现已明确写出这一点。
  • 这个跳过也不「显性」——本描述的第一版在这里写错了:100% 相似度的目录改名与对旧路径的编辑能干净合并,这类分支不会报冲突。它们需要 rebase 才能重新被门禁覆盖。
  • 具体案例:fix(standalone): pin @lydell/node-pty-linux-arm64 and fail release on missing prebuilds #12649 现在是 open 的,改了 packages/desktop-shell/scripts/prepare-runtime.js 和 packages/desktop-shell/scripts/test-release.js——正是被跳过的 node scripts/test-release.js 所检验的那两个文件。它应在合并前 rebase 到本次改名之上。
  • 曾考虑把过滤器放宽为 packages/desktop(-shell)?/,本 PR 不采纳:单独放宽是空操作(改名前的 head 命中过滤器后,守卫仍会因 packages/desktop/src-tauri/Cargo.toml 不存在而置 changed=false)。要真正生效必须在 filter 步骤解析出 crate_dir,并把它接到守卫、rust-cache 的 workspaces: 和两个 working-directory: 上——那是对该任务的过渡期重构,超出了一个改名 PR 的范围。
  • 本 PR 改为:新增 scripts/tests/desktop-isolation.test.js,把 ci.yml 的五处 crate 路径钉到同一个目录并断言其 src-tauri/Cargo.toml 存在;同时以超集形态(保留 packages/desktop-shell 绊线的合法性)把 nativePrefixes 与根 workspace 的否定项对齐。已做变异验证:把过滤器分支或任一 working-directory 改回旧名、从 nativePrefixes 删掉 'packages/desktop'、或从 package.json 删掉 !packages/desktop,都会让它变红。
  • Open PR fix(ci): harden the already-published desktop probe #12184 改了 desktop-release.yml 的探测段(与本 PR 的路径编辑不同行),rebase 应是机械操作。
  • 未验证:从改名后的路径跑一次真实桌面端发布——下一个 desktop-v* tag 会覆盖;workflow 改动仅为路径替换。
  • 范围外:Deprecate the Electron desktop app and rename desktop-shell to desktop #8596 中的能力分类讨论继续留在该 issue。

The Electron-era packages/desktop was removed in #9085 and the OpenWork
downstream has forked, so the short name is free and the shell suffix is
the only thing left of the transition. Rename the package directory and
every load-bearing reference: workspace negations (npm + pnpm), the ci.yml
crate filter, desktop-release.yml, the isolation guard, lint/ignore configs,
scripts tests, CLI workspace-fixture tests, and living docs.

User-facing identity is untouched: the crate stays qwen-code-desktop,
productName stays "Qwen Code Desktop", the bundle identifier, updater
feed, release tag scheme, and the legacy electron-bridge asset names are
all unchanged. check-desktop-isolation now guards both path names so the
old one cannot re-enter a workspace set. Dated design docs under
docs/design/ keep their historical paths deliberately.

Refs #8596
yiliang114 and others added 4 commits September 25, 2026 00:16
The web-shell-browser-notification-details pair is a living doc without a
date prefix, so it falls under the PR's update rule rather than the
historical-record exception.
Three prose sites and one CI comment still described the pre-rename world,
or contradicted themselves once `packages/desktop` named both the removed
Electron app and the living Tauri shell.

- ci.yml `desktop_shell`: the comment this branch added credited the
  Cargo.toml guard with keeping "branches from either side of the rename"
  green. It does not. A pre-rename head's files sit under
  `packages/desktop-shell`, which the changed-files filter no longer
  matches, so the job skips before the guard ever runs. Say that, and say
  what the guard does cover (a head the filter matched because ci.yml
  itself changed, with no crate at the new path).
- docs/design/web-shell-user-message-links.md: "desktop-shell routing" /
  "desktop-shell clicks" -> "desktop-host", the wording this branch already
  chose in LinkifiedText.tsx for the same rule.
- docs/design/telemetry-runtime-client-attribution-design.md: repoint the
  `runtime.rs` citation. It backs the live `QWEN_CODE_DESKTOP=1` claim, and
  the other document of record for that invariant -- the comment in
  acp-channel-fallback.ts -- was already repointed by this branch, so the
  two disagreed. Only the path token changes; the doc's dated findings are
  untouched.
- brand-create.mjs / SKILL.md / src-tauri/src/main.rs: name the historical
  referent as historical (the Electron `packages/desktop` removed in PR
  9085) instead of letting it read as a self-reference. In main.rs the
  citation `packages/desktop/packages/shared/src/config/storage.ts` now
  looked like a subpath of the file's own package. Rewritten, not deleted:
  the `QWEN_DEFAULT_WORKSPACE_DIR` clause next to it is the only in-code
  documentation of that override and still resolves.

Deliberately not swept: `scripts/check-desktop-isolation.js`'s
`packages/desktop-shell` tripwire, ci.yml's #8132 history comment,
`docs/design/9152-architecture-invariant-classification.md` (names both
spellings and is accurate), and the date-prefixed
`docs/design/2026-07-31-desktop-web-shell-release.md`.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmug1iw422v
…overage

Both invariants fail green today, and this rename is the second time the
crate directory has moved.

`scripts/check-desktop-isolation.js` gained `'packages/desktop'` in
`nativePrefixes` -- the only production-logic line in this branch -- and
nothing read it. Deleting that line leaves the guard's output and exit code
byte-identical, because `isNativeLocation('packages/desktop')` then matches
no remaining prefix; a later PR that drops `!packages/desktop` from the root
workspace list would re-admit the package with CI green.

The `desktop_shell` job names the crate directory in five places (the
changed-files filter, the Cargo.toml guard and its `::notice::` text, the
rust-cache `workspaces:`, and two `working-directory:` values). Nothing
asserted they agree with each other or with a directory that exists, so the
next drift reports a skipped job as a passed one.

The new suite parses both instead of re-running them, and is superset-shaped
on purpose: `nativePrefixes` carries a fourth entry (the
`packages/desktop-shell` tripwire) that nothing negates, and an exact-match
assertion would invite deleting it. The npm/pnpm mirror of the negation list
is already pinned by package-scripts.test.js, so this reads package.json only.

Verified by mutation, each applied alone and then restored: reverting the
filter alternative or either `working-directory` to `packages/desktop-shell`,
dropping `'packages/desktop'` from `nativePrefixes`, and dropping
`!packages/desktop` from package.json all turn this suite red. Today no other
test does.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmug1iw422v
@wenshao

wenshao commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

Local real-environment verification — PR #12653 @ b053c21

Verdict: ready to merge — no blockers. The rename is complete, and a real macOS desktop app builds and boots from packages/desktop. There is one merge-order item for #12649 (see Finding 1), plus a note on the guard (Finding 2) that doesn't block.

Environment: macOS 26.6 arm64, Node 22.23.2 (from .nvmrc), cargo 1.97.1, pnpm 11.24.0. The PR head was also test-merged against origin/main d124dd5, which is 12 commits ahead of the branch point and merges cleanly.

Desktop app built from packages/desktop, running on macOS

Qwen Code Desktop.app, built from the renamed path with npm run build:runtime and tauri build --bundles app. It was launched with an isolated HOME: the bundled qwen serve starts and the Web Shell loads in the native window. CI's Desktop Shell matrix covers only ubuntu and windows, so this is the macOS data point.

Verification matrix

What was run

Check Result
git grep desktop-shell on the test-merge tree (PR + current main) 10 hits, all deliberate: 2 ci.yml comments, the dated design doc (2 hits), 9152-…classification.md, the guard's tripwire, and the new test (4 hits). The 12 main commits since the branch point added no new old-path references.
pnpm install --frozen-lockfile at the root OK. packages/desktop stays outside the workspace set.
cargo test in packages/desktop on macOS 34/34
npm run build:runtime + npx tauri build --bundles app Qwen Code Desktop.app, 337 MB, bundle id com.alibaba.qwen-code unchanged. The only error was the expected updater-signing message (no TAURI_SIGNING_PRIVATE_KEY locally).
npm run smoke:packaged -- <.app>/Contents/MacOS/qwen-code-desktop Runtime ready in 5.7 s
node scripts/test-release.js passed
npm run check:desktop-isolation passed
scripts suites: the new desktop-isolation.test.js, plus workspaces, package-scripts, brand-create-safety, desktop-oss-workflow, security-checks-audit-retry, qwen-autofix-workflow 7 files, 440 passed / 1 skipped
CLI suites: review/lib/{workspaces,workspace-scope,diff-plan}, review/{build-test,test-efficacy}, config/acp-channel-fallback (run from packages/cli) 6 files, 383/383
Every packages/desktop… path in desktop-release.yml All exist in the renamed tree. The diff is path substitutions only.

Finding 1 — #12649's CI will skip the crate once this lands (confirms the PR's Risk section, measured)

I extracted the Detect desktop changes step from ci.yml verbatim, using a YAML parse. I then ran it against the live GitHub PR-files API, with each PR's head as the working directory:

Head Filter from Output
#12653 this PR changed=true
#12649 (6f89c26, edits packages/desktop-shell/scripts/{prepare-runtime,test-release}.js) main today changed=true
#12649 this PR (i.e. after merge) changed=false: the job skips and reports green

The merged result itself is correct. git merge-tree of (main + #12653) with #12649 is clean and leaves 0 files under packages/desktop-shell/. Rename detection carries #12649's edits into packages/desktop/scripts/: prepare-runtime.js is byte-identical to #12649's version, and test-release.js differs only by this PR's one-line path change. Only #12649's own PR CI would be blind.

Suggested action: after this merges, #12649 should git merge origin/main (no rebase needed) before it is approved. Its PR-files list then shows packages/desktop/… and the Desktop job runs again. Alternatively, land #12649 first. Either order produces a correct tree.

Finding 2 (non-blocking, pre-existing) — the guard's npm query half is blind on the pnpm tree, and the new test is what covers the gap

I ran a mutation matrix. Each mutant was applied, confirmed with git diff --shortstat, and then restored:

Mutant new desktop-isolation.test.js check:desktop-isolation
M1 drop 'packages/desktop' from nativePrefixes ❌ 2 failed ✅ pass (blind)
M2 drop "!packages/desktop" from package.json ❌ 1 failed ✅ pass (blind)
M3 filter alternative → packages/desktop-shell/ ❌ 1 failed n/a (out of scope)
M4 cargo working-directory → old path ❌ 1 failed n/a
M5 rust-cache workspaces → old path ❌ 1 failed n/a
M6 Cargo.toml guard → old path ❌ 1 failed n/a
M7 test-release working-directory → old path ❌ 1 failed n/a

All 7 mutants are killed by the new test, which matches the PR's mutation claims. M2 is the interesting one. CI runs check:desktop-isolation after corepack pnpm install, and on a pnpm-laid-out node_modules, npm query .workspace returns only 7 packages (acp-bridge, channels/base, cli, core, sdk-typescript, web-shell, web-templates). So a packages/desktop that re-enters the npm workspaces list never shows up there.

The guard still has teeth through its lockfile-importer half. As a positive control, I dropped the negation from both package.json and pnpm-workspace.yaml and ran pnpm install --lockfile-only. The guard then fails with Root pnpm-lock.yaml should not contain native package importers: packages/desktop. So "guards the new path" holds, via the lockfile.

The npm-query half going inert predates this PR and comes from the pnpm migration. This PR doesn't need to fix it, but it is worth a follow-up issue.

Not verified

  • A signed or notarized release, and the updater feed, from the renamed path. That needs release secrets, and the next desktop-v* tag will exercise it.
  • Windows and Linux crate builds locally. The PR's green Desktop Shell (windows-2022 / ubuntu-22.04) jobs cover those.
中文说明

本地真实环境验证 — PR #12653 @ b053c21

结论:可以合入,无阻断项。 改名完整,从 packages/desktop 能在 macOS 上构建出真实桌面应用并正常启动。合并顺序上有一件事要处理,涉及 #12649(见发现 1);另有一条关于守卫的说明,不阻断(发现 2)。

环境:macOS 26.6 arm64,Node 22.23.2(按 .nvmrc),cargo 1.97.1,pnpm 11.24.0。另把 PR head 与当前 origin/main d124dd5 做了试合并;main 比分叉点新 12 个提交,合并干净。

截图 1:用改名后的路径执行 npm run build:runtime + tauri build --bundles app,产出 Qwen Code Desktop.app,用隔离的 HOME 启动:内置 qwen serve 起来了,Web Shell 在原生窗口中加载成功。CI 的 Desktop Shell 矩阵只覆盖 ubuntu 和 windows,这是 macOS 这一侧的数据。截图 2 是验证矩阵汇总。

执行项

检查 结果
在试合并树(PR + 当前 main)上 git grep desktop-shell 10 处命中,全部是有意保留:ci.yml 注释 2 处、带日期的设计文档(2 处)、9152-…classification.md、守卫里的 tripwire、新测试(4 处)。分叉点之后 main 新增的 12 个提交没有带进新的旧路径引用
根目录 pnpm install --frozen-lockfile 通过,packages/desktop 不在 workspace 集合内
macOS 上在 packages/desktop 跑 cargo test 34/34
npm run build:runtime + npx tauri build --bundles app Qwen Code Desktop.app,337 MB,bundle id com.alibaba.qwen-code 未变;唯一的报错是预期内的 updater 签名提示(本地没有 TAURI_SIGNING_PRIVATE_KEY)
npm run smoke:packaged 5.7 s runtime ready
node scripts/test-release.js 通过
npm run check:desktop-isolation 通过
scripts 套件:新增的 desktop-isolation.test.js,外加 workspaces、package-scripts、brand-create-safety、desktop-oss-workflow、security-checks-audit-retry、qwen-autofix-workflow 7 个文件,440 通过 / 1 跳过
CLI 套件(在 packages/cli 目录下跑) 6 个文件,383/383
desktop-release.yml 里引用的每个 packages/desktop… 路径 在改名后的树里全部存在,diff 只是路径替换

发现 1 — 本 PR 合入后,#12649 的 CI 会跳过 crate 编译(PR 的 Risk 一节所述,已实测确认)

用 YAML 解析把 ci.yml 的 Detect desktop changes 步骤逐字取出,以各 PR 的 head 为工作目录,对线上 GitHub PR-files API 实跑:本 PR 为 changed=true;#12649 用 main 当前的过滤器为 changed=true;#12649 换成本 PR 的过滤器(即合入后)为 changed=false,job 跳过并报绿。

合并结果本身是对的:git merge-tree(main + #12653)⊕ #12649 合并干净,packages/desktop-shell/ 下 0 个文件。改名检测把 #12649 的改动带进了 packages/desktop/scripts/:prepare-runtime.js 与 #12649 的版本逐字节相同,test-release.js 只差本 PR 那一行路径改动。只是 #12649 自己的 PR CI 看不见这些改动。

建议: 本 PR 合入后,#12649 先 git merge origin/main(不需要 rebase)再批准。这样它的 PR-files 列表会变成 packages/desktop/…,Desktop job 重新生效。也可以让 #12649 先合入。两种顺序得到的树都正确。

发现 2(不阻断,既有问题)— 守卫的 npm query 那一半在 pnpm 树上失效,靠新测试补位

变异矩阵(每个变异都先用 git diff --shortstat 确认已生效,再还原):M1–M7 七个变异全部被新测试打红,与 PR 的变异声明一致;守卫对 M1/M2 都放行,看不出问题。M2 的原因是:CI 在 corepack pnpm install 之后才跑 check:desktop-isolation,而在 pnpm 布局的 node_modules 上,npm query .workspace 只返回 7 个包,所以 packages/desktop 重新进入 npm workspaces 时不会在这里出现。

守卫的lockfile importer 那一半依然有效。阳性对照:同时去掉 package.json 和 pnpm-workspace.yaml 里的排除项,再跑 pnpm install --lockfile-only,守卫报 Root pnpm-lock.yaml should not contain native package importers: packages/desktop 并失败。所以「新路径受守卫保护」这一说法成立,靠的是 lockfile 那一半。

npm-query 那一半失效早于本 PR,来自 pnpm 迁移。本 PR 不需要修,但值得开一个后续 issue。

未验证

  • 从改名后路径发布签名/公证版本,以及 updater feed:需要发布密钥,下一个 desktop-v* tag 会覆盖到。
  • 本地没有编译 Windows/Linux 的 crate:由 PR 上已通过的 Desktop Shell (windows-2022 / ubuntu-22.04) 覆盖。

yiliang114 and others added 2 commits September 25, 2026 12:39
Four review findings on scripts/tests/desktop-isolation.test.js, each
verified by mutating the thing it claims to pin, before and after.

- The comment above the local `isNativeLocation` copy claimed a change to
  the script's rule "has to be made here too". Nothing reads the rule back
  from the producer -- `nativePrefixesFromSource` parses the array literal
  only -- and narrowing the script's rule to prefix equality leaves the
  suite green. Describe the copy instead of claiming coupling that does not
  exist.
- `still carries the Cargo.toml existence guard` matched only the guard's
  condition text. Flip the body's `changed=false` to `changed=true`, or move
  it after `fi`, and the suite stayed green at 5/5 while the job runs every
  gated step against a crate that is not there. Assert the assignment sits
  inside the guard's own `if ... fi` body.
- Both on-disk checks keyed on the bare directory, so git-ignored residue
  under `packages/desktop-shell` (`node_modules`, which survives a branch
  switch with an empty `git status`) reddened two tests on a tree with no
  defect and blamed the root workspace set. Key on `package.json`, which is
  what `packages/*` requires to make a directory a workspace member; a real
  re-entry still reddens both.
- The `startsWith(filterAlternative)` assertion compared a path built from
  `crateDir` -- `filterAlternative` with one trailing slash stripped -- back
  against `filterAlternative`, so it could not fail for any input. Dropping
  the trailing slash from the changed-files filter in ci.yml left it green.
  Replace it with the property that makes the alternative a path prefix
  rather than a bare string prefix.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmugedurp3j
Brings the branch up to date with main (78faaec), including #12649,
which edited packages/desktop-shell/scripts/prepare-runtime.js and
test-release.js at the pre-rename path.

Rename detection carried both edits into the new packages/desktop path:
prepare-runtime.js takes main's blob verbatim, and test-release.js keeps
main's degrade-arm comment rewrite at line 771 together with this PR's
path change at line 530. package.json keeps both sides: main's
@lydell/node-pty-linux-arm64 pin and 0.24.5 version bump, plus this PR's
!packages/desktop workspace negation. packages/desktop-shell is absent
from the merged tree.

Co-authored-by: Qwen-Coder <[email protected]>

@yiliang114 yiliang114 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Review at 65afaeb (author is myself — this COMMENT is the record; a non-author maintainer vote is needed to clear REVIEW_REQUIRED).

No blocking findings on a rename this size (121 files):

  1. Completeness verified at the tree level: zero desktop-shell paths remain in the head's git tree (10,293 entries walked), and every desktop-shell hit in the diff is either a removed line or a deliberate historical note in comments. New references consistently use packages/desktop, including the root package.json workspace exclusion.
  2. CI wiring updated coherently: the path filter, the Cargo.toml presence guard, rust-cache workspaces, and both working-directory entries all moved together; the Desktop Shell lanes (ubuntu-22.04 + windows-2022) are green on this head, which is the only lane that actually compiles the crate.
  3. The one real trade-off is disclosed in the workflow comment itself: a pre-rename branch (files still under packages/desktop-shell) no longer matches the filter and would report green having compiled nothing — the comment states such branches need a rebase to be gated again. That's the honest answer for a rename and acceptable: those branches must rebase before merge anyway.
  4. The review-lib path updates (workspaces.ts, workspace-scope, build-test, test-efficacy) are mechanical renames with their tests updated to match; the desktop-brand-builder skill's relative paths follow the move.

CI green except review-pr (queued, bot infrastructure) and web-shell E2E Smoke (queued). All 8 threads resolved.

@chiga0 chiga0 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No blocking findings.
Approval blockers: none.

Scope: 121 files, 402 additions / 204 deletions. ~96 pure renames (packages/desktop-shell/* → packages/desktop/*) plus targeted path-string substitutions in CI workflows, root workspace manifests, tool configs, docs, test fixtures, and two CLI workspaces source files (comment-only updates). One production-logic change: check-desktop-isolation.js gains 'packages/desktop' in nativePrefixes. New test: scripts/tests/desktop-isolation.test.js.

Checked:

  • Workspace isolation coherence (class 1 — writer/reader contract): package.json workspace negation (!packages/desktop), pnpm-workspace.yaml exclusion, check-desktop-isolation.js nativePrefixes, and pnpm-worktree-smoke.yml path filters all updated consistently. packages/desktop-shell kept in nativePrefixes as a re-entry tripwire — deliberate and documented.

  • CI wiring (class 1): The desktop_shell job's five crate-path references (changed-files filter alternative, Cargo.toml existence guard, guard ::notice:: text, rust-cache workspaces:, both working-directory: values) all move together to packages/desktop. desktop-isolation.test.js pins all five sites to agree, existence-checks Cargo.toml, and verifies the filter alternative carries a trailing / (preventing prefix collision with any future sibling named packages/desktop-extra or similar).

  • Pre-rename branch skip risk: Explicitly documented in both the PR description and the ci.yml job comment. A branch still at packages/desktop-shell/ no longer matches the filter and reports green having compiled nothing. Not a defect introduced here — it is the acknowledged trade-off of a directory rename. The Cargo.toml existence guard continues to cover the complementary case (filter matched because ci.yml itself changed, crate absent at the new path).

  • npm package name (@qwen-code/desktop-shell → @qwen-code/desktop): private: true throughout — no published consumer can break.

  • Callers of renamed path strings (class 2): acp-channel-fallback.ts, LinkifiedText.tsx, web-shell/client/index.html, .qwen/skills references, docs all updated. LinkifiedText.tsx:9 deliberately uses desktop-host routing (not desktop routing); per the author's thread reply, this is the terminology adopted in the living docs.

  • Deliberate desktop-shell survivors (class 10 — stated intent): the isolation-guard tripwire in check-desktop-isolation.js, two ci.yml comment lines naming both sides of the rename, docs/design/9152-architecture-invariant-classification.md (names both spellings accurately), and the date-prefixed docs/design/2026-07-31-desktop-web-shell-release.md (historical record). All are correct per the PR description.

  • desktop-isolation.test.js test validity (class 5): The guard-body assertion now pins changed=false inside the if..then..fi block (not just the condition text), fixing R2-2. The pre-rename tripwire checks packages/desktop-shell/package.json existence rather than the bare directory, fixing R2-3 (build residue under the old path would no longer produce a false positive). The prior tautological startsWith assertion (R2-4) is absent from the current head.

  • Binary renames (icons, images): All shown as similarity-100 renames in the diff — no content changes, only path moves.

Not covered: local execution of the vitest suite (no node_modules available); Windows path behaviour; CI matrix runs (delegated to the Desktop Shell CI job on this PR).

Reviewed with AI assistance.

@qqqys qqqys left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Critical-only review at 65afaeb9, base 78faaec8.

Verdict: APPROVE — no Critical, and no blocking issue was ever filed here. For a 121-file rename the thing to verify is not the moved bytes but every reference that has to keep resolving, so that is what I checked: the load-bearing ones all point at the new path, and the two places that still name the old one are deliberate.

The rename is coherent across everything that resolves a path

Both workspace negations moved together — "!packages/desktop" in the root package.json workspaces array and '!packages/desktop' in pnpm-workspace.yaml. That pair matters more than the rest: the release set is derived from the workspace globs, so a negation left behind at the old path would have pulled packages/desktop into RELEASE_WORKSPACES and into a publish step that has no business publishing it. It is also private: true, so the exclusion is doubled rather than resting on one mechanism.

In ci.yml the changed-files filter, the rust-cache workspaces: key and both working-directory: values all read packages/desktop. desktop-release.yml, eslint.config.js and .prettierignore contain zero occurrences of the old name at this head. Of the 121 files, the overwhelming majority are pure renames with no content change; the substantive edits are the reference updates above plus comments.

Both remaining references to the old path are intentional, and I read them rather than counting them

scripts/check-desktop-isolation.js keeps packages/desktop-shell in nativePrefixes alongside the new packages/desktop, with the reason stated: nothing should be created under the pre-rename location again, and it must never enter a workspace set. Dropping it would have removed the tripwire exactly when a stale branch is most likely to recreate the directory.

The two occurrences in ci.yml are inside the comment that documents the rename's own hazard, and the job carries two guards plus one disclosed gap:

  • The changed-files filter includes .previous_filename as well as .filename, with the comment naming why — renaming a file out of the crate changes it, and only the old path says so. Without that, moving a source file out of packages/desktop/ would not trigger the crate compile.
  • The Cargo.toml existence guard sets changed=false with a ::notice:: when the filter matched but packages/desktop/src-tauri/Cargo.toml is absent, so a pre-rename head that matched only because ci.yml itself changed does not fail with a missing working directory blamed on the PR.
  • The gap is disclosed rather than papered over: a pre-rename head's files sit under the old path, the filter no longer matches, the job skips and reports green having compiled nothing, and because a 100%-similarity directory rename merges cleanly with an edit to the old path, such a branch reports no conflict either. Those branches need a rebase. The description also records that widening the filter to packages/desktop(-shell)?/ was considered and rejected, with the reasoning — on its own it is a no-op, since the guard would set changed=false anyway, and making it real means resolving a crate directory and plumbing it into four sites, which is a transition-window redesign rather than a rename.

scripts/tests/desktop-isolation.test.js is what keeps that coherent: it pins all five ci.yml crate-path sites to one directory, asserts that directory's src-tauri/Cargo.toml exists, and pins nativePrefixes superset-shaped against the root workspace negations so the old-path tripwire stays legal. The description reports it was verified by mutation — reverting the filter alternative or either working-directory, dropping packages/desktop from nativePrefixes, or dropping !packages/desktop from package.json each turns it red. That is the right shape of test for a rename, where the failure mode is a reference nobody greps for.

The non-mechanical edits are corrections the rename forced

packages/cli/src/commands/review/lib/workspaces.ts changes nine lines and every one is inside a comment: the negation-ownership examples that used packages/desktop-shell as their illustration now use packages/desktop, with the surrounding reasoning about fallback ownership preserved verbatim. No logic moves.

packages/desktop/src-tauri/src/main.rs changes two comment lines, and it is the most interesting edit in the diff. The old comment cited packages/desktop/packages/shared/src/config/storage.ts — a path belonging to the Electron package #9085 removed, which was already dead. Left alone, this rename would have made that dead citation look live again, since packages/desktop now exists and means something different. It is rewritten to name the removed Electron package and the PR that removed it. That is the class of error a rename produces and a grep for the old name cannot find.

One item in Risk & Scope is now stale, in the harmless direction

The description says #12649 is open and edits packages/desktop-shell/scripts/prepare-runtime.js and test-release.js, and should be rebased onto this rename before merging. #12649 merged to main since this branch last took main, so that ordering advice no longer applies. The outcome is still the one the description relies on elsewhere: a 100%-similarity rename merges cleanly with edits made at the old path, so #12649's comment changes follow the files to their new location rather than being lost, and GitHub reports this PR MERGEABLE against a main that contains them. Worth a line in the description so the next reader does not act on advice that has already been overtaken, and worth knowing that the two files #12649 touched are exactly the ones the skipped node scripts/test-release.js step exercises — which is the concrete form of the rebase gap documented above.

CI

28 checks pass and 26 are skipped at this head, with web-shell E2E Smoke and review-pr pending and nothing failing. The lanes that would catch a missed reference are green: both Desktop Shell lanes, which compile the crate at its new path, all three Install lanes, which would fail on an incoherent workspace set, Test (ubuntu-latest, Node 22.x), Lint & Static and Integration Tests (no-AK, No Sandbox). I did not wait on the two pending lanes. No review thread is unresolved.

The one thing no lane can verify here is the actual desktop release from the renamed path — the workflow edits are path substitutions and the next desktop-v* tag is what exercises them, which the description states plainly rather than claiming coverage it does not have.

@yiliang114
yiliang114 added this pull request to the merge queue Sep 25, 2026
Merged via the queue into main with commit 73aa65a Sep 25, 2026
93 of 94 checks passed
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.

4 participants