news 2026/9/20 7:45:41

如何给 Qwen Code 桌面客户端换品牌:从 brand.json 到安装包

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何给 Qwen Code 桌面客户端换品牌:从 brand.json 到安装包

如何给 Qwen Code 桌面客户端换品牌:从 brand.json 到安装包

【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code

你手上有一个 AI 产品,想出一个带自己 logo、自己名字的桌面客户端,而不是一个 Qwen Code 的换皮版。好消息是 Qwen Code 仓库内置了一条完整通路:桌面壳换到 Tauri 底座之后,packages/desktop-shell/ 成为当前唯一的桌面实现,品牌化构建的挂载点只有三处——src-tauri/tauri.conf.jsonsrc-tauri/icons/图标目录,以及bootstrap/启动 UI。一条 brand-create 品牌构建脚本负责把这三处一次性换掉,你最终拿到的是一个白标桌面应用安装包。

你只需要交两样东西:brandId 和 logo

输入规则的设计目标是最少输入,脚本自己算,不问你brandIdlogo必填,website可选,appName、appId、artifactPrefix、updaterEndpoints、updaterPubkey、target 这些字段全都可以缺省——脚本会派生;你只想覆盖其中某几项时,也可以直接在配置里给值。技能文档对这一点有硬性要求:必填项不全时只允许询问一次,字段一旦齐全就直接进入构建,不追加任何确认步骤

校验规则很简单:

  • brandId必须匹配^[a-z][a-z0-9-]*$,即小写字母开头,后接小写字母、数字、短横线
  • logo是本地图片文件路径,必须真实存在,推荐 1024px 以上的方形 PNG
  • website可选,只影响 appId 的派生
  • 其余字段缺失时由脚本补齐,不需要你填

默认值是怎么自动算出来的

脚本自己算,不问你。拿acme-ai走一遍完整推导:

  • appName:短横线切段、逐段首字母大写、空格连接 →Acme AI
  • artifactPrefix:同一套规则,用短横线连接 →Acme-AI
  • appId:取website的 host,剥掉www.前缀,把标签反转后追加.desktophttps://acme.aiai.acme.desktop

host 反转有一个隐含条件:反转前 host 至少要剩两段,否则不算"合法 host",直接落回退逻辑。website没给、格式不对、或者 host 只有一段时,appId回退为app.<brandId>.desktop,例如app.acme-ai.desktop

还有一个小细节:脚本内置了一组常见缩写词(aiapicliidesdkuiurl),派生名称时整体大写而不是首字母大写——brandId: acme-cli得到的是Acme CLI,不是Acme Cli

从零到安装包:一条命令链

整条工作流是线性的,按顺序走即可。先隔离克隆:每个品牌一个全新 clone,克隆到独立目录再开brand-<brandId>分支。

BUILD_ROOT="$PWD/brand-builds/acme-ai-$(date +%s)" git clone --branch main --single-branch \ https://gitcode.com/GitHub_Trending/qw/qwen-code "$BUILD_ROOT/qwen-code" git -C "$BUILD_ROOT/qwen-code" checkout -B brand-acme-ai origin/main

clone 或 checkout 失败就必须停在这里报告失败,绝不能假装分支已经创建而继续往下走。在构建目录里写一份最小的 brand.json(logo 用绝对路径):

{ "brandId": "acme-ai", "logo": "/abs/path/to/logo.png", "website": "https://acme.ai" }

装依赖要装两层:根部的npm installbuild:runtime会调用根部的cross-env、esbuild 等 devDependencies),加上 desktop-shell 自己的依赖:

npm install cd packages/desktop-shell npm install --workspaces=false

最后运行 brand-create.mjs:这是一个不需要装任何第三方包的 Node 脚本(Node 18 以上即可)。技能文档明确要求:内置脚本可用时,不要手工去编辑tauri.conf.json、图标文件或 bootstrap 品牌字符串,脚本才是补丁配置与生成资源的唯一权威来源。

