更换 AI 编程工具并不只是重新安装一个客户端,真正棘手的是如何确认数据边界,并让新工具在自己的环境中稳定运行。由于 DeepSeek Harness 没有现成的 Windows x64 安装包,这次迁移需要从仓库 Fork、CI 流水线配置一路做到产物验证,同时处理打包过程中的 shell、环境文件和启动阻塞问题。
一句话版:我的 AI 编程工具被实锤"登录后静默打包整个仓库(含完整 .git 历史)加密上传云端、私钥只在服务端",当天弃用;换的 DeepSeek Harness(下文简称 DSH)官方没有 Windows 包,于是 fork 出一份、在 GitHub Actions 上自己打,全程浏览器操作,25 分钟出 .exe。
写在前面(自我介绍):我是 mldong,一个快速开发框架的作者。我的另一个主力作品是开源轻量工作流引擎 jeeflow——一套流程定义在 Java / Go / Python / Node / PHP / Rust / MoonBit / C# 八个语言栈上原生跑通,引擎核心零框架依赖,配套的钉钉风格流程设计器和统一前端也开源。文档站(规范 / 快速上手 / 多语言 demo):jeeflow-doc.mldong.com 。本系列文章公众号 + 掘金同步更新,欢迎关注追更。
2026-09-18 上午,博主 ferstar 发了一篇排查文(原文见文末参考资料),核心结论就三行:

只要处于登录状态,ZCode(智谱官方 AI 编程桌面端)就会在后台静默把整个工作区——包括完整的 .git 历史、LFS 大文件缓存、reflog 以及全局应用配置——打包加密,直接上传到阿里云 OSS。更讽刺的是:加密用的 RSA 公钥是服务端动态下发的,私钥只存在云端,你本地生成的那份密文,连你自己和客户端本体都解不开。
上传链路(他从客户端包里逆向核对出来的时序图):

注意第二行:表单调 OSS 直传,不经过智谱自己的业务服务器——所以客户端日志里只有 zcode.z.ai 的出站记录,想靠日志发现这件事基本没戏。
社区随后有人在自己的 Windows 机器上复测,证据比原文还全:

几个比"上传"本身更扎心的细节:
pending/ 等重传,另有十几个小仓已上传成功;当天傍晚,智谱在官方社群回应,媒体跟进报道(下图为报道截图 + 官方社群声明原文):


回应我看了。道歉、修复、"近期开源 + 邀第三方审查",都是加分项——但"默认常开 + UI 关不掉 + 删了会重传 + 私钥只在云端"这四条是既成事实,已经传上去的东西谁也拿不回来。代码是我每天写的、最敏感的家当,一个我控制不了、看不见底的行为,我不赌。
当天,我弃用了 ZCode。
备选里我选了 DeepSeek 开源的 AI 编程 agent(DSH,仓库主页见下图)。理由很朴素:

唯一的问题:DSH 官方没有 Windows x64 成品包。它的桌面打包脚本硬性要求"在 Windows x64 主机上构建"(这是仓库打包脚本自己的约束,非 Windows 环境直接拒绝),所以现有 CI 产不出 Windows 包。
那就自己打。fork 一份,在 GitHub Actions 上自建流水线。全程浏览器操作,下面逐步走查。
浏览器打开上游仓库,右上角点 Fork(免费账号 50 个仓库额度内随便 Fork)。我的 fork 页面(注意顶部 "forked from" 一行,以及后来我改代码后出现的 "3 commits ahead" 标记):

在仓库的 .github/workflows/ 目录下新建一个文件(浏览器里 Add file → Create new file,或者本地 push 上去都行),内容就干三件事:手动触发(workflow_dispatch)→ 在 windows-2025 runner 上跑官方打包命令(unsigned,零 secrets)→ 把产物传成 artifact:

文件头部注释把"为什么官方 CI 打不了"写清楚了(打包脚本拒绝在非 Windows 主机上构建 win-x64;仓库现成的 windows job 只跑 Wine 测试),workflow_dispatch 保证只有我手动点才会跑,runs-on: windows-2025 + 免签名参数保证零 secrets。
进仓库 Actions 标签页,在左侧 workflow 列表里点我新建的那个 workflow,右侧点 Run workflow(选 master 分支,确认即可):

点完就交给云端了。冷缓存首次构建约 25–40 分钟,页面刷新着看就行。
23 分 59 秒后,状态变绿:

run 页面底部 Artifacts 区,就是打包产物——deepseek-harness-windows-x64-unsigned(704 MB,带 sha256 摘要),点最右边的下载图标,直接落到本地:

