Skip to content

feat(runtime): 本体更新时一并更新 Runtime 可执行文件 - #609

Open
qiyinxi wants to merge 2 commits into
AUTO-MAS-Project:devfrom
qiyinxi:feat/runtime-selfupdate-20260907
Open

feat(runtime): 本体更新时一并更新 Runtime 可执行文件#609
qiyinxi wants to merge 2 commits into
AUTO-MAS-Project:devfrom
qiyinxi:feat/runtime-selfupdate-20260907

Conversation

@qiyinxi

@qiyinxi qiyinxi commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

auto-mas-runtime.exe 现在只能靠重装整包升级:bootstrap --version 会把 repo/ 换成新版本源码,Runtime 却停在装机那天,用户机器上会出现「新本体 + 旧 Runtime」这种没联调过的组合。

本 PR 把 Runtime 版本钉扎进本体源码,让它跟着源码一起走。

改了什么

  • 新增 res/runtime.jsonversion + sha256),成为 Runtime 版本与哈希的唯一来源。它随发布分支进到用户的 repo/res/runtime.json
  • build-app.ymlscripts/build-local-package.ps1 不再从 workflow 的 RUNTIME_VERSION env 取版本,改读这个文件;下载后除了对该 Release 的 SHA256SUMS.txt 校验,再和钉扎值比一次——前者证明文件没坏,后者证明钉扎没抄错版本,而装机后的桌面端只认钉扎值。
  • 新增 frontend/electron/services/runtimeBinaryService.ts:读钉扎 → 问现有 exe 自报的版本 → 不一致就按 gh-proxy 家族到 GitHub 官方的顺序轮换下载 → 校验 SHA-256 → 原地替换。
  • 挂接两处:backendService 在 managed 启动链路 bootstrap --if-needed 之后、supervise 之前(此刻旧监督进程已退出、新的还没起来,是唯一能安全替换 exe 的窗口);runtimeUpdateService 在源码换完之后、重启之前加一个 runtime 进度段。

几处取舍

  • 判身份用 exe 自报的版本,不是文件哈希。 哈希只能证明「下到的那份没坏」,本地那份被重签名之类的后处理动过一个字节就永远对不上、而版本没变,会让每次启动都白下载十几兆。scripts/build-local-package.ps1 本来就是这么校验 Runtime 的,口径一致。
  • 判据是版本相等,不是「钉扎的更新才换」——本体回退时 Runtime 要跟着退回去。
  • 取不到新 Runtime 只记警告继续用旧的启动,不阻断。 卡在「更新完就打不开」比多跑一版旧 Runtime 糟得多;不一致留到下次启动重试。
  • 替换首选一次 rename 直接盖过去(Windows 上原子),只有目标被占用时才退回「改名让路 → 挪新文件 → 失败改回来」。避免出现「目录里没有 exe」这种一旦发生就只能重装的状态——那时 resolveRuntimeExecutable() 返回 null,同步逻辑根本进不去。
  • 一轮同步有 10 分钟总预算,换源之前查一次。卡死的连接由下载器自己的超时兜住,但「连得上、就是慢」不触发那些超时,四个源各拉一遍能把启动挂很久。
  • 取消更新时不核对 Runtime:那条路源码一动没动,也不该在用户点了取消之后开一个他取消不掉的下载。

兼容性

res/runtime.json 缺失或字段非法一律按「本体没有钉扎」处理,什么都不做——回退到本 PR 之前发布的版本不会让启动失败。development 模式与 AUTO_MAS_RUNTIME_EXE 指定的 Runtime 都不碰。

本地验证

frontend 目录:

  • yarn test 444 用例通过 443。唯一失败的是 dev 上既存的 backendService.test.tsmanaged 模式 > 不传 --repo、不先跑 environment ensure,--app-root 就是用户数据根(5 秒超时)——把该文件换回 dev 原版复跑同样失败,与本 PR 无关。
  • yarn lint / yarn build:main / yarn typecheck / yarn lint:md 均通过。