node packages/desktop-shell/.agents/skills/desktop-brand-builder/scripts/brand-create.mjs \ --shell-root /abs/path/to/qwen-code/packages/desktop-shell \ --config /abs/path/to/brand.json

跑完输出一份 JSON 报告:brandId、appName、appId、artifactPrefix、updaterEndpoints,外加被补丁的 tauriConfig 路径、图标生成结果和 bootstrap 文件列表。

脚本改了哪三处文件

按"用户最先看到什么"的顺序讲,先说换肤。

第一步:bootstrap 启动 UI。脚本把你的 logo 复制为bootstrap/brand-logo<ext>,然后把bootstrap/index.htmlbootstrap/bootstrap.js里所有Qwen Code字面量替换成品牌名——页面标题、启动大标题、"Starting …" 文案,以及qwen-code-logo.svg的引用换成品牌 logo 文件名。为什么这样设计:启动 UI 是用户打开应用第一眼看到的东西,而品牌字符串就硬编码在这些字面量里,整体替换最可靠。

第二步:图标全家桶。脚本用 Tauri CLI 的icon命令从一张 logo 重新生成全部尺寸和平台格式,覆盖src-tauri/icons/。CLI 跑不起来时的回退是:logo 为 PNG 就复制成icons/icon.png并警告"其余尺寸仍是旧 logo";非 PNG 则一个图标都不动,提示转成 PNG 重试。

第三步:tauri.conf.json 配置。改四个字段:productName(应用名)、identifier(bundle identifier,应用在各平台的唯一身份)、bundle.shortDescription,以及plugins.updater.endpoints。为什么这样设计:这四个字段分别决定应用显示名、系统层面的身份标识、商店/描述文案,以及应用从哪里检查更新。

几个值得留意的设计细节:

  • 这个脚本一次只能跑一次。它靠检测productName是否还是默认值Qwen Code Desktop来判断是否首次运行,已打过补丁的克隆会被直接拒绝——bootstrap 补丁依赖原始字面量,重跑会把品牌字符串重复拼接进去
  • 品牌方给了更新源配置、但目标tauri.conf.json里根本没有 updater 段时,脚本会直接报错拦下来,不偷偷跳过——否则等于悄悄丢弃你校验过的更新配置,交付一个永远无法更新的应用;清空更新端点时同步把bundle.createUpdaterArtifacts置 false、plugins.updater.pubkey置空字符串而不是删除字段(schema 要求该字段是 String 且无默认值,删了启动即反序列化失败,而端点为空时空字符串无害)
  • 生成图标时 logo 路径以普通命令行参数传递、不经过任何命令解释器,路径里就算有$()或反引号也不会被 shell 执行

换个平台打包:交叉编译 Tauri 应用最容易翻车

默认按宿主平台打包:npm run build:runtime --workspaces=false然后npx tauri build。要交叉编译时,问题集中在build:runtime上。prepare-runtime.js 按QWEN_DESKTOP_TARGET环境变量(不设置时取宿主平台)下载对应平台的 Node.js 运行时并捆绑进包。取值会被归一化为五种受支持目标:aarch64-apple-darwindarwin-arm64x86_64-apple-darwindarwin-x64aarch64-unknown-linux-gnulinux-arm64x86_64-unknown-linux-gnulinux-x64x86_64-pc-windows-msvcwin32-x64,不在其中的直接抛错。

⚠️目标平台与宿主不同时,必须在每次tauri build --target之前带着环境变量重跑build:runtime

QWEN_DESKTOP_TARGET=aarch64-apple-darwin npm run build:runtime --workspaces=false npx tauri build --target aarch64-apple-darwin

不重跑的代价:产物里内嵌的是宿主架构的 Node 二进制,用户一打开就是 exec format error(操作系统拒绝执行架构不符的二进制)。target: all时逐目标执行"build:runtime → tauri build",且只跑当前机器或 CI 环境支持的目标——文件真实存在才算产出,别声称造出了跑不了的包。产物统一落在src-tauri/target/下,按平台进dmg/nsis/appimage/deb/四个 bundle 子目录(DMG 是 macOS 光盘镜像,AppImage 是 Linux 免安装单文件)。