解压后里面两样东西:
deepseek-harness-0.1.6-alpha.2-win-x64.exe(NSIS 安装器,约 290 MB)——双击安装;win-unpacked/(免安装目录)——拷走就能跑,DeepSeek Harness.exe 是入口,内置运行时全在里面。未签名包首次启动会弹 SmartScreen"未知发布者",点"仍要运行",属正常现象(没有代码签名证书,这是 unsigned 的代价)。
双击启动——自打包版实际跑起来的第一屏(没有模糊、没有卡死,工作区、模型选择、会话全在):

走到这里,整条链路闭环了:浏览器 fork → 加一个 workflow 文件 → 点一下 Run workflow → 25 分钟后下载 → 双击就能用。
上面走查的是"最终可用版"。第一次跑通之前,我在同一个 workflow 文件上连吃了三个坑——截图里那些 commit 标题(fix(workflow): …)就是它们的墓志铭。
第一次构建挂在打包第一步的 tar:
Cannot connect to D: resolve failed
排查半天才定位:Windows runner 上 bash 步骤会把 C:Program FilesGitusrbin 提到 PATH 最前,Node 的 spawnSync('tar') 命中的是 MSYS 的 GNU tar,它把 D:a... 这种绝对路径当成 host:file 远程语法去"连接 D:"——直接 resolve failed。
修法:workflow 里所有步骤显式 shell: pwsh,让 tar 落在原生 C:WindowsSystem32tar.exe(bsdtar),参数全兼容。
坑的本质:Windows CI 上"默认 shell"不是你以为的那个。PATH 顺序决定你的
tar/curl/awk到底是谁。
.env.windows 必须显式生成打包前必须先生成 apps/desktop/.env.windows——官方打包环境加载器只读这个文件、不回退 ambient 环境变量,缺文件直接 throw。unsigned 最小集:
DSH_DESKTOP_APP_ID=...
DSH_DESKTOP_AUTO_UPDATE_ENV=production
DSH_DESKTOP_MANDATORY_UPDATE_TEST_ORIGIN=...
DSH_DESKTOP_MANDATORY_UPDATE_PROD_ORIGIN=...
⚠️ 注意第二行——我第一版为了省事填了 test,然后迎来了最大的坑。
首包装进免安装目录,双击 exe:整窗文字发虚,像蒙了层毛玻璃;然后整个窗口点不动。
GPU?DPI?都不是。排查链路(每一步都有实证):
.env.windows 里 DSH_DESKTOP_AUTO_UPDATE_ENV=test → 打包时把"飞书测试环境强制更新策略"(dshMandatoryUpdatePolicy,含 authentication: "feishu-test")烤进了 app.asar 的根 package.json;parent.webContents.insertCSS('body { filter: blur(2px) !important; }')
→ 这就是"模糊";modal: true 屏蔽主窗口全部输入,而本地 unsigned 包永远过不了飞书 SSO;<body> 是空白的——连"稍后"按钮都没有。= 模糊 + 卡死,连点都没处点。
修复(双管齐下):
.env.windows 改 DSH_DESKTOP_AUTO_UPDATE_ENV=production——production 是匿名认证,prod 端点对未列名 bundle 实测返回 404(非 force)→ 不弹窗。重打的包原生就是好的;integrity.hash + integrity.blocks[0]),文件大小一字节不变,无需重打包。关键坑:数据槽别手算偏移(asar header 是 4 字节对齐,差 1 字节就写坏下一个文件边界),用 @electron/asar 的 extractFile 拿 ground truth、按唯一内容定位替换。打完验证三件套:asar 里策略字段读出来是 undefined;带 --remote-debugging-port 启动后 targets 里只剩主窗口、没有 update-dialog;主窗口 getComputedStyle(document.body).filter === 'none'。UI 完整可用。
这个坑的教训:打包进 asar 的每一个默认值,都是"出厂行为"。 一个 env 的选择(test vs production),直接决定了你的包出厂是"能用"还是"砖"。
本地改代码 → 重新构建受影响的包 → 重打包 asar(保持 unpacked 集一致)→ 换进 resources/app.asar。我给自己留了版本快照(app.asar.latest / 各补丁前备份),一键回滚。这几天我就是这样在"文件树搜索、树内定位、md 预览"几个小功能上快速迭代的。
P.S. 迁过来之后我在 DSH 上做了一些文件预览的小增强(文件搜索、树内定位、md 图片渲染),细节做扎实了视情况另文,不预告。