其它:

  • build-app.yml 的 pwsh 片段(${{ }} 换占位量后)与 scripts/build-local-package.ps1 都过了 [Parser]::ParseFile 语法检查;build-local-package.ps1 -VerifyRuntimeOnly 真跑通了一遍(下载 v0.1.4、清单哈希与钉扎哈希比对通过、exe 自报 v0.1.4、退出码 0)。
  • 用真实 auto-mas-runtime-v0.1.4.exe 核对过 --output ndjson --protocol 1 versiondetails.runtimeVersion 逐字为 v0.1.4,与钉扎格式一致。

没有验证的:真实受管安装下的整条下载与替换(手上没有受管安装现场);build-app.yml 只能等真发版才跑到。

🤖 Generated with Claude Code

Sourcery 摘要

确保托管 Runtime 可执行文件在整个构建、更新和启动过程中始终与应用程序源代码版本保持一致。

新功能:

  • 添加托管 Runtime 同步功能,使 Runtime 可执行文件遵循更新后的应用程序源代码所固定的版本。

错误修复:

  • 防止托管更新后出现更新的应用程序代码与过时 Runtime 二进制文件不兼容的组合。
  • 允许 Runtime 同步失败,同时通过继续使用现有可执行文件来保留启动流程。

增强功能:

  • 在 res/runtime.json 中集中管理 Runtime 版本和 SHA-256,并在 CI 构建、本地打包和桌面端更新中统一使用。
  • 通过按顺序尝试代理回退来下载 Runtime 发布版本,验证其哈希值,并通过重试和回滚机制安全替换已安装的可执行文件。
  • 将 Runtime 对齐集成到托管启动和应用程序更新流程中,包括进度报告,以及针对开发环境或显式配置的 Runtime 二进制文件的安全保护措施。

构建:

  • 更新应用程序和本地软件包构建流程,使其从 res/runtime.json 读取并验证 Runtime 元数据,同时验证固定的哈希值。

文档:

  • 记录 Runtime 固定版本、本地 Runtime 测试,以及本地打包构建所需的 AUTO_MAS_RUNTIME_EXE 配置。

测试:

  • 添加全面的 Runtime 二进制文件同步测试,涵盖固定版本验证、版本匹配、备用下载、完整性检查、超时、并发、清理以及替换失败等场景。
  • 添加更新流程测试,涵盖 Runtime 同步顺序、非阻塞失败、取消操作和重试。
Original summary in English

Summary by Sourcery

Keep the managed Runtime executable aligned with the application source version throughout builds, updates, and startup.

New Features:

  • Add managed-runtime synchronization so the Runtime executable follows the version pinned by the updated application source.

Bug Fixes:

  • Prevent incompatible combinations of updated application code and stale Runtime binaries after managed updates.
  • Allow Runtime synchronization failures to preserve startup by continuing with the existing executable.

Enhancements:

  • Centralize the Runtime version and SHA-256 in res/runtime.json and use it consistently for CI builds, local packaging, and desktop updates.
  • Download Runtime releases through ordered proxy fallbacks, validate their hashes, and safely replace the installed executable with retry and rollback behavior.
  • Integrate Runtime alignment into managed startup and application-update flows, including progress reporting and safeguards for development or explicitly configured Runtime binaries.

Build:

  • Update application and local-package builds to read and validate Runtime metadata from res/runtime.json and verify the pinned hash.

Documentation:

  • Document Runtime pinning, local Runtime testing, and the AUTO_MAS_RUNTIME_EXE requirement for locally packaged builds.

Tests:

  • Add comprehensive Runtime binary synchronization tests covering pin validation, version matching, fallback downloads, integrity checks, timeouts, concurrency, cleanup, and replacement failures.
  • Add update-flow tests covering Runtime synchronization ordering, non-blocking failures, cancellation, and retries.