想让品牌客户端能收到更新:桌面应用更新签名必须用自己的密钥

品牌构建默认不签名。上游发布流水线的签名私钥与更新密钥只属于官方 Qwen Code 发布;品牌方要发签名版或应用内更新,必须自建独立密钥对加独立更新源,绝不复用上游的。密钥对一行命令生成:

npx @tauri-apps/cli signer generate -w ~/.tauri/my-brand.key

.key是私钥(配进构建 CI 的TAURI_SIGNING_PRIVATE_KEY),配套.pub里的 base64 公钥填进 brand.json 的updaterPubkey

公钥和私钥必须配对。updater 插件用这把公钥校验每次更新的签名,所以脚本在加载配置时强制校验:updaterEndpoints非空而没有updaterPubkey直接报错——配错或不配,每次更新检查都会校验失败,应用将永远无法更新。方向反过来同样成立:品牌构建与官方更新源各走各的更新通道updaterEndpoints默认空数组意味着品牌包永不轮询官方源,官方源也不会更新品牌包。另外注意:appName不能写成Qwen Code Desktop,加载配置时就会拒绝——"一次只能跑一次"的判断依赖productName偏离默认值,名字撞了默认值,守卫就失效了。

打包完,先别急着交付

验证按四步走:

  1. 确认产物落在src-tauri/target/release/bundle/(交叉编译时是src-tauri/target/<triple>/release/bundle/),平台对应dmg/nsis/appimage/deb/
  2. 对每个产物计算 SHA-256(sha256sum,macOS 用shasum -a 256
  3. macOS 上对生成的 DMG 执行hdiutil verify
  4. 把产物路径、SHA-256、应用名、appId 和构建目录一起报告给对方

常见翻车点速查:

场景处理
brandId不合法摆出正则^[a-z][a-z0-9-]*$,请用户改
logo 缺失或不是图片请用户给一个存在的本地图片路径
brand-create.mjs 不存在报告脚本缺失,附上预期命令
shell-root 已品牌化脚本会拒绝运行,从全新克隆重来

两条铁律:

失败时不要删构建目录——它是事后排查的依据,留着它,只把最后几行有用报错和日志路径带回来。

禁止在同一克隆重跑 brand-create——脚本一次只能跑一次,配置错了就丢弃这个克隆、重新克隆重来。

一份 brand.json,加一个不需要装任何第三方包的 Node 脚本,就是 Qwen Code 桌面客户端品牌化构建的全部核心抽象:输入两样东西,输出三处补丁和一份可核验的安装包清单。下次"帮我做一个带自己 logo 的白标桌面应用"这种需求来的时候,你只需要把acme-ai换成自己的 brandId。

【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 7:45:27

GetQzonehistory 使用指南:5 分钟完成 QQ 空间数据备份

GetQzonehistory 使用指南&#xff1a;5 分钟完成 QQ 空间数据备份 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 跑完一次 GetQzonehistory&#xff0c;一次 QQ空间数据备份就完成了&…

作者头像 李华
网站建设 2026/9/20 7:45:25

华为IPD研发质量管理:流程裁剪、决策评审与质量成本模型落地

简介&#xff1a;这是一份以华为IPD与质量管理体系融合为核心的研发质量管理培训PPT&#xff0c;面向研发管理者、质量工程师、流程改进人员以及希望系统学习IPD方法的产品经理。内容先解读IPD主业务流框架与核心思想&#xff0c;包括跨职能团队、市场导向、并行工程和产品生命…

作者头像 李华
网站建设 2026/9/20 7:40:28

本地优先AI编程记忆中枢:用Git+Markdown打通Claude Code、Codex、Cursor

如果你和我一样&#xff0c;电脑上同时装着 Claude Code、Codex 和 Cursor 三款 AI 编程工具&#xff0c;大概率经历过这种崩溃瞬间&#xff1a;上午用 Claude Code 敲定了一套 API 的返回结构&#xff0c;下午切到 Cursor 改前端&#xff0c;它完全不记得这回事&#xff0c;按…

作者头像 李华