弃用 ZCode,转 DeepSeek Harness:我用 GitHub Actions 自建 Windows 打包的全实录

一句话版:我的 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 。本系列文章公众号 + 掘金同步更新,欢迎关注追更。

一、起因:ZCode 把整个工作区悄悄传上了云

2026-09-18 上午,博主 ferstar 发了一篇排查文(原文见文末参考资料),核心结论就三行:

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

上传链路(他从客户端包里逆向核对出来的时序图):

注意第二行:表单调 OSS 直传,不经过智谱自己的业务服务器 ------所以客户端日志里只有 zcode.z.ai 的出站记录,想靠日志发现这件事基本没戏。

社区随后有人在自己的 Windows 机器上复测,证据比原文还全:

几个比"上传"本身更扎心的细节:

  • 32 个工作区被抓过快照 (只要在该工作区发过 prompt 就中招),最大单包 107MB,有包重试上传失败 152 次还躺在 pending/ 等重传,另有十几个小仓已上传成功
  • 快照与模型渠道无关:哪怕你配的是第三方 API、推理内容根本不经过它的服务器,快照 sidecar 只认登录态 JWT------用谁的模型它都照拍照传;
  • 全局配置随每次快照"搭车"上传,而 ZCode 的配置里存着明文 API key
  • 触发点是每次发 prompt 前 + 任务结束时,单会话最多 62 次捕获;
  • 四条"死线":默认常开、UI 没有任何开关能关、隐私政策没提、手动删了 pending 包 30 分钟内自动重新打包重传

当天傍晚,智谱在官方社群回应,媒体跟进报道(下图为报道截图 + 官方社群声明原文):

回应我看了。道歉、修复、"近期开源 + 邀第三方审查",都是加分项------但"默认常开 + UI 关不掉 + 删了会重传 + 私钥只在云端"这四条是既成事实,已经传上去的东西谁也拿不回来。代码是我每天写的、最敏感的家当,一个我控制不了、看不见底的行为,我不赌。

当天,我弃用了 ZCode。

二、换谁?DeepSeek Harness(DSH)

备选里我选了 DeepSeek 开源的 AI 编程 agent(DSH,仓库主页见下图)。理由很朴素:

  1. 开源 + 本地优先 :代码全在 GitHub 上,行为可以逐行核对;数据落本机,没有"服务端私钥"这种我够不着的东西。对"上传"这件事的终极答案就是------源码翻完也没法"悄悄",因为它没有悄悄的余地
  2. 社区是真的活:写这篇时 229k stars、27k+ forks,Discussions 1300+ 条,社区插件 150+,连 ACP 协议、本地小模型都被接了进来。
  3. 可扩展:口号就是 "Everything is a Plugin"------文件预览、终端、浏览器全是插件,不满意可以自己改(本篇后面有伏笔)。

唯一的问题:DSH 官方没有 Windows x64 成品包。它的桌面打包脚本硬性要求"在 Windows x64 主机上构建"(这是仓库打包脚本自己的约束,非 Windows 环境直接拒绝),所以现有 CI 产不出 Windows 包。

那就自己打。fork 一份,在 GitHub Actions 上自建流水线。全程浏览器操作,下面逐步走查。

三、fork + 自建流水线:浏览器操作全流程

3.1 第一步:Fork 上游仓库

浏览器打开上游仓库,右上角点 Fork(免费账号 50 个仓库额度内随便 Fork)。我的 fork 页面(注意顶部 "forked from" 一行,以及后来我改代码后出现的 "3 commits ahead" 标记):

3.2 第二步:在 fork 里加一个打包 workflow

在仓库的 .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。

3.3 第三步:Actions 里手动触发

进仓库 Actions 标签页,在左侧 workflow 列表里点我新建的那个 workflow,右侧点 Run workflow(选 master 分支,确认即可):

点完就交给云端了。冷缓存首次构建约 25--40 分钟,页面刷新着看就行。

3.4 第四步:看 run 成功

23 分 59 秒后,状态变绿:

3.5 第五步:下载 .exe

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 里了)

上面走查的是"最终可用版"。第一次跑通之前,我在同一个 workflow 文件上连吃了三个坑------截图里那些 commit 标题(fix(workflow): ...)就是它们的墓志铭。

坑一:步骤的 shell 必须写 pwsh,不能写 bash

第一次构建挂在打包第一步的 tar:

arduino 复制代码
Cannot connect to D: resolve failed

排查半天才定位:Windows runner 上 bash 步骤会把 C:\Program Files\Git\usr\bin 提到 PATH 最前 ,Node 的 spawnSync('tar') 命中的是 MSYS 的 GNU tar,它把 D:\a\... 这种绝对路径当成 host:file 远程语法去"连接 D:"------直接 resolve failed。

修法:workflow 里所有步骤显式 shell: pwsh,让 tar 落在原生 C:\Windows\System32\tar.exe(bsdtar),参数全兼容。

坑的本质:Windows CI 上"默认 shell"不是你以为的那个。PATH 顺序决定你的 tar/curl/awk 到底是谁。