Original summary in English

`auto-mas-runtime.exe` 此前只能靠重装整包升级:`bootstrap --version` 能把本体源码
换成新版本,Runtime 却停在装机那天,于是「新本体 + 旧 Runtime」这种从未联调过的
组合会出现在用户机器上。

把 Runtime 版本钉扎进本体源码,让它跟着源码走:

- 新增 `res/runtime.json`(version + sha256),成为版本与哈希的唯一来源。发布 CI 与
  `scripts/build-local-package.ps1` 都不再从 `build-app.yml` 的 `RUNTIME_VERSION` 正则
  抠版本号,改读它;下载后同时对该 Release 的 SHA256SUMS.txt 与钉扎值各校验一次——
  前者证明文件没坏,后者证明钉扎没抄错版本,而装机后的桌面端只认钉扎值。
- 新增 `runtimeBinaryService`:读钉扎、问现有 exe 自报的版本、按 gh-proxy 家族到
  GitHub 官方的顺序轮换下载、校验 SHA-256 后原地替换。
- `backendService` 在 managed 启动链路 `bootstrap --if-needed` 之后、`supervise` 之前
  接一次同步——此刻旧监督进程已退出、新的还没起来,是唯一能安全替换 exe 的窗口;
  `runtimeUpdateService` 在源码换完之后、重启之前加一个 `runtime` 进度段,让界面在
  下载那十几兆时有话可说。两处调的是同一个函数。

几处取舍:

- 判身份用 exe 自报的版本而不是文件哈希。哈希只能证明「下到的那份没坏」,本地那份
  被重签名、杀软隔离后还原之类的后处理动过一个字节就永远对不上,会让每次启动都白
  下载十几兆;版本比对不受影响。`scripts/build-local-package.ps1` 早就是这么校验的。
- 判据是版本相等而不是「钉扎的更新才换」,本体回退时 Runtime 必须跟着退回去。
- 取不到新 Runtime 只记警告继续用旧的启动,不阻断;不一致留到下次启动重试。
- 替换首选一次 rename 直接盖过去(Windows 上是原子的),只有目标被占用时才退回
  「改名让路 → 挪新文件 → 失败改回来」。避免出现「目录里没有 exe」这种一旦发生就
  只能重装的状态:那时 `resolveRuntimeExecutable()` 返回 null,同步逻辑根本进不去。
- 一轮同步有 10 分钟总预算,换源之前查一次。卡死的连接由下载器自己的超时兜住,但
  「连得上、就是慢」不会触发那些超时,四个源各拉一遍能把启动挂上一个钟头。
- 取消更新时不核对 Runtime:那条路源码一动没动,没有要对齐的东西,也不该在用户点了
  取消之后开一个他取消不掉的下载。
- 镜像顺序自己实现而不复用 `MirrorRotationService`——后者会把 key 含 github 的源提到
  最前,正好把国内用户最连不上的官方源排到第一个。

本地验证(`frontend`):`yarn test` 444 用例通过 443,唯一失败的
`backendService.test.ts` 5 秒超时在 dev 基线上把本文件换回原版复跑同样失败;
`yarn lint`、`yarn build:main`、`yarn typecheck`、`yarn lint:md` 均通过。
`build-app.yml` 的 pwsh 片段与 `scripts/build-local-package.ps1` 都过了 PowerShell AST
解析,钉扎读取逻辑单独演练过。另用真实 `auto-mas-runtime-v0.1.4.exe` 核对过
`--output ndjson --protocol 1 version` 的 `details.runtimeVersion` 逐字为 `v0.1.4`。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @qiyinxi, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 4 days and 19 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Sep 7, 2026

Copy link
Copy Markdown

审查者指南

本 PR 将 Runtime 版本及哈希钉扎到本体源码,并在构建、启动和本体更新链路中统一使用该钉扎值:受管 Runtime 会在安全窗口按版本检查、镜像轮换下载、SHA-256 校验后原地替换,失败则保留旧版本继续运行,同时向更新界面报告进度。

