Skip to content

[Grok/dsh 66] macOS 预编译安装、更新与回退 #198

Description

@Blackman99

Parent

#132

Ticket: 66

Status: ready-for-agent

User Stories: 6, 7, 69, 70, 73(见父规格)

What to build

macOS 用户通过保留的 npm/codsh 入口安装预编译 Rust 客户端及必要辅助程序,启动 dsh 并安全更新或回到旧版。

Acceptance criteria

  • 在干净环境安装真实打包产物而非开发目录,匹配目标架构且普通用户无需 Rust 编译工具链。
  • dsh 最低版本、缺依赖、下载损坏、版本不匹配和部分更新失败有清晰恢复路径。
  • 新旧命令选择、Home/Profile 隔离和回退不破坏旧数据;不得启动官方 Grok 运行时兜底。
  • 为现有 Changesets/锁步发版提供兼容包布局、许可证和双语安装说明;本票不直接发布 npm release。

Blocked by

Delivery contract

用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。

Activity

  1. Blackman99 commented on Sep 28, 2026

    @Blackman99
    OwnerAuthor

    集成完成:macOS 预编译安装、更新与回退(#198)

    提交 412741e 已以普通(非强制)推送并入 rewrite/grok-dsh-20260920,基于 e0d31bf(#220)。

    实现内容

    • 版本一致:原生客户端报告启动器的包版本(codsh-rust 0.24.0),不再是内部 Cargo 的 0.1.0;build:rust 传入 CODSH_PACKAGE_VERSION。
    • 更新/回退:新增 packages/cli/bin/installer.mjs,按"拥有当前包的安装器"选择 npm/pnpm/Yarn/Bun(先看全局前缀,再看继承的 npm_config_user_agent)。codsh update 与新命令 codsh --rust update [--check] [--to <版本>] [--json](schema codsh.rust-update.v1)共用它;更新后先校验新 Rust 客户端再报告成功,失败时给出回到旧版的命令。
    • 恢复路径:原生文件损坏/截断、目标架构不符、版本不匹配、缺失、dsh 缺失或低于最低版本、部分更新失败,都给出一行可执行的恢复命令,并说明 ~/.codsh-rust、~/.dsh、~/.grok 不受影响、普通 codsh 仍可用。
    • dsh 固定测试版本:packages/cli/package.json 新增 codsh.testedDsh: "0.1.5-rc.3"。缺失/过旧提示、install-check(dsh.tested、dsh.note)和中英文 README 都给出 npm install -g @deepseek-ai/dsh@0.1.5-rc.3。
    • 启动竞态:dsh 已开始应答 ACP,但 dsh-llm-pi-ai 要等 settings 服务注入后才注册 provider adapter。因此在较慢的机器上,第一次 session/new 会失败("no adapter registered for provider"),或在清理时被 "ACP session persistence flush failed" 掩盖。现在在 15 秒内每 250 ms 重试一次(单测 adapter_registration_race_is_recognized),ACP 错误的 data 细节也会显示出来。
    • macOS 构建修复:
      • wrap.rs openpty 指针可变性;
      • 安装测试把 /tmp 解析为 /private/tmp;
      • rust-screen-pty-test.py 的 f-string 在 Python 3.10/3.11 上的语法错误(89141ee 引入)。
    • CI:
      • 可复用的 rust-native.yml 在各自的 runner 上构建 darwin-arm64/darwin-x64/linux-x64;
      • rust-platforms.yml 打包所有原生产物,并在 macOS arm64、Intel、Apple 芯片上的 x64 Node(Rosetta)三种环境中,用 registry 安装的 dsh 跑干净安装、更新/损坏/回退、PTY 隔离/网络审计和第一阶段流程;
      • release.yml 在发布前构建原生产物并运行 check:rust-package。
    • 中英文 README 与 CONTRIBUTING 的安装、更新、回退说明;Changeset rust-update-installer.md(codsh-cli / codsh-bundle patch)。

    检查(本机 Linux,完整链路,最终树与 412741e 相同)

    • cargo fmt --check、pnpm run typecheck:通过。
    • 严格 clippy:只有已知的 2 个错误(filesystem_sandbox.rs 的 tail_marker dead code、needless_return);放行这两类后通过。
    • cargo test --workspace:codsh-rust 791 通过 / 4 失败,均为已知的 Linux 失败(2 个 filesystem_sandbox、voice substitute_route…、privacy drafts_stay_local…);其余 crate 498 + 42 + 61 + 2 + 379 + 61 全部通过。
    • pnpm test:110 个文件通过、2 个跳过;2669 通过、15 跳过(含新增的 scripts/rust-update.spec.mjs 14 项)。
    • 旧版 e2e(pnpm 10):19 个文件通过、1 个跳过;177 通过、1 跳过。
    • build、build:rust、check:rust-package、rust-install-test.py、子代理审批 PTY:通过;plain-pipe 通过(沙箱段按已知 Linux 缺口跳过);rust-pty-test.py 在 Linux 上按设计拒绝运行(需要 macOS 网络审计),macOS 结果见下文 CI。

    真实运行(GitHub Actions macOS runner,未使用任何本地 Mac)

    • 证据分支运行 36379089738(ci/198-macos-install,f9ff16d,全部通过;之后只改了 README 措辞和 job 条件):
      • macOS arm64:macOS 15.7.9,Apple M1(虚拟机),Node v24.20.0 darwin-arm64。
      • macOS Intel:macOS 15.7.9,i7-8700B,Node v24.19.0 darwin-x64。
      • Rosetta 下的 x64 Node:sysctl.proc_translated=1。
      • 证据产物:macos-evidence-macos-15-native、macos-evidence-macos-15-intel-native、macos-evidence-macos-15-rosetta、codsh-cli-package(打包 tarball)、native-darwin-arm64、native-darwin-x64。
    • 集成分支运行 36381566523(412741e,推送后自动触发):三个原生产物、打包布局和三个 macOS 安装 job 全部通过(arm64、Intel、Rosetta)。
    • 每个 macOS job 的流程:
      1. 先删除 Rust 工具链(包括 Homebrew rustup),并确认 cargo on PATH: none;
      2. 用 npm install -g --prefix <干净前缀> @deepseek-ai/dsh@0.1.5-rc.3 codsh-cli-0.24.0.tgz 安装打包产物;
      3. install-check 结果:ok: true;artifact.key 为 darwin-arm64/darwin-x64,format 为 mach-o;dsh 0.1.5-rc.3(requires 0.1.5-rc.2,tested 0.1.5-rc.3);--version 为 codsh-rust 0.24.0 (dsh ACP; upstream a28ee2b; reference 1.0.34)。
    • rust-install-test.py(三个环境均通过):
      • headless 回合和 TUI 回合正常;
      • 更新到 99.0.1 后会话保留,再回退到 0.24.0,提示 "Return with: npm install -g codsh-cli@99.0.1";
      • 部分更新失败(99.0.2 缺原生文件)时给出回到 0.24.0 的命令;
      • rust_update JSON 的更新/回退:npm 安装并校验 sha256;
      • 拒绝版本不匹配、损坏(改写一个字节,提示 "damaged or incomplete download")、目标不符和缺失;
      • dsh 缺失/过旧时拒绝启动;
      • legacy_untouched: true,no_toolchain_or_official_runtime_called: true,8 次 LLM 请求全部走本机模拟服务。
    • arm64 和 Intel 上的已安装产物 PTY:rust-pty-test.py(隔离和网络审计)、streamed turn、permission、cancel、resume,以及 8 次旧 Home 继承启动(旧数据不变),全部 PASS。
    • Rosetta:把 arm64 Node 换成 x64 Node 后,启动器会说明"x64 Node 运行在 Rosetta 下,请安装 arm64 Node",并给出恢复命令。

    对照验收标准

    • 在干净环境安装真实打包产物,而不是开发目录;目标架构匹配(arm64、Intel、Rosetta 提示);runner 上已删除 Rust 工具链,普通用户不需要它。
    • dsh 最低版本、缺依赖、下载损坏、版本不匹配和部分更新失败都有清晰的恢复路径(见 install-test 的 refusals / dsh_refusals / update_partial_failure)。
    • 新旧命令选择(codsh 与 codsh --rust)、Home/Profile 隔离和回退都不破坏旧数据(legacy_untouched、旧 Home PTY);不会启动官方 Grok 运行时兜底。
    • 包布局兼容 Changesets/锁步发版(check:rust-package 校验原生文件、installer.mjs、Ship 文件和许可证),并有中英文安装说明;本票没有发布 npm release、没有打 tag。

    已记录的差异

    • dsh 版本固定:registry 上最新的 @deepseek-ai/dsh 0.1.7-rc.2 在第一个回合就失败(turn failed: format v4 message requires a producer-owned source kind);@0.1.5-rc.2 会解析出 rc.2/rc.3 混合的依赖树,在 Linux 上无法启动(dsh-sandbox-local 无法解析)。因此文档和恢复提示都固定为已测试的 0.1.5-rc.3。需要决策:README 旧版(非 Rust)安装行和 codsh.mjs 中的裸 npm install -g @deepseek-ai/dsh codsh-cli 保持不变,而按它安装会得到不兼容的 0.1.7。要么把 codsh 移植到 dsh 0.1.7(另起工作),要么把这些地方也改成固定版本。
    • 安装器优先级:与参考实现的检测顺序不同,这里全局前缀归属优先于继承的 npm_config_user_agent,因为在 pnpm/Yarn 脚本中运行 npm 安装的 codsh 时,会继承错误的 user agent(e2e 中有对应修复)。
    • 没有 TUI 内的 /update;update 只在启动器层面提供。
    • 没有 Developer ID 签名和公证:原生文件是 ad-hoc 签名,minos 11.0。通过 npm 安装不会带 quarantine 属性,所以 Gatekeeper 不会拦截;从浏览器下载的 tarball 仍可能被拦截。
    • release.yml 的原生构建只在 main 上生效,本票没有触发它。
    • Cargo.toml 内部仍是 0.1.0,对外版本以 CODSH_PACKAGE_VERSION 为准。

    未改动

    • main、发布流程的实际执行、npm 包、tag、仓库设置和 secrets 均未改动。
    • 旧版(非 Rust)codsh 的安装说明和行为未改动。
    • 证据分支 ci/198-macos-install 保留,没有删除。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions