feat(desktop): remove the Electron package after OpenWork fork; keep the Tauri upgrade bridge - #9085
Conversation
🖼️ web-shell visual previewRendered against a mock daemon (no real backend): the PR base vs this PR head Screenshots · before / afterFull-resolution recordings (.webm) are attached to the workflow run. — Qwen Code · web-shell visuals |
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
|
wait to review |
Code reviewIndependent baseline first: for "delete the Electron tree after the downstream forked, keep the upgrade bridge", I'd do exactly what this PR does — Verification was done statically (this is an unattended run — no PR code executed), against the current
No critical findings, no convention violations. Files changed — surviving surface (34 of 1,723 shown)
Testing evidence (the PR's own CI, read via API — no PR code executed here)All checks on the reviewed commit are settled — none pending, none failed. The load-bearing ones:
中文说明先给独立基线:对"下游 fork 后删除 Electron 树、保留升级桥"这个任务,我会做的正是这个 PR 的形状——删除 验证以静态方式进行(无人值守运行,不执行 PR 代码),基于当前 main 树与 diff 交叉核对——由于 main 已超过本 PR 的 base,这是保守口径:
无关键问题,无规范违反。测试证据:所审提交的全部 CI 已出结果——无 pending、无失败;关键项为单位套件(绿)与两个 Desktop Shell 编译单元(绿,证明删树后 Tauri 壳仍可构建);macOS/Windows 单元与 CLI 集成单元由仓库分类器跳过(纯配置/文档/删除变更)。本 PR 无用户可见行为变化,无需真机操作;随本次分诊触发的沙箱验证任务正在运行,将单独发布报告。 — Qwen Code · qwen3.8-max Reviewed at |
|
Confidence: 4/5 — clean across every stage; the one point off is the named non-blocking nit (the 9152 design doc's isolation-check line goes mildly stale after merge), not any doubt about the change itself. Stepping back: my independent proposal for this task was exactly the shape this PR has — delete the tree, retire the machinery that existed only for it, sweep every reference, prove the bridge didn't move — and the adversarial pass (grepping current main against the diff rather than trusting the head tree) didn't surface a single orphaned functional reference. What convinced me is what the diff doesn't contain: zero added lines inside the deleted tree, the four bridge paths absent from the 1,723-file list entirely, and the live-host feed contract re-pinned on the surviving CLI installer instead of just being dropped. That's the difference between a deletion and a careful deletion. The 380k-line number looks dramatic but reads small: one-directional churn, 136 added lines, all of them reference updates. CI is fully settled at the reviewed commit with the load-bearing proof green (both Approving with two items on the record for the follow-up rename PR: (1) rework the isolation-check line in 中文说明置信度:4/5 —— 各阶段全部干净;扣掉的一分来自那条已点名的非阻塞问题(9152 设计文档中隔离检查的表述在合并后会轻微过时),而不是对变更本身有任何怀疑。 退一步看:我为这个任务构想的独立方案与 PR 的形状完全一致——删树、退役只为它存在的设施、清扫全部引用、证明桥未动;而对抗性核查(用当前 main 与 diff 交叉核对,而不是相信 head 树)没有找出任何一条悬空的功能性引用。真正说服我的是 diff 里"没有"什么:删除树内零新增行、四处桥路径完全不在 1,723 个文件之列、live-host 冻结 feed 契约被重新钉在存活的 CLI 安装器上而非一删了之。这是"谨慎的删除"与"删除"的区别。38 万行的数字看着惊人,读起来很小:单向变更、136 行新增、全部是引用更新。所审提交的 CI 已全部出结果,关键证明为绿(两个 Desktop Shell 编译单元在无该树的情况下构建成功;完整单位套件通过)。 批准,同时为后续改名 PR 记录两项:(1)重做 — Qwen Code · qwen3.8-max Reviewed at |
|
Re-run on the rewritten PR — the previous pass reviewed the move/rename iteration; this pass reviews the straight deletion. All three stage comments are rewritten from scratch against the current head. Template ✓ — all sections present, bilingual summary included. Problem. Real and documented, not theoretical: #8596 (follow-up of #8092) settled that the Electron app is deprecated in favor of the Tauri shell, with deletion once the OpenWork downstream is migrated. The PR's premise is that this migration condition is now met because OpenWork forked the Electron code and is self-contained — Direction. Aligned — this executes the deletion half of #8596. One process note, not a blocker: the issue's constraint was "the sync must continue until that downstream is migrated", and the fork-completion call itself isn't spelled out in the issue thread. The author is the maintainer driving that issue, and the PR records the retirement explicitly (OpenWork owns future Electron/live-host releases; nothing further publishes from this repo). The Size. Maintainer-authored (author has admin access) and Approach. Minimal — strictly smaller than the move/rename iteration this replaces. The scope boundaries are drawn correctly: the Electron→Tauri upgrade bridge is kept whole ( Risk. The revert-history screen matched two paths ( Moving on to code review. 🔍 中文说明针对重写后的 PR 重新运行——上一轮审的是"移动+改名"方案,这一轮审的是直接删除。三条阶段评论全部基于当前 head 重写。 模板 ✓ —— 各部分齐全,含中文对照。 问题。 真实且有据,不是理论问题:#8596(#8092 的后续)已确定 Electron 应用弃用、由 Tauri shell 接替,待 OpenWork 下游完成迁移后删除。本 PR 的前提是迁移条件已满足——OpenWork 已 fork Electron 代码并自包含; 方向。 对齐——这是落地 #8596 的删除部分。一点流程备注(非阻塞):issue 的约束是"同步持续到下游迁移完成",而 fork 完成这一判断本身没有写在 issue 讨论里。作者正是主导该 issue 的维护者,PR 中也明确记录了退役安排(OpenWork 拥有后续 Electron/live-host 发布;本仓库不再发布)。 规模。 维护者提交(作者有 admin 权限)且标题为 方案。 最小化——比它所替代的"移动+改名"方案严格更小。边界划得正确:Electron→Tauri 升级桥完整保留( 风险。 回滚历史筛查命中两个路径( 进入代码审查 🔍 — Qwen Code · qwen3.8-max Reviewed at |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
e8aad57 to
034c855
Compare
|
Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration. 中文请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。 |
034c855 to
a5dbf04
Compare
…Tauri upgrade bridge OpenWork (modelstudioai/openwork) has forked the Electron desktop code and is self-contained now, so retire the Electron package and its release/sync machinery from this repo: - Delete packages/desktop (Electron app, live-host app, bun workspace). - Retire scripts/desktop-openwork-sync.ts and the desktop-openwork-sync root script; the OpenWork sync is no longer needed. - Retire .github/workflows/live-host.yml, live-host-release.yml and sync-live-host-to-oss.yml; live-host releases now live in OpenWork. The CLI-side packages/cli/src/serve/live code stays for now (separate cleanup). - Retire scripts/check-voice-guard-sync.js (cli<->desktop parity only) and its CI step. - Clean up remaining references: root package.json workspaces negation and package-lock.json, eslint/prettier/yamllint ignores, architecture docs, web-shell skill descriptions, and review-lib workspace fixtures/comments (renamed to point at packages/desktop-shell, the remaining negation). Deliberately kept: the Electron->Tauri upgrade bridge — desktop-release.yml (incl. the electron_bridge input), create-electron-bridge-manifest.mjs, sync-desktop-to-oss.yml (mirrors Tauri desktop-shell artifacts only) and everything under packages/desktop-shell.
a5dbf04 to
bf88a29
Compare
|
@qwen-code /triage |
|
Sandboxed verification: ❌ not passed — findings reported (agent verdict) - workflow run Ran the PR in an isolated, token-free container: A/B against the base build, mock-free harness assertions, targeted gates. Advisory evidence for human reviewers — not a review, an approval, or a CI check. Scripted assertions: 68 passed · 3 failed · 71 total Flakiness gate: 中文 — 判定:❌ 不通过 · 报告了发现(agent 判定)沙箱验证在隔离、无凭证的容器中执行了该 PR 的代码(与 base 构建 A/B 对照、无 mock harness 断言、定向门禁)。仅作为评审证据,不构成评审、批准或 CI 检查。 脚本断言:68 通过 · 3 失败 · 71 总计 抖动门: Verification reportPR #9085 deep verification —
|
| cell | oracle | base (HEAD^1) |
head (HEAD^2) |
|---|---|---|---|
bare packages/desktop([^/-]|$) outside the tree |
hit count | 62 (control: oracle is sensitive) | 6 — PR claims 0 → FAIL |
broader non--shell packages/desktop refs |
hit count | 122 | 16 in 10 files → FAIL |
desktop-openwork-sync |
hit count | 6 | 0 ✓ |
bump-live-host-version |
hit count | 3 | 0 ✓ |
openwork beyond PR's stated set |
disallowed hits | — | 3 design-doc mentions → FAIL |
live-host survivors |
file allowlist | — | 13 files, all packages/cli/src/serve/** + the frozen-feed script test ✓ |
| deleted artifacts exist | git cat-file -e |
all 9 present ✓ | all 9 gone ✓ |
| bridge byte-identity | git diff over the 4 bridge paths |
— | empty diff ✓ (incl. electron_bridge input present) |
check:desktop-isolation |
exit code | 0 (calibration) | 0 ✓ |
Secondary claim — every surviving production hunk is comment/data-only — held: all six changed runtime TS files (agent.ts, voice-transcriber.ts, workspaces.ts, workspace-scope.ts, toolClassification.ts, integration-tests/tsconfig.json) changed comments only (scripted per-line classification); web-shell localCommands.ts/i18n.tsx lost exactly the removed skill's entries; package.json lost exactly the negation + 2 scripts; the lockfile lost exactly the negation line; ci.yml lost exactly the voice-guard step; .size-baseline lost exactly the three live-host entries.
The mutation matrix (mutations.mjs, witnessed by 02-mutation-matrix.png) proves the updated tests/gates are live and the renamed fixtures still pin production behavior — 11/11:
| mutation | expected | observed |
|---|---|---|
M1: re-add 6384 live-host.yml to .size-baseline |
caught by workflow-size.test.js ("records no file that no longer exists") |
caught, exit 1 ✓ |
M2: insert live-host: into desktop-release.yml |
caught by the new "free of Live Host jobs" test | caught, exit 1 ✓ |
M3: break the negation fallback in workspaces.ts (owner = null) |
caught by the renamed fixture suite | caught ("falls back to the surviving OUTER member" red) ✓ |
M4a: fake packages/desktop-shell/fake lockfile entry |
isolation check fails | exit 1, entry named ✓ |
M4b: fake packages/desktop/fake lockfile entry |
now passes (narrowed scope) | exit 0 ✓ (documents the reduction) |
M5: base-arm calibration, release-workflow.test.js at base |
green (the deleted tests were live there) | green ✓ |
| restore checks (6) | git status --porcelain clean |
all clean ✓ |
Gates (gates-check.mjs, witnessed by 03-targeted-gates.png and 04-suite-summaries-raw.png):
| gate | result |
|---|---|
| scripts vitest suite at head | 1597/1597 tests passed; 1 file (install-script.test.js) failed collection via its deliberate zip/unzip CI guard — A/A-proven identical at base (environmental, see Not covered) |
| cli review suite at head | 103/103 files (incl. the 5 fixture-renamed test files) |
| web-shell | tsc --noEmit exit 0; localCommands tests 10/10 |
check:desktop-isolation |
green at head and base |
| eslint on the 17 changed files | clean; liveness control (planted unused var) flagged ✓ |
npm query .workspace |
23 workspaces resolve, zero packages/desktop* members; lockfile workspaces == package.json workspaces |
Findings
F1 (Minor): the "no remaining references" cleanup claim is falsified; one doc now overstates a guard this PR narrowed
Reproduce (committed tree, PR's own step-2 pattern):
git grep -inE 'packages/desktop([^/-]|$)' HEAD -- . ':(exclude)packages/desktop'returns 6 hits at the verified head (PR test plan step 2 says "returns nothing"):
.github/workflows/qwen-triage.yml:3564, 3582— comments beside a still-live bash case armpackages/desktop/*|docs-site/*)at line 3562 (the arm itself misses the PR's pattern because of the/); the arm's fixture pair in.github/scripts/qwen-triage-workflow.test.mjs:3082-3096also modelspackages/desktop/apps/electron..qwen/skills/find-simplifications/SKILL.md:102,references/land.md:124,references/survey.md:234— agent-guidance text.docs/design/9152-architecture-invariant-classification.md:226— the sharpest instance: this doc catalogs mechanically enforced invariants and states the isolation check "fails ifpackages/desktoporpackages/desktop-shellre-enters the root npm workspace set … No gap." This PR narroweddesktopPrefixesto['packages/desktop-shell'](mutation M4b proves apackages/desktoplockfile entry now passes), so the stated guarantee no longer holds as of this merge. The same doc's voice-guard paragraph sayscheck-voice-guard-sync.js"remains as-is" (it does anticipate the deletion two sentences later, but reads false once merged).
The broader sweep (packages/desktop[^-], i.e. including subpath shapes) adds: docs/plans/2026-07-16-default-background-subagents.md:50 (historical plan), .qwen/skills/repo-hygiene/references/scan.md:111 ("the three UI apps (packages/desktop/, …)" plus its stale desktop/apps/electron sub-block), and two dangling provenance pointers in code the PR deliberately leaves untouched — packages/desktop-shell/src-tauri/src/main.rs:35 and packages/web-shell/client/index.html:39. The bridge pointers are the one place cleanup conflicts with the (correct) bridge byte-identity goal; I recommend leaving them to the follow-up rename.
Classification matters: most residues self-heal under the announced desktop-shell → desktop rename (the triage arm becomes correct again, the packages/desktop* wildcard in land.md still covers both trees, the skill lists re-match). The persistent ones are the 9152 guard claim, the repo-hygiene ui-apps list, and the voice-guard phrasing.
Suggested fix (measured): applied in a scratch worktree and re-measured — 4 files, −9/+8: narrow the 9152 guard sentence to packages/desktop-shell, put the voice-guard paragraph in past tense, drop packages/desktop from the two find-simplifications lines, and fix the scan.md opener (its electron sub-block needs the same treatment). Post-fix, the bare pattern drops 6 → 3, and the 3 survivors are all self-healing class (two qwen-triage.yml comments + the land.md wildcard). No test suite reads any of the four edited files (verified: only run-agent.mjs is consumed), so gate impact is nil by construction. The scan.md electron sub-block wording and the qwen-triage arm/fixture pair are left to the author — both are defensible to defer to the rename PR.
Blast radius: none functional — every residue is a comment, doc, or agent-guidance line; no gate is red because of them. The cost is the claim's credibility and one invariant doc stating a guarantee the code no longer provides.
F2 (Nit): the body's evidence numbers are stamped against a superseded head
The body cites head 034c85590f68… and "52/52 files, 1141 passed / 13 skipped" (scripts) / "282/282" (cli review). At the verified head bf88a29 the suites are larger — scripts 63 files / 1597 tests, cli review 103 files — because the merge ref was rebuilt against a newer main. All green; the numbers just no longer correspond. No action beyond re-stamping.
F3 (Nit/observation): isolation-check prefix narrowing is a real, bounded scope reduction
scripts/check-desktop-isolation.js no longer polices packages/desktop (M4a/M4b pin both sides). Any resurrection of packages/desktop would be visible — without the removed !packages/desktop negation it becomes an ordinary packages/* workspace member rather than failing quietly — and the follow-up rename plausibly restores the prefix under the new name. Reported so a reviewer accepts the interim semantics knowingly, and because F1's 9152 item is its documentation casualty.
Not covered
install-script.test.jsarchive tests never ran here — this container shipsunzipbut notzip, and withCI=truethe file's own guard throws at collection instead of silently skipping. A/A control: base arm fails collection byte-identically, so this is the container, not the PR. This reproduces the guard firing, not the archive tests it protects; the repo's real CI lane (withzip) is where they run. One transientvitest-worker onTaskUpdateRPC timeout appeared under load in the same log; it affects no assertion.- Repo-wide
npm run typecheckand non-targeted package suites — the job's pre-existingnpm run build(full TS compile of every workspace at HEAD) is the type gate for the untouched surface; I ran only the affected suites. - The PR's CI-only lanes:
desktop_shellcompile job (proves the bridge builds without the deleted tree), prettier/yamllint/actionlint wrappers, integration tests, Windows/macOS matrix. - Base-arm full scripts suite (calibration was done per-file where it mattered: M5 + the A/A control); base's state is main-CI-known.
- The
qwen-triage.ymlbash case arm dynamically — audited statically; the paths it matches cannot appear post-deletion. - Two pre-existing worktree artifacts of this verify container are not PR content and were excluded (audits read the committed tree via
git grep <rev>): an untracked.qwen/skills/openwork-desktop-sync/SKILL.md(session-skill materialization) and a 1-line uncommitted edit to.qwen/skills/desktop-pet/scripts/gen_spritesheet.py. - The
openwork-desktop-syncskill deletion itself was checked complete: base carried exactly one file (SKILL.md), gone at head.
Methodology
Environment: the CI verify container (node:22-bookworm, Node v22.23.2, CI=true, no zip binary), working tree at refs/pull/9085/merge (depth 2); npm ci + npm run build had completed at HEAD before this round. Harnesses (audit.mjs, mutations.mjs, gates-check.mjs, this report, raw logs per cell/suite) live in tmp/pr9085-verify-20260825-052600/. The A/B used HEAD^1 (local base tip 4a492bc) vs HEAD^2 (bf88a29) via git grep <rev>/git diff on the committed trees; the base arm for live checks ran in a tmp/base-tree worktree whose node_modules was a symlink to the head install — safe here because the base-arm probes (check-desktop-isolation.js, one vitest file) read config/files, not workspace code. Mutations were applied to the head tree one at a time, exercised, restored with git checkout --, and each restore was itself asserted clean. Expected base-arm states were encoded as assertions, so fail counts only unexpected outcomes; the 3 fails map one-to-one to F1. Evidence images were rendered with scripts/verify-capture.mjs.
Flakiness gate log
rounds=5 files=8 skipped=0
file packages/cli/src/commands/review/build-test.test.ts: (cd packages/cli) npx --no-install vitest run ./src/commands/review/build-test.test.ts
file packages/cli/src/commands/review/lib/diff-plan.test.ts: (cd packages/cli) npx --no-install vitest run ./src/commands/review/lib/diff-plan.test.ts
file packages/cli/src/commands/review/lib/workspace-scope.test.ts: (cd packages/cli) npx --no-install vitest run ./src/commands/review/lib/workspace-scope.test.ts
file packages/cli/src/commands/review/lib/workspaces.test.ts: (cd packages/cli) npx --no-install vitest run ./src/commands/review/lib/workspaces.test.ts
file packages/cli/src/commands/review/test-efficacy.test.ts: (cd packages/cli) npx --no-install vitest run ./src/commands/review/test-efficacy.test.ts
file scripts/tests/qwen-autofix-workflow.test.js: (cd .) npx --no-install vitest run --config ./scripts/tests/vitest.config.ts ./scripts/tests/qwen-autofix-workflow.test.js
file scripts/tests/release-workflow.test.js: (cd .) npx --no-install vitest run --config ./scripts/tests/vitest.config.ts ./scripts/tests/release-workflow.test.js
file scripts/tests/workspaces.test.js: (cd .) npx --no-install vitest run --config ./scripts/tests/vitest.config.ts ./scripts/tests/workspaces.test.js
per-file results (P=pass F=fail I=infra-exit, one letter per run):
packages/cli/src/commands/review/build-test.test.ts: PPPPP
packages/cli/src/commands/review/lib/diff-plan.test.ts: PPPPP
packages/cli/src/commands/review/lib/workspace-scope.test.ts: PPPPP
packages/cli/src/commands/review/lib/workspaces.test.ts: PPPPP
packages/cli/src/commands/review/test-efficacy.test.ts: PPPPP
scripts/tests/qwen-autofix-workflow.test.js: FFFFF
scripts/tests/release-workflow.test.js: PPPP
scripts/tests/workspaces.test.js: PPPP
verdict: consistent-fail
summary: 1 of 8 changed test file(s) failed identically in every round — deterministic, so CI owns that signal
--- per-invocation detail (full copy in the artifact) ---
round 1 · packages/cli/src/commands/review/build-test.test.ts: P (exit 0)
round 1 · packages/cli/src/commands/review/lib/diff-plan.test.ts: P (exit 0)
round 1 · packages/cli/src/commands/review/lib/workspace-scope.test.ts: P (exit 0)
round 1 · packages/cli/src/commands/review/lib/workspaces.test.ts: P (exit 0)
round 1 · packages/cli/src/commands/review/test-efficacy.test.ts: P (exit 0)
round 1 · scripts/tests/qwen-autofix-workflow.test.js: F (exit 1)
--- output tail · round 1 · scripts/tests/qwen-autofix-workflow.test.js ---
You appear to have cloned an empty repository.
warning: You appear to have cloned an empty repository.
warning: You appear to have cloned an empty repository.
�[32m✓�[39m scripts/tests/qwen-autofix-workflow.test.js �[2m(�[22m�[2m218 tests�[22m�[2m)�[22m�[33m 73524�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mholds a round while review-pr is in flight on the head (#8888) �[33m 442�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mauto-updates a PR red only from a stale base, gated on green-on-main �[33m 593�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mauto-reruns a check that died on infrastructure, once, guarded by run_attempt �[33m 623�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mbehaviorally replays the stale-duplicate revalidation, including the conflict-only transition �[33m 4159�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mbehaviorally replays the eligibility recheck across lifecycle and label states �[33m 3402�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mreleases the dispatch-pending marker when the recheck discards a target �[33m 1051�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mraises the round cap to TAKEOVER_MAX_ROUNDS while the label is present �[33m 436�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mbehaviorally replays the takeover-command toggle across all four paths �[33m 3725�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mbehaviorally resets round counting at the latest takeover engage ack �[33m 871�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mbehaviorally seeds the round counter from the window anchor and only from it �[33m 1646�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mrecovers transient forced-target reads and reports terminal takeover blocks �[33m 693�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mwires forced admission end to end: reader, classifier, permission gate, reporter �[33m 430�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mposts the non-main base refusal without depending on any other API call �[33m 1915�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mswitches to Critical-only feedback after five change rounds �[33m 381�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mturns a budget breach into a growth-audit round instead of a divergence stop �[33m 2050�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mposts a takeover milestone digest as rounds accumulate, with a residual bucket �[33m 632�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mrejects a round that expands into CI machinery outside the PR footprint �[33m 1227�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22msurfaces deny-by-default footprint expansions, rejecting only when enforcement says so �[33m 436�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mupserts deferred findings into a per-PR issue that survives the merge �[33m 8941�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mbite check: rejects a round whose changed tests pass on the pre-round tree �[33m 2908�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mstops a PR that fails to push for CONSECUTIVE_FAILURE_CAP rounds in a row �[33m 664�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mre-arms a stranded PR from a marker instead of a deleted comment �[33m 585�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22maddress-side stale check mirrors the scan-side re-arm logic under bash �[33m 860�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mbehaviorally posts the re-arm marker only after verifying the PAT identity �[33m 384�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mresolves only the review threads whose findings it implemented �[33m 2181�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22manswers the threads it leaves open, in those threads �[33m 623�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mdoes not flag an API error that appears after a real verdict or a loop guard �[33m 326�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mflags recoverable API renders without a leading status code, and skips non-recoverable ones �[33m 446�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mclassifies permanent API failures terminal and records the cause class �[33m 1175�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m qwen-autofix workflow�[2m > �[22mpreserves an agent-written handoff when the budget kills qwen after it �[33m 653�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m growth-audit hardening: park wake set and verdict pipeline (round 3)�[2m > �[22mskips the scan stale-base update while a conflict handoff pends �[33m 581�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m review verification gate: baseline A/B on deterministic rejection�[2m > �[22mclassifies an unchanged branch by its verdict files (handoff contract) �[33m 657�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m review verification gate: baseline A/B on deterministic rejection�[2m > �[22mrejects a verdict stream whose later document is truncated or shape-filtered �[33m 315�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m run-agent idle watchdog�[2m > �[22mkills a silent agent at the idle window, naming the idle limit �[33m 1251�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m run-agent idle watchdog�[2m > �[22mnever fires while the agent emits protocol events, however slowly �[33m 3262�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m run-agent idle watchdog�[2m > �[22mnever fires while the agent talks on stderr only �[33m 3259�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m run-agent idle watchdog�[2m > �[22mdoes not treat an unterminated stdout byte stream as progress �[33m 805�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m run-agent idle watchdog�[2m > �[22mrequests streamed partial progress so active headless work refreshes the watchdog �[33m 3262�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m stale sandbox container cleanup�[2m > �[22man idle kill removes only the running sandbox its own agent launched �[33m 1253�[2mms�[22m�[39m
�[33m�[2m✓�[22m�[39m stale sandbox container cleanup�[2m > �[22ma budget kill removes only the running sandbox its own agent launched �[33m 1259�[2mms�[22m�[39m
�[31m⎯⎯⎯⎯⎯⎯�[39m�[1m�[41m Unhandled Errors �[49m�[22m�[31m⎯⎯⎯⎯⎯⎯�[39m
�[31m�[1m
Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.�[22m�[39m
�[31m⎯⎯⎯⎯⎯⎯�[39m�[1m�[41m Unhandled Error �[49m�[22m�[31m⎯⎯⎯⎯⎯⎯⎯�[39m
�[31m�[1mError�[22m: [vitest-worker]: Timeout calling "onTaskUpdate"�[39m
�[90m �[2m❯�[22m Object.onTimeoutError node_modules/vitest/dist/chunks/rpc.-pEldfrD.js:�[2m53:10�[22m�[39m
�[90m �[2m❯�[22m Timeout._onTime
...truncated -- full content in the run artifacts.
Evidence images
Harness scripts and raw logs are in the workflow run artifacts (7-day retention).
— Qwen Code · sandboxed verification
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
Local verification report — real environment, base ↔ PR A/BI built the whole thing locally instead of reading the diff: two clean worktrees at the merge-base Verdict: no blocker. Safe to merge. Every item in the Reviewer Test Plan reproduces, the Electron→Tauri bridge is provably untouched at the git-object level, and the one thing that keeps living off the deleted pipeline — the CLI 1. Reviewer Test Plan, item by item
Also identical on both arms: 2. Verification beyond the plana) The one user-visible change. Deleting b) The frozen Live Host feed, exercised for real. This is the part of the PR that keeps depending on a pipeline that no longer exists, so I drove the retained c) Merge-queue safety. The d) One coverage note. The deleted e) PR CI is green here, including 3. Non-blocking findings🟡 N1 — nothing pins the protocol version the frozen feed actually serves. After this PR the repo can never publish a new Live Host build, yet const liveHostTypes = readFileSync('packages/cli/src/serve/live/types.ts', 'utf8');
// The frozen feed serves protocolVersion 6 and this repo can no longer republish it.
expect(liveHostTypes).toContain('LIVE_HOST_PROTOCOL_VERSION = 6');🟡 N2 — Keeping both prefixes costs nothing, and it is the exact guard the follow-up 🔵 N3 — residual references (cosmetic, none functional). The description's own grep returns these 6:
Worth a sweep in this PR or a follow-up; also worth correcting "returns nothing" in the description so the claim matches the tree. 🔵 N4 — one edit outside the stated scope. 4. Not verifiedmacOS/Windows beyond what CI covers; the completeness of the OpenWork fork itself; and long-term retention of the OSS mirror objects (they are live today — HTTP 200 on 中文说明本地验证报告 —— 真实环境、base ↔ PR 双臂对比我没有只读 diff,而是在本地把整套环境跑了起来:在 merge-base 结论:没有阻塞项,可以合并。 评审测试计划的每一条都能复现;Electron→Tauri 升级桥在 git object 级别可证明完全未动;唯一还依赖被删流水线的东西 —— CLI 1. 逐条核对评审测试计划
(截图见英文部分 p1 / p2。) 另外两臂完全一致的还有: 2. 计划之外的补充验证a) 唯一用户可见的变化。 删掉 b) 冻结的 Live Host feed 真跑了一遍。 这是本 PR 中唯一继续依赖「已被删除的流水线」的部分,所以我用保留下来的 c) 合并队列安全性。 d) 一点覆盖率提示。 被删的 e) 本 PR 的 CI 全绿,包含 3. 非阻塞发现🟡 N1 —— 没有任何东西钉住冻结 feed 实际提供的协议版本。 本 PR 之后仓库再也无法发布新的 Live Host 构建,但 const liveHostTypes = readFileSync('packages/cli/src/serve/live/types.ts', 'utf8');
// 冻结 feed 提供的是 protocolVersion 6,本仓库已无法重新发布它。
expect(liveHostTypes).toContain('LIVE_HOST_PROTOCOL_VERSION = 6');🟡 N2 —— 🔵 N3 —— 残留引用(都属于装饰性,无功能影响)。 描述里那条 grep 实际命中 6 处:
可以在本 PR 里顺手清理,也可以另开一个;另外建议把描述里「returns nothing」改成与实际一致的说法。 🔵 N4 —— 一处超出声明范围的改动。 4. 未验证的部分CI 覆盖之外的 macOS/Windows 行为;OpenWork fork 本身的完整性;以及 OSS 镜像对象的长期保留策略(今天是可用的 —— 🤖 Generated with Claude Code — Claude Opus 5 (1M context) |
…-out main removed packages/desktop (QwenLM#9085, OpenWork fork); this branch's provider-state module and desktop onboarding test no longer have their surrounding implementation. The Kimi/Xiaomi auth work for live surfaces remains in cli and vscode-ide-companion.
|
Released in v0.22.2. |
…ell (QwenLM#10164) * feat(desktop-shell): restore the brand builder skill for the Tauri shell The Electron-era desktop-brand-builder skill was removed with packages/desktop in QwenLM#9085, leaving the Tauri shell without a white-label customization path. Restore it against the new branding hooks: tauri.conf.json, the icon set, and the bootstrap UI. The bundled script is dependency-free Node, regenerates icons via tauri icon, and empties updater endpoints so branded builds never touch the official feed. * fix(desktop-shell): give brand builder scripts node globals for eslint The desktop-brand-builder skill script runs under node but lives outside every existing node-scripts glob in eslint.config.js, so lint:ci failed with 7 no-undef errors on process/console/URL in brand-create.mjs. Add the skill scripts path to that existing block. Co-authored-by: Qwen-Coder <qwen-coder @alibabacloud.com> * fix(desktop-shell): complete updater identity patching and fix npx spawn on Windows - When branded build has no custom updater endpoints, also clear the official pubkey and set bundle.createUpdaterArtifacts to false so the Tauri bundler does not produce signed updater artifacts that no feed will serve. - Add shell: true to the npx spawnSync call so it works on Windows where npx is npx.cmd. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(desktop-shell): address review findings for brand builder skill - Add brand-builds/ to .gitignore (R1-19) - Validate logo is a file, not a directory (R1-8) - Document target-specific bundle path in SKILL.md (R1-17) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(desktop-shell): harden brand-create against injection and shell safety - Use function replacers in replaceAll to prevent $& pattern interpretation when appName contains dollar signs (R1-3) - Quote logo path in shell spawn to handle paths with spaces (R1-4) - Add image extension validation for logo files (suggestion R1-6) - Document silent config mutations in SKILL.md (suggestion R1-5) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(desktop-shell): document cross-compile workflow and guard against re-run - SKILL.md: document that build:runtime must be re-run with QWEN_DESKTOP_TARGET set before each cross-compile target, otherwise the packaged artifact contains a wrong-arch Node binary. - brand-create.mjs: detect already-branded shell-root (productName no longer 'Qwen Code Desktop') and fail early with a clear message, preventing silent stale results from non-idempotent re-runs. - SKILL.md: add explicit 'never re-run in the same clone' warning to Failure Handling section. Addresses review findings R1-16 (cross-compile docs) and idempotency guard from qwen-code-ci-bot. Co-authored-by: Qwen Code <noreply@alibaba-inc.com> * fix(desktop-shell): harden brand-create against updater crash, icon misreport, and JS injection - Keep updater pubkey as empty string instead of deleting it (the tauri-plugin-updater schema requires `pubkey: String` with no default; removing it causes deserialization failure at startup). - Report accurate icon replacement status when `tauri icon` fails on non-PNG logos (previously claimed icon.png was replaced even when it was not). - Escape single quotes in appName before injecting into bootstrap.js single-quoted string literals (an appName like "Bob's App" caused SyntaxError). - Add root `npm install` step to SKILL.md workflow (build:runtime shells out to repo root which needs cross-env and other root devDependencies). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(desktop-shell): eliminate shell injection in brand icon generation (R1-4) Replace shell:true npx spawn with direct Node invocation of the Tauri CLI entry point. The logo path is now passed as a plain argv element, preventing command substitution via crafted filenames ($(cmd), `cmd`). Falls back to shell-less npx when @tauri-apps/cli is not resolvable from the shell root. Adds a test verifying generateIcons contains no shell:true usage. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(desktop-shell): require updaterPubkey when custom updater feed is configured (R1-1) When a brand supplies updaterEndpoints, the matching signing pubkey must also be provided. Without this check, custom feeds were paired with the official pubkey, breaking update verification permanently. loadConfig now fails fast when updaterEndpoints is non-empty but updaterPubkey is missing. patchTauriConfig sets the pubkey from the brand config when endpoints are present. SKILL.md documents updaterPubkey and TAURI_SIGNING_PRIVATE_KEY usage. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(desktop-shell): reject appName matching pristine default to close re-run guard bypass (R3-4) When appName equals 'Qwen Code Desktop' (either explicitly or derived from brandId like 'qwen-code-desktop'), the detectAlreadyBranded guard never fires on the first run, allowing a second run to double-patch bootstrap strings. loadConfig now rejects this appName at validation time, before any files are mutated. Covers both explicit override and derived paths. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(desktop-shell): silence empty-block lint in brand-create-safety test Add /* best-effort cleanup */ comments inside two catch blocks used for teardown so ESLint no-empty rule is satisfied. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(desktop-shell): escape backslashes and newlines in appName for bootstrap.js injection brand-create.mjs only escaped single quotes before splicing appName into the single-quoted string literals of bootstrap/bootstrap.js. A free-form appName ending in a backslash (or containing a newline) produced syntactically invalid generated bootstrap.js while the script still exited 0 reporting bootstrapPatched. Derive the injected content via JSON.stringify so backslashes, newlines, and control characters are all escaped, then re-quote it for the single-quoted context. Add a safety test covering hostile appName values. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * fix(desktop-shell): HTML-escape appName in bootstrap/index.html, fail closed on missing updater section (R5-1, R5-8) R5-1: appName was spliced raw into bootstrap/index.html (<title>, alt attribute, <h1>, <h2>), so free-form brand names with <, > or " produced broken markup (and a </title> breakout). The index.html path now uses an HTML-escaped form while bootstrap.js keeps its JS-literal escaping. R5-8: when the target shell-root's tauri.conf.json has no plugins.updater section, the brand's validated updaterEndpoints/updaterPubkey were silently discarded while brand-create exited 0 reporting them as applied. Fail closed before any file is written, leaving the config unmutated. Tests: hostile-appName index.html fixture assertions (escaped output, no raw breakout) and a no-plugins.updater shell-root case (non-zero exit, stderr names the missing section, config byte-identical). Both new assertions go red when the corresponding fix is removed. Suite 8/8 green; prettier + eslint clean on both changed files. Co-authored-by: Qwen-Coder <qwen-coder @alibabacloud.com> * fix(desktop-shell): fail on non-array updaterEndpoints in brand.json A scalar updaterEndpoints (e.g. a string typo of the JSON-array shape documented in SKILL.md) was silently coerced to [] before the updater-safety guards ran, so brand-create exited 0 while shipping the brand with in-app updates permanently disabled. Reject any non-array value with an explicit error naming the expected shape; omitted or [] still disables updates as documented. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder @alibabacloud.com> Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: Qwen Code <noreply@alibaba-inc.com> Co-authored-by: root <root@vscode-sqlx011163220057.na131>









What this PR does
This replaces the move/rename approach previously attempted in this PR with a straight deletion, as agreed in review. OpenWork (modelstudioai/openwork) has already forked the Electron desktop code and is self-contained, so the Electron tree and its release/sync machinery leave this repo:
packages/desktop(the Electron desktop app, including thelive-hostElectron app and its bun workspace), and retires the OpenWork sync:scripts/desktop-openwork-sync.ts, thedesktop-openwork-syncroot script, the.qwen/skills/openwork-desktop-sync/skill, and the matching web-shell skill descriptions/i18n entries..github/workflows/live-host.yml,.github/workflows/live-host-release.yml, and.github/workflows/sync-live-host-to-oss.yml.scripts/check-voice-guard-sync.js(its sole purpose was cli↔desktop voice-guard parity againstpackages/desktop/packages/server-core) and its CI step.package.jsonworkspaces negation,package-lock.json,eslint.config.js,.prettierignore,.yamllint.yml,docs/developers/architecture.md, the isolation check, and the review-lib workspace fixtures/comments, which now use the surviving!packages/desktop-shellnegation as their worked example.Why it's needed
The Electron desktop app has been replaced by the Tauri app in
packages/desktop-shell, and the Electron tree is no longer developed in this repo. OpenWork now owns that code (including live-host) and has already forked it, so maintaining a commit-by-commit sync plus separate Live Host CI/release pipelines here is pure maintenance cost with no benefit. Deleting the dead tree removes ~380k lines that CI, tooling, and contributors still have to step around, and it lets the follow-updesktop-shell→desktoprename happen on a clean slate.Reviewer Test Plan
How to verify
.github/workflows/desktop-release.ymlis byte-identical on this branch (still carries theelectron_bridgeinput and builds only frompackages/desktop-shell),.github/scripts/create-electron-bridge-manifest.mjsand everything underpackages/desktop-shell/are untouched, and.github/workflows/sync-desktop-to-oss.ymlis untouched (verified it mirrors only Tauri artifacts: it consumesdesktop-release.ymloutputs and its test readspackages/desktop-shell/src-tauri/tauri.conf.json).grep -rniE 'packages/desktop([^/-]|$)|desktop-openwork-sync|bump-live-host-version' . --exclude-dir=.gitreturns nothing;grep -rni openwork . --exclude-dir=.gitreturns one explanatory comment in a script test plus unrelatedopenWorkflowDetailidentifiers;grep -rli live-host . --exclude-dir=.gitreturns only the keptpackages/cli/src/serve/**files plus one script test that pins the frozen feed contract.npm cisucceeds (validates the editedpackage.json/package-lock.jsonworkspace set), thennpm run check:desktop-isolationpasses.npx vitest run --config ./scripts/tests/vitest.config.ts— 52/52 files, 1141 passed / 13 skipped (covers the editedrelease-workflow.test.js,workspaces.test.js,qwen-autofix-workflow.test.js, and the retaineddesktop-oss-workflow.test.js).npx vitest runonpackages/cli/src/commands/review/(build-test, workspaces, workspace-scope, test-efficacy) — 282/282 pass after the fixture rename topackages/desktop-shell;packages/web-shelltypecheck and itslocalCommandstests also pass.Evidence (Before & After)
N/A — deletion/tooling change, no user-visible UI. Local verification output:
Desktop workspace isolation check passed., scripts suiteTest Files 52 passed (52) / Tests 1141 passed | 13 skipped, cli review suiteTests 282 passed (282), web-shelltsc -p tsconfig.json --noEmitexit 0,eslint --max-warnings 0clean on every touched file. Head commit:034c85590f68eada2f4deef616714d5361854a36.Tested on
Environment (optional)
Node v22 on Linux; repo tooling only (
npm ci, vitest suites, eslint, prettier, tsc). Full platform matrix left to CI, including thedesktop_shellcompile job that proves the bridge still builds withoutpackages/desktop.Risk & Scope
desktop-release.yml(incl. theelectron_bridgeinput),create-electron-bridge-manifest.mjs, thedesktop-latestfixed release/feed mirrored bysync-desktop-to-oss.yml, and all ofpackages/desktop-shell, so existing Electron users can still upgrade to Tauri.packages/cli/src/serve/live/**stays (it still installs from the frozenlive-host-latestfeed; removing it is a separate cleanup); thedesktop-shell→desktoprename is explicitly NOT in this PR and lands as a follow-up.Linked Issues
Implements the deletion/deprecation half of #8596 (the
desktop-shell→desktoprename half follows as a separate PR). Related bridge work, unchanged here: #8392, #9079.中文说明
这个 PR 做了什么
按照评审中达成的一致意见,本 PR 把之前尝试的「移动/改名」方案替换为直接删除。OpenWork(modelstudioai/openwork)已经 fork 了 Electron 桌面端代码并完全自包含,因此 Electron 代码树及其发布/同步机制从本仓库移除:
packages/desktop(Electron 桌面应用,含live-hostElectron 应用及其 bun workspace),并停用 OpenWork 同步:scripts/desktop-openwork-sync.ts、根目录的desktop-openwork-sync脚本、.qwen/skills/openwork-desktop-sync/skill,以及 web-shell 中对应的 skill 描述/i18n 条目。.github/workflows/live-host.yml、.github/workflows/live-host-release.yml和.github/workflows/sync-live-host-to-oss.yml。scripts/check-voice-guard-sync.js(它唯一的作用是针对packages/desktop/packages/server-core做 cli↔desktop 语音守卫镜像校验)及其 CI 步骤。package.json的 workspaces 排除项、package-lock.json、eslint.config.js、.prettierignore、.yamllint.yml、docs/developers/architecture.md、隔离检查脚本,以及 review 库中的 workspace 测试夹具/注释(改为以仍保留的!packages/desktop-shell排除项作为示例)。为什么需要
Electron 桌面应用已被
packages/desktop-shell中的 Tauri 应用取代,Electron 代码树不再在本仓库开发。OpenWork 已经 fork 并拥有这部分代码(含 live-host),继续在本仓库维护逐提交同步和独立的 Live Host CI/发布流水线只有成本没有收益。删除这棵死树可以减少约 38 万行 CI、工具链和贡献者都要绕开的代码,也让后续desktop-shell→desktop的改名能在干净的基线上进行。评审测试计划
如何验证
.github/workflows/desktop-release.yml在本分支上逐字节未变(仍带electron_bridge输入,且只从packages/desktop-shell构建);.github/scripts/create-electron-bridge-manifest.mjs和packages/desktop-shell/下所有内容未动;.github/workflows/sync-desktop-to-oss.yml未动(已核实它只镜像 Tauri 产物:消费desktop-release.yml的输出,其测试读取packages/desktop-shell/src-tauri/tauri.conf.json)。grep -rniE 'packages/desktop([^/-]|$)|desktop-openwork-sync|bump-live-host-version' . --exclude-dir=.git无任何命中;grep -rni openwork . --exclude-dir=.git只剩一个脚本测试里的解释性注释和无关的openWorkflowDetail标识符;grep -rli live-host . --exclude-dir=.git只命中保留的packages/cli/src/serve/**文件和一个钉住冻结 feed 契约的脚本测试。npm ci成功(验证修改后的package.json/package-lock.jsonworkspace 集合),随后npm run check:desktop-isolation通过。npx vitest run --config ./scripts/tests/vitest.config.ts—— 52/52 个文件,1141 通过 / 13 跳过(覆盖修改过的release-workflow.test.js、workspaces.test.js、qwen-autofix-workflow.test.js以及保留的desktop-oss-workflow.test.js)。packages/cli/src/commands/review/(build-test、workspaces、workspace-scope、test-efficacy)运行npx vitest run—— 夹具改名为packages/desktop-shell后 282/282 通过;packages/web-shell的 typecheck 及其localCommands测试也通过。证据(前后对比)
N/A —— 删除/工具链变更,无用户可见 UI。本地验证输出:
Desktop workspace isolation check passed.、scripts 套件Test Files 52 passed (52) / Tests 1141 passed | 13 skipped、cli review 套件Tests 282 passed (282)、web-shelltsc -p tsconfig.json --noEmit退出码 0、对所有改动文件eslint --max-warnings 0无告警。Head commit:034c85590f68eada2f4deef616714d5361854a36。测试环境
环境(可选)
Linux 上的 Node v22;仅使用仓库自带工具链(
npm ci、vitest 套件、eslint、prettier、tsc)。完整平台矩阵交给 CI,其中包括desktop_shell编译任务,用以证明没有packages/desktop时升级桥仍可构建。风险与范围
desktop-release.yml(含electron_bridge输入)、create-electron-bridge-manifest.mjs、由sync-desktop-to-oss.yml镜像的desktop-latest固定版本/feed,以及整个packages/desktop-shell,现有 Electron 用户仍可升级到 Tauri。packages/cli/src/serve/live/**下的 CLI 侧 live 代码保留(它仍从冻结的live-host-latestfeed 安装;移除是单独的清理工作);desktop-shell→desktop的改名明确不在本 PR 内,将作为后续 PR。关联 Issue
实现 #8596 的删除/弃用部分(
desktop-shell→desktop改名部分将作为单独 PR 跟进)。相关的升级桥工作(本 PR 未改动):#8392、#9079。