受管 Runtime 二进制同步时序图

sequenceDiagram
    participant BackendService
    participant RuntimeBinaryService
    participant RuntimeExe
    participant Downloader
    participant GitHub

    BackendService->>RuntimeBinaryService: syncRuntimeBinary(runtimePath, appRoot, sourceRoot)
    RuntimeBinaryService->>RuntimeBinaryService: readRuntimeBinaryPin(sourceRoot)
    RuntimeBinaryService->>RuntimeExe: version
    RuntimeExe-->>RuntimeBinaryService: runtimeVersion
    alt version matches pin
        RuntimeBinaryService-->>BackendService: current
    else version differs or unavailable
        loop proxy sources then GitHub
            RuntimeBinaryService->>Downloader: download(source.url, downloadPath)
            Downloader->>GitHub: GET pinned Runtime asset
            GitHub-->>Downloader: executable
            RuntimeBinaryService->>RuntimeBinaryService: hashFileSha256(downloadPath)
        end
        RuntimeBinaryService->>RuntimeBinaryService: replaceRuntimeBinary(runtimePath, downloadPath, backupPath)
        RuntimeBinaryService-->>BackendService: upgraded
    end
Loading

源码替换后的 Runtime 更新时序图

sequenceDiagram
    participant RuntimeUpdateService
    participant BackendService
    participant RuntimeBinaryService
    participant Supervisor

    RuntimeUpdateService->>BackendService: stopBackend()
    BackendService->>BackendService: bootstrap --version
    BackendService-->>RuntimeUpdateService: repository updated
    RuntimeUpdateService->>RuntimeBinaryService: syncRuntimeBinary(runtimePath, appRoot, repo)
    alt synchronization succeeds
        RuntimeBinaryService-->>RuntimeUpdateService: upgraded or current
    else synchronization fails
        RuntimeBinaryService-->>RuntimeUpdateService: failed
        RuntimeUpdateService->>RuntimeUpdateService: continue with existing Runtime
    end
    RuntimeUpdateService->>BackendService: startBackend()
    BackendService->>Supervisor: supervise()
    RuntimeUpdateService-->>RuntimeUpdateService: runtime progress completed
Loading

文件级变更

变更 详情 文件
将 Runtime 版本和 SHA-256 固定到源码中的单一配置,并让构建与本地打包流程据此获取、校验和捆绑 Runtime。
  • 新增 res/runtime.json 作为版本与哈希来源。
  • CI 和本地打包脚本从钉扎文件读取并校验版本格式、发布清单哈希及实际文件哈希。
  • 移除 workflow 中独立的 RUNTIME_VERSION 配置。
.github/workflows/build-app.yml
res/runtime.json
scripts/build-local-package.ps1
scripts/README.md
实现受管 Runtime 可执行文件的版本对齐、下载、校验和安全替换。
  • 读取并校验 repo/res/runtime.json,通过现有 Runtime 自报版本判断是否需要更新,支持本体回退时降级。
  • 按三个 gh-proxy 源到 GitHub 官方源的顺序下载,并验证钉扎 SHA-256。
  • 设置单轮十分钟预算,失败时保留旧 Runtime 并允许继续启动。
  • 优先原子覆盖,目标被占用时采用备份让路与失败回滚策略,并清理临时文件。
  • 跳过 development 模式及 AUTO_MAS_RUNTIME_EXE 指定的 Runtime。
frontend/electron/services/runtimeBinaryService.ts
frontend/electron/services/index.ts
frontend/electron/services/runtimeBinaryService.test.ts
将 Runtime 对齐接入受管后端启动和本体更新编排,并向 UI 暴露更新进度。
  • bootstrap --if-needed 后、supervise 前同步 Runtime,失败仅记录警告,不阻断启动。
  • 在源码更新完成、后端重启前增加 Runtime 更新阶段;取消更新时不触发下载。
  • 为重试路径复用同一同步逻辑,并保持开发模式不变。
  • 扩展主进程服务导出、进度阶段类型和前端阶段顺序。