坑二:.env.windows 必须显式生成

打包前必须先生成 apps/desktop/.env.windows------官方打包环境加载器只读这个文件、不回退 ambient 环境变量,缺文件直接 throw。unsigned 最小集:

ini 复制代码
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?都不是。排查链路(每一步都有实证):

  1. .env.windowsDSH_DESKTOP_AUTO_UPDATE_ENV=test → 打包时把"飞书测试环境强制更新策略"(dshMandatoryUpdatePolicy,含 authentication: "feishu-test"烤进了 app.asar 的根 package.json

  2. 启动时壳子请求测试环境更新策略 → 返回 401 未登录

  3. 打包态 → 弹"登录测试环境 / 请飞书登录"的阻塞模态窗;

  4. 模态窗创建时往主窗口注入一条 CSS------全代码库唯一注入点

    js 复制代码
    parent.webContents.insertCSS('body { filter: blur(2px) !important; }')

    这就是"模糊"

  5. 模态窗 modal: true 屏蔽主窗口全部输入,而本地 unsigned 包永远过不了飞书 SSO

  6. 雪上加霜:登录窗自己的文档 JS 要等接口 resolve 才渲染按钮,实测 <body>空白的------连"稍后"按钮都没有。

= 模糊 + 卡死,连点都没处点。

修复(双管齐下):

  • 根治.env.windowsDSH_DESKTOP_AUTO_UPDATE_ENV=production------production 是匿名认证,prod 端点对未列名 bundle 实测返回 404(非 force)→ 不弹窗。重打的包原生就是好的;
  • 已下的包不重打也能修 :asar 原地热补丁------把根 package.json 里的策略字段等长空格替换删掉 ,同步改掉 asar header 里该文件的 2 处 SHA256(integrity.hash + integrity.blocks[0]),文件大小一字节不变 ,无需重打包。关键坑:数据槽别手算偏移(asar header 是 4 字节对齐,差 1 字节就写坏下一个文件边界),用 @electron/asarextractFile 拿 ground truth、按唯一内容定位替换。

打完验证三件套:asar 里策略字段读出来是 undefined;带 --remote-debugging-port 启动后 targets 里只剩主窗口、没有 update-dialog;主窗口 getComputedStyle(document.body).filter === 'none'。UI 完整可用。

这个坑的教训:打包进 asar 的每一个默认值,都是"出厂行为"。 一个 env 的选择(test vs production),直接决定了你的包出厂是"能用"还是"砖"。

附:迭代不必每次全量 CI

本地改代码 → 重新构建受影响的包 → 重打包 asar(保持 unpacked 集一致)→ 换进 resources/app.asar。我给自己留了版本快照(app.asar.latest / 各补丁前备份),一键回滚。这几天我就是这样在"文件树搜索、树内定位、md 预览"几个小功能上快速迭代的。

五、小结

  • 工具可以换,代码主权不能谈。上传行为"已修复 + 将开源"是好事,但对存量数据是既成事实------这个账我算了之后就没再犹豫;
  • 换 DSH 的价值不只是"换一个编码 agent",而是整条工具链回到自己手里:源码、打包、补丁、迭代,全在自己眼皮底下;
  • 给同样想在 Windows 上用 DSH 的同学:浏览器 fork 一份 → 加一个 workflow 文件(避开上面三个坑)→ Actions 里点一下 → 25 分钟后 Artifacts 里就有你的 .exe。

P.S. 迁过来之后我在 DSH 上做了一些文件预览的小增强(文件搜索、树内定位、md 图片渲染),细节做扎实了视情况另文,不预告。

参考资料(平台不支持外链,正文关键处已截图;以下为原文地址,可自行访问)

相关推荐
Wang's Blog2 小时前
Java 接入Redis: Redis下载与源码编译安装
java·服务器·redis
农民工老王2 小时前
故障排查:反向代理转发 GET 请求时 JDK 自动追加 Content-Length:0 致后端 500
java·httpclient·content-length
泡海椒2 小时前
jquick-pdf 防止 PDF 内容分页断裂:keepTogether 属性妙用
java·开发语言·pdf
vx_BS813302 小时前
【项目编号:project51381】Spring Boot 婚纱摄影管理系统:套餐预约、在线咨询、支付与客片展示的一站式业务实现
java·spring boot·eclipse·tomcat·mybatis
IT毕设实战小研2 小时前
基于大数据的商场商铺数据分析与可视化的设计与实现
android·java·大数据·django·课程设计
万年咸鱼2 小时前
Java Classpath 详解:从原理到实战
java
Ivanqhz3 小时前
矩阵引擎的数据流模式与 BM1684X 架构
java·服务器·网络·深度学习·神经网络
小蒜学长3 小时前
大学生健康饮食的智慧管理系统(代码+数据库+LW)
java·后端·springboot·大学生·健康饮食
计算机毕设定制辅导-无忧学长3 小时前
《基于SpringBoot的中学教师数字胜任力测评网站的设计与实现》
java·vue.js·spring boot·mysql·中学教师数字胜任力测评网站