frontend/electron/services/backendService.ts
frontend/electron/services/runtimeUpdateService.ts
frontend/electron/services/runtimeUpdateService.test.ts
frontend/src/composables/useBackendRuntimeUpdate.ts
frontend/src/types/electron.d.ts

提示和命令

与 Sourcery 交互

  • 触发新的审查: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 根据审查评论生成 GitHub issue: 回复审查评论,请 Sourcery 根据该评论创建 issue。你也可以使用 @sourcery-ai issue 回复审查评论,以根据该评论创建 issue。
  • 生成 pull request 标题: 在 pull request 标题的任意位置写入 @sourcery-ai,即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title,以随时生成或重新生成标题。
  • 生成 pull request 摘要: 在 pull request 正文的任意位置写入 @sourcery-ai summary,即可在指定位置随时生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary,以随时生成或重新生成摘要。
  • 生成审查者指南: 在 pull request 中评论 @sourcery-ai guide,即可随时生成或重新生成审查者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 忽略所有 Sourcery 审查: 在 pull request 中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 审查。如果你想从新的审查开始,这尤其有用——别忘了评论
    @sourcery-ai review 以触发新的审查!

自定义你的体验

访问你的控制面板以:

  • 启用或禁用审查功能,例如 Sourcery 生成的 pull request
    摘要、审查者指南等。
  • 更改审查语言。
  • 添加、删除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

本 PR 将 Runtime 版本及哈希钉扎到本体源码,并在构建、启动和本体更新链路中统一使用该钉扎值:受管 Runtime 会在安全窗口按版本检查、镜像轮换下载、SHA-256 校验后原地替换,失败则保留旧版本继续运行,同时向更新界面报告进度。

Sequence diagram for managed Runtime binary synchronization

sequenceDiagram
    participant BackendService
    participant RuntimeBinaryService
    participant RuntimeExe
    participant Downloader
    participant GitHub

    BackendService->>RuntimeBinaryService: syncRuntimeBinary(runtimePath, appRoot, sourceRoot)
    RuntimeBinaryService->>RuntimeBinaryService: readRuntimeBinaryPin(sourceRoot)
    RuntimeBinaryService->>RuntimeExe: version
    RuntimeExe-->>RuntimeBinaryService: runtimeVersion
    alt version matches pin
        RuntimeBinaryService-->>BackendService: current
    else version differs or unavailable
        loop proxy sources then GitHub
            RuntimeBinaryService->>Downloader: download(source.url, downloadPath)
            Downloader->>GitHub: GET pinned Runtime asset
            GitHub-->>Downloader: executable
            RuntimeBinaryService->>RuntimeBinaryService: hashFileSha256(downloadPath)
        end
        RuntimeBinaryService->>RuntimeBinaryService: replaceRuntimeBinary(runtimePath, downloadPath, backupPath)
        RuntimeBinaryService-->>BackendService: upgraded
    end
Loading

Sequence diagram for Runtime update after source replacement

sequenceDiagram
    participant RuntimeUpdateService
    participant BackendService
    participant RuntimeBinaryService
    participant Supervisor

    RuntimeUpdateService->>BackendService: stopBackend()
    BackendService->>BackendService: bootstrap --version
    BackendService-->>RuntimeUpdateService: repository updated
    RuntimeUpdateService->>RuntimeBinaryService: syncRuntimeBinary(runtimePath, appRoot, repo)
    alt synchronization succeeds
        RuntimeBinaryService-->>RuntimeUpdateService: upgraded or current
    else synchronization fails
        RuntimeBinaryService-->>RuntimeUpdateService: failed
        RuntimeUpdateService->>RuntimeUpdateService: continue with existing Runtime
    end
    RuntimeUpdateService->>BackendService: startBackend()
    BackendService->>Supervisor: supervise()
    RuntimeUpdateService-->>RuntimeUpdateService: runtime progress completed
Loading

File-Level Changes

Change Details Files
将 Runtime 版本和 SHA-256 固定到源码中的单一配置,并让构建与本地打包流程据此获取、校验和捆绑 Runtime。
  • 新增 res/runtime.json 作为版本与哈希来源。
  • CI 和本地打包脚本从钉扎文件读取并校验版本格式、发布清单哈希及实际文件哈希。
  • 移除 workflow 中独立的 RUNTIME_VERSION 配置。
.github/workflows/build-app.yml
res/runtime.json
scripts/build-local-package.ps1
scripts/README.md
实现受管 Runtime 可执行文件的版本对齐、下载、校验和安全替换。
  • 读取并校验 repo/res/runtime.json,通过现有 Runtime 自报版本判断是否需要更新,支持本体回退时降级。
  • 按三个 gh-proxy 源到 GitHub 官方源的顺序下载,并验证钉扎 SHA-256。
  • 设置单轮十分钟预算,失败时保留旧 Runtime 并允许继续启动。
  • 优先原子覆盖,目标被占用时采用备份让路与失败回滚策略,并清理临时文件。
  • 跳过 development 模式及 AUTO_MAS_RUNTIME_EXE 指定的 Runtime。
frontend/electron/services/runtimeBinaryService.ts
frontend/electron/services/index.ts
frontend/electron/services/runtimeBinaryService.test.ts
将 Runtime 对齐接入受管后端启动和本体更新编排,并向 UI 暴露更新进度。
  • bootstrap --if-needed 后、supervise 前同步 Runtime,失败仅记录警告,不阻断启动。
  • 在源码更新完成、后端重启前增加 Runtime 更新阶段;取消更新时不触发下载。
  • 为重试路径复用同一同步逻辑,并保持开发模式不变。
  • 扩展主进程服务导出、进度阶段类型和前端阶段顺序。
frontend/electron/services/backendService.ts
frontend/electron/services/runtimeUpdateService.ts
frontend/electron/services/runtimeUpdateService.test.ts
frontend/src/composables/useBackendRuntimeUpdate.ts
frontend/src/types/electron.d.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

复核在 AUTO-MAS-Project#609 上发现的几处问题:

- `syncRuntimeBinary` 没有在途互斥:devtools 的重启按钮与 `backend-start` IPC 能在更新
  链路的同步还没结束时再触发一次启动,两份下载会写同一个 `.download` 文件,让一个没
  校验过的文件盖到 exe 上。加模块级在途记录,后来者复用同一个 promise 的结果,进度
  回调也一并转发。
- 单个慢源没有时长上限:10 分钟预算只在换源之前查,分片超时又只管空闲,「连得上但被
  限速」的源能跑半小时。给每个源加上限(剩余预算与总预算一半取小),超时就换下一个源。
  下载器没有取消接口,被放弃的那次仍会往文件里写,所以每次尝试各用一个
  `<exe>.download-<token>` 临时文件,等它自己结束后再清;下次同步按前缀清扫全部残留。
- `-LocalRuntimePath` 打出来的包在首次 managed 启动时会被钉扎版覆盖,开发者以为在验证
  自己的 Runtime。安装包不带 `res/runtime.json`,同步逻辑读的是 Runtime 克隆到
  `<app-root>/repo/` 的那一份,打包脚本改不了它,所以在 README 写明必须设
  `AUTO_MAS_RUNTIME_EXE`,并让脚本在该分支打印提示。
- 补上 `replaceRuntimeBinary` 目标被占用时「改名让路」与「让路后失败回滚」两条路径的
  测试;`runtimeUpdateService.test.ts` 里写死反斜杠的路径断言改成 `path.join`